SwiftUI:防止 Image() 将视图矩形扩展到屏幕边界之外

Posted

技术标签:

【中文标题】SwiftUI:防止 Image() 将视图矩形扩展到屏幕边界之外【英文标题】:SwiftUI: Prevent Image() from expanding view rect outside of screen bounds 【发布时间】:2019-08-21 14:06:19 【问题描述】:

我正在努力实现的目标

我正在尝试创建一个 SwiftUI 视图,其中图像应该扩展整个屏幕 (edgesIgnoringSafeArea(.all)),然后在其上覆盖一个视图,该视图也填充整个屏幕,但尊重安全区域。

我尝试过的

这是我的代码,很接近:

struct Overlay: View 
  var body: some View 
    VStack 
      HStack 
        EmptyView()
        Spacer()
        Text("My top/right aligned view.")
          .padding()
          .background(Color.red)
      
      Spacer()
      HStack 
        Text("My bottom view")
          .padding()
          .background(Color.pink)
      
    
  


struct Overlay_Previews: PreviewProvider 
  static var previews: some View 
    ZStack 
      Image(uiImage: UIImage(named: "background")!)
        .resizable()
        .edgesIgnoringSafeArea(.all)
        .aspectRatio(contentMode: .fill)
      Overlay()
    
  

问题和测试解决方案

问题是图像没有像看起来那样被剪裁,因此它将父视图扩展为大于屏幕宽度的宽度,然后使右上对齐的红色文本框浮出屏幕(见图)。

我尝试在各个地方使用.clipped(),但没有成功。如果可能的话,我最好避免使用GeometryReader

问:如何让图像视图只填满屏幕?

【问题讨论】:

我添加了一个非GeometryReader answer 【参考方案1】:

您必须在 ZStack 拾取越界 Image 之前限制其帧大小以避免 ZStack em> 增长,因此 Overlay 偏离位置。

编辑: aheze 用.background(Image()..)Image 放到Overlay() 的背景中,用GeometryReader 显示了他的答案。这完全避免了ZStackGeometryReader 的使用,并且可能是一个更清洁的解决方案。

基于父视图大小

struct IgnoringEdgeInsetsView2: View 
    var body: some View 
        ZStack 
            GeometryReader  geometry in
                Image("smile")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .edgesIgnoringSafeArea(.all)
                    .frame(maxWidth: geometry.size.width,
                           maxHeight: geometry.size.height)
            
            Overlay()
        
    

基于屏幕尺寸

struct IgnoringEdgeInsetsView: View 
    var body: some View 
        ZStack 
            Image("smile-photo")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .edgesIgnoringSafeArea(.all)
                .frame(maxWidth: UIScreen.main.bounds.width, 
                       maxHeight: UIScreen.main.bounds.height)
            Overlay()
        
    

【讨论】:

太好了,谢谢!我没有想到UIScreen.main.bounds.width,我的脑海里自动想到了GeometryReader。也不知道maxWidth/maxHeight,这比设置固定宽度更有意义。 :) 我添加了一个GeometryReader 示例:-) 为什么 GeometryReader 没有自动集成到堆栈中?会更干净。 @fullmoon 也许是出于性能原因?我不确定你的意思。【参考方案2】:

无需弄乱 GeometryReader。相反,您可以使用.background() 修饰符来防止图像溢出。

struct ContentView: View 
    var body: some View 
        Overlay()
        .background( /// here!
            Image("City")
            .resizable()
            .aspectRatio(contentMode: .fill)
            .ignoresSafeArea()
        )
    

结果:

【讨论】:

这绝对是一个比@F*** 的答案更好的通用和更惯用的约束视图大小的解决方案。对于其他读者:background()overlay() 都会将您提供的视图限制在接收视图的范围内。

以上是关于SwiftUI:防止 Image() 将视图矩形扩展到屏幕边界之外的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI:将背景颜色应用于圆角矩形

如何防止键盘在 SwiftUI 中向上推视图? [复制]

SwiftUI之深入解析如何使用组合矩形GeometryReader创建条形(柱状)图

SwiftUI之深入解析如何使用组合矩形GeometryReader创建条形(柱状)图

将样式为 .bordered 的 SwiftUI 按钮扩展为全宽

SwiftUI:防止视图在 VStack 内展开