ios SwiftUI子视图的内容不会调整大小,除非将内容直接放在主视图中

cyej8jka  于 2023-08-08  发布在  iOS
关注(0)|答案(1)|浏览(107)

我在SwiftUI中创建了一个子视图:

struct MockView : View {
    
    var body: some View {
        Button {
            print("ok")
        } label: {
            ZStack {
                Rectangle()
                    .fill(.red)
                Text("Hello")
                    .frame(width: getFrame().width, height: getFrame().height)
                    .background(Color.gray)
                    .cornerRadius(20)
            }
           
        }

    }
}

func getFrame() -> (width: CGFloat, height: CGFloat) {
        func getWidth() -> CGFloat{
          return UIScreen.main.bounds.width
      }
        func getHeight() -> CGFloat{
          return UIScreen.main.bounds.height
      }
        let height: CGFloat =   getWidth() < getHeight() ? 5 : 10
        let width: CGFloat  =  getWidth() < getHeight() ? 3 : 8
       
        return ( width, height)
    }

字符串
我必须为文本设置文本框架,因为我需要文本有一个特定的框架。我用来计算宽度和高度的函数为横向模式返回一个高度和宽度,为纵向模式返回另一个高度和宽度。
问题是,如果我从主视图调用MockView,如果我更改了设备的方向,那么在我的mockView中只有矩形会调整大小,而文本不会。

struct MainView: View {
    ...
    
    var body: some View {
        GeometryReader { geometry in

            ...
            MockView()
            ...
        }
    }
    
}


如果我把MockView的代码直接放到MainView中,就不会出现调整大小的错误。内容完美地调整大小和工作完美。
怎么会这样呢?如何使子视图也能工作?
我看到,删除框架的工作,但我需要的文本有特定的框架。

li9yvcax

li9yvcax1#

你需要让你的子视图 * 依赖于 * 它的容器视图的大小。在您的示例中,子视图的主体只计算一次,即创建相关的底层真实的视图时。
你可以这样做:

import SwiftUI

struct ContentView: View {
    var body: some View {
        GeometryReader { geometry in
            let size = geometry.size
            let screenSize = "(\(UIScreen.main.bounds.size.width), \(UIScreen.main.bounds.size.height)"
            
            // your child view:
            VStack {
                Text("width: \(size.width)")
                Text("height: \(size.height)")
                Text("Screen: \(screenSize)")
            }
            .padding()
        }
    }
}

字符串
不过,子视图的容器大小 * 不是 * 屏幕大小。你需要你的子视图帐户。但是,您也可以像之前那样检索屏幕的大小,然后使用它来计算您的子视图。

注意事项

如果子视图的容器大小没有改变,并且这是子视图的唯一依赖项,则不会计算子视图的主体。

使用大小类

另一种可能解决问题的方法是利用SwiftUI环境变量verticalSizeClasshorizontalSizeClass

struct ChildView: View {
    @Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
    @Environment(\.horizontalSizeClass) var horizontalSizeClass: UserInterfaceSizeClass?
    
    var body: some View {
        
        switch (verticalSizeClass, horizontalSizeClass) {
        case (.regular, .regular):
            ...
        case (.regular, .compact):
            ...

            
        }
    }
}


我建议阅读文档:https://developer.apple.com/documentation/swiftui/environmentvalues/verticalsizeclasshttps://developer.apple.com/documentation/swiftui/environmentvalues/horizontalsizeclass的数据库
如果这还不够,您可能需要返回到UIKit并捕获方向模式的通知更改。您可以在“模型”中执行此操作,并将这些通知转发到您的SwiftUI视图。

**注意:**一般建议使用Size Classes和容器视图的大小进行布局,而不是设备方向。

相关问题