如何在SwiftUI中居中裁剪图像 [英] How to center crop an image in SwiftUI

查看:104
本文介绍了如何在SwiftUI中居中裁剪图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是SwiftUI的新手.我想每个人都在这一点上.我已经从事应用程序开发大约6年了,我在StackOverflow上问这个问题时感到很愚蠢.但是我到处看.如何在SwiftUI的ImageView中居中裁切图像?

我知道可以更改长宽比,但是我只能看到合适的填充.我只想要imageView对图像进行centerCrop(android term).有人知道吗?

解决方案

Android的


替代解决方案

制作中心裁切图像的另一种方法是使图像成为 Color.clear .overlay().这允许 Color.clear 建立剪切范围.

  Color.clear.覆盖(图片("apolloimage").resizable().scaledToFill()).clipped() 

以及与 Image 相对应的扩展名看起来像这样:

 扩展名图像{func centerCropped()->一些视图{颜色透明.覆盖(自己.resizable().scaledToFill()).clipped()}} 

I'm new to SwiftUI. I guess everyone is at this point. I've been an app developer for about 6 years now and I feel stupid asking this question on StackOverflow. But I looked everywhere. How do I center crop an image in an ImageView in SwiftUI?

I know there's an option to change the aspect ratio but I only see fit and fill. I just want the imageView to centerCrop(android term) the image. Does anybody know?

解决方案

Android's ImageView.ScaleType documentation describes CENTER_CROP as:

CENTER_CROP

Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). The image is then centered in the view.

This is essentially what Aspect Fill Scaling (aka .scaledToFill()) does, except (surprisingly) Aspect Fill doesn't clip the parts that fall outside of the frame.

By making the image .resizable, and applying .scaledToFill(). the image will be scaled proportionally to fill its available frame leaving off the top and bottom or sides as necessary. .clipped() then removes the parts of the image outside of the frame.

Image("myImage")
    .resizable()
    .scaledToFill()
    .frame(width: 200, height: 200, alignment: .center)
    .clipped()

To make this more convenient, I created this extension of Image:

extension Image {
    func centerCropped() -> some View {
        GeometryReader { geo in
            self
            .resizable()
            .scaledToFill()
            .frame(width: geo.size.width, height: geo.size.height)
            .clipped()
        }
    }
}

To use the Image extension, just put it in a file in your project (a name like image-centercropped.swift will work nicely). Then just add .centerCropped() to any image you want to be center cropped.

Image("apolloimage").centerCropped()

It uses GeometryReader to figure out its frame so that it can crop the image correctly, which means you don't have to specify the frame to get proper clipping. You are free to size the image however you like using an explicit frame, or by just adding padding() and Spacer() to keep it nicely placed relative to other user interface items.

For example: If you want an image to fill the screen of the phone:

struct ContentView: View { 
    var body: some View {
        Image("apolloimage")
            .centerCropped()
            .edgesIgnoringSafeArea(.all)
    }
}

will nicely show the center of the image by scaling the image to show either the full height or the full width of the image and cropping the parts the hang over on the other dimension.


Demonstration:

Here's a demo that shows how the image is centered and cropped as the image grows. In this demo, the frame width is a constant 360 while the frame height varies from 50 to 700 as the slider advances to the right. At the beginning when the frame is short, the tops and bottoms of the image are cropped. As the frame exceeds the aspectRatio of the original image, the resulting image is centered but cropped on the left and right sides.

struct ContentView: View {
    
    @State private var frameheight: CGFloat = 50
    
    var body: some View {
        VStack(spacing: 20) {
            Spacer()
            Image("apolloimage")
                .resizable()
                .scaledToFill()
                .frame(width: 360, height: self.frameheight)
                .clipped()
            Spacer()
            Slider(value: self.$frameheight, in: 50...700)
                .padding(.horizontal, 20)
        }
    }
}

or an equivalent test using .centerCropped():

struct ContentView: View {
    
    @State private var frameheight: CGFloat = 50
    
    var body: some View {
        VStack(spacing: 20) {
            Spacer()
            Image("apolloimage")
                .centerCropped()
                .frame(width: 360, height: self.frameheight)
            Spacer()
            Slider(value: self.$frameheight, in: 50...700)
                .padding(.horizontal, 20)
        }
    }
}


Alternate Solution

Another way to make a center cropped image is to make the image an .overlay() of Color.clear. This allows Color.clear to establish the clipping bounds.

Color.clear
.overlay(
    Image("apolloimage")
    .resizable()
    .scaledToFill()
)
.clipped()

and the corresponding extension to Image looks like this:

extension Image {
    func centerCropped() -> some View {
        Color.clear
        .overlay(
            self
            .resizable()
            .scaledToFill()
        )
        .clipped()
    }
}

这篇关于如何在SwiftUI中居中裁剪图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆