ios 在GeometryReader中横向 Package SwiftUI View的重要性

q43xntqr  于 2023-10-21  发布在  iOS
关注(0)|答案(1)|浏览(106)

经过多年的UIKit开发,我决定使用SwiftUI。我发现了一件非常奇怪的事情,那让我花了至少6个小时拔头发。
目标:我有一个应用程序,在纵向和横向模式的作品。
纵向模式:一切都很好,UI完全按照我的预期呈现。
横向模式:当我将手机旋转到横向模式时,所有UI似乎都有一个超出屏幕边界的偏移。虽然我看到我的元素水平对齐正确,我看不到屏幕的顶部。这没关系,如果我启动应用程序已经在横向手机,或者如果我启动一个应用程序在肖像模式,然后旋转-效果是完全相同的。
这是我的ContentView - Root视图,这是我的UI的开始

struct ContentView: View {
    
    @State var isActive: Bool = false
    
    private let container: DIContainer
    
    init(container: DIContainer) {
        self.container = container
        self.isActive = isActive
    }
    
    var body: some View {
            ZStack {
                if self.isActive {
                    
                    RootView().inject(container)
                    
                } else {
                    LinearGradient(colors: [.blue, Color("light_blue")],
                                   startPoint: .top,
                                   endPoint: .center)
                    .edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
                    
                    Text("HELLO")
                        .font(.system(size:36))
                        .foregroundColor(Color.white)
                }
                
            }.onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
                    
                    withAnimation {
                        self.isActive = true
                    }
                }
            }
    }
}

因此,为了调试这个令人难以置信的恼人的问题,我决定将我的ContentView Package 在GeometryReader中,看看它有什么偏移量,等等。所以我做了这个

struct ContentView: View {
    
    @State var isActive: Bool = false
    
    private let container: DIContainer
    
    init(container: DIContainer) {
        self.container = container
        self.isActive = isActive
    }
    
    var body: some View {
        GeometryReader { geometry in
            ZStack {
                if self.isActive {
                    
                    RootView().inject(container)
                    
                } else {
                    LinearGradient(colors: [.blue, Color("light_blue")],
                                   startPoint: .top,
                                   endPoint: .center)
                    .edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
                    
                    Text("HELLO")
                        .font(.system(size:36))
                        .foregroundColor(Color.white)
                }
                
            }.onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now() + 2.5) {
                    
                    withAnimation {
                        self.isActive = true
                    }
                }
            }
        }
    }
}

你会相信吗-它解决了一个问题!一旦我在GeometryReader中 Package 了我的ContentView,应用程序就开始在所有模式下正确渲染-肖像和风景。所以基本上-出于纯粹的运气,我已经解决了这个问题。
我的问题是-为什么我需要在Geometry Reader中 Package ContentView,以便SwiftUI能够正确呈现?我问的原因是-我搜索了所有的谷歌,Youtube等,我没有找到这个recomendation任何地方!所以我的假设是,我的SwiftUI代码中有一些可怕的错误,这就是为什么我需要实现这个解决方案。因为我不相信每个拥有支持免费应用程序的人都默默地处理同样的问题,不分享这些重要信息。
UPD:如果我只在横向模式下锁定应用程序,它仍然是不正确的渲染与巨大的偏移到顶部。如果我将ContentView Package 在GeometryReader中,

mitkmikd

mitkmikd1#

GeometryReader是贪婪的,会使用所有可用的空间,而ZStack本身不会这样做。但是应该可以让ZStack版本类似地工作,而不需要用GeometryReader Package 它。
首先,如果你把Color.clear放在ZStack里面,那么这将使它膨胀到最大尺寸。
然后,GeometryReader中的内容总是位于左上角,所以你可能也想对ZStack应用.topLeading对齐:

ZStack(alignment: .topLeading) { // alignment added
    Color.clear // added
    if self.isActive {
        RootView().inject(container)
    } else {
        // other content as before
    }
}

.ignoresSafeArea()添加到ZStack和/或RootView也可能有帮助。但是,如果当内容用GeometryReader Package 时它工作正常,那么这里也不需要它。
使用.topLeading对齐会导致初始文本消息也出现在左上角,因此要解决这个问题,您可以对文本应用最大宽度和高度:

Text("HELLO")
    .font(.system(size:36))
    .foregroundColor(Color.white)
    .frame(maxWidth: .infinity, maxHeight: .infinity) // added

相关问题