0

我在使用不同屏幕尺寸的应用时遇到问题。我做了一个小例子来说明这个问题。我有一个屏幕,左边有一个文本和一个按钮,右边有一个图像。在这之后,在 zstack 中,我有更大的相同图像,并且在该图像上具有不透明度 0.5 的图层。

问题是我使用的是相对于屏幕的度量,结果是不同的。在所附图片中,您可以看到差异。

这是结果

这是代码。

struct Screen2: View {
var body: some View {
    VStack {
        ZStack {
            ZStack {
                Image(uiImage: resizeImage(image: UIImage.init(named: "cover.jpeg")!, targetSize: .init(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)))
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 2.9, alignment: .center)
                    .cornerRadius(0)
                Color.black
                    .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 2.9, alignment: .center)
                    .opacity(0.5)
            }
            .edgesIgnoringSafeArea(.all)
            .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 5, alignment: .top)
            HStack(alignment: .top) {
                VStack {
                    Text("The Suicide Squad")
                        .font(.title)
                        .shadow(color: .white, radius: 5)
                    Button("Publish") {
                        print("Published")
                    }
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .padding()
                }
                .padding([.leading], 10)
                Spacer()
                Image(uiImage: resizeImage(image: UIImage.init(named: "cover.jpeg")!, targetSize: CGSize.init(width: UIScreen.main.bounds.width / 4, height: UIScreen.main.bounds.height / 4)))
            }
        }
        HStack {
            Spacer()
            Text("TESTING")
            Spacer()
        }
        .background(Color.red)
        Spacer()
    }
}

func resizeImage(image: UIImage, targetSize: CGSize) -> UIImage {
    let size = image.size
    let widthRatio = targetSize.width / size.width
    let heightRatio = targetSize.height / size.height
    var newSize:CGSize
    if (widthRatio > heightRatio)
    {
        newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio)
    }
    else
    {
        newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio)
    }
    let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height)
    UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0)
    image.draw(in: rect)
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

}

任何人都可以帮助我在每个屏幕尺寸中以相同的方式显示结果吗?

谢谢

4

1 回答 1

1
  1. 您将封面调整为 one targetSize,然后使用 设置其他尺寸.frame,然后再向 container 添加一帧ZStack。为什么要这么做?
  2. 当图像框架更改并contentMode设置为 时.fill,它将在其框架中居中,但图像的其余部分将在框架外可见。您可以在此示例中看到这一点:
let targetSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 2.9)

Image("cover")
    .resizable()
    .aspectRatio(contentMode: .fill)
    .cornerRadius(0)
    .frame(width: targetSize.width, height: targetSize.height, alignment: .center)
    .overlay(Rectangle().stroke(lineWidth: 5).foregroundColor(.red))

这可以用.clipped()修饰符修复。clipsToBounds如果您熟悉它,它与 UIKit 相同

  1. 当您应用edgesIgnoringSafeArea中的一项时VStack,它的作用类似于offset修饰符,这意味着下一项不会紧随其后。您需要应用edgesIgnoringSafeArea到 whole VStack,如果需要,您可以禁用 if.edgesIgnoringSafeArea([])对于需要安全区域插入的项目
  2. 在将图像传递给之前无需调整图像大小Image,尤其是您不想在视图构建器函数中执行该操作,因为每次更新此视图时都会重新计算。通常应用所需的修饰符就足以获得所需的结果,让 SwiftUI 为您优化它:
VStack(spacing: 0) {
    ZStack(alignment: .bottom) {
        let targetSize = CGSize(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height / 2.9)

        ZStack {
            Image("cover")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .cornerRadius(0)
                .frame(width: targetSize.width, height: targetSize.height, alignment: .center)
                .clipped()
            Color.black
                .opacity(0.5)
        }
        .frame(width: targetSize.width, height: targetSize.height, alignment: .center)
        HStack(alignment: .top) {
            VStack {
                Text("The Suicide Squad")
                    .font(.title)
                    .shadow(color: .white, radius: 5)
                Button("Publish") {
                    print("Published")
                }
                .background(Color.blue)
                .foregroundColor(.white)
                .padding()
            }
            .padding([.leading], 10)
            Spacer()
            Image("cover")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: UIScreen.main.bounds.width / 4)
        }
        .edgesIgnoringSafeArea([])
    }
    HStack {
        Spacer()
        Text("TESTING")
        Spacer()
    }
    .background(Color.red)
    Spacer()
}
.edgesIgnoringSafeArea(.all)

结果:

于 2021-08-16T09:28:45.630 回答