在不使用垫片的情况下将视图定位在底部

时间:2019-12-03 20:50:52

标签: position swiftui

如何在不使用垫片的情况下将视图放置在底部。我知道我可以实现在VStack中放置间隔符和视图,但是我不想使用间隔符,因为我不希望视图占据所有垂直空间。有了UIKit,我可以将其放置在安全区域底部指南中。

3 个答案:

答案 0 :(得分:1)

用不同的方法进行实验我最终创建了自己的自定义容器,该容器有一些已知的限制,可以完全满足我的需求。希望对其他人有帮助。

演示:

PinnedView Demo1

优点:ContentView和PinnedView在布局上绝对独立,可以自动处理设备方向,内部内容实际上是无限的

缺点:由于在顶级内容上使用GeometryReader使用.infinity或固定视图会导致由于“鸡鸡蛋”问题导致的崩溃。

容器代码:

struct ContainerWithPinnedBottomView<Content, Pinned>: View 
                                     where Content: View, Pinned: View {

    private var content: () -> Content
    private var bottomView: () -> Pinned

    @inlinable public init(@ViewBuilder pinnedView: @escaping () -> Pinned,
                            @ViewBuilder content: @escaping () -> Content) {
        self.content = content
        self.bottomView = pinnedView
    }

    var body: some View {
        ZStack(alignment: .bottom) {
            Rectangle().fill(Color.clear) // !! Extends ZStack to full screen
            GeometryReader { _ in
                ZStack {
                    self.content()
                }
            }
            self.bottomView()
                .alignmentGuide(.bottom) { $0[.bottom] }
        }
    }

}

(示例屏幕截图的)使用示例

struct TestBottomView: View {
    var body: some View {
        ContainerWithPinnedBottomView(pinnedView: {
            HStack {
                Spacer()
                Text("Always Pinned to Bottom")
                    .padding()
    //                .frame(width: .infinity) // !! LIMITATION - don't use, cycling crash
                Spacer()
            }
            .background(Color.blue)
        }) {
            NavigationView {
                List (0 ..< 100, id: \.self) { i in
                    NavigationLink(destination: Text("Other")) {
                        Text("Row \(i)")
                    }
                }
                .navigationBarTitle("TitleBar")
            }
        }
    }
}

struct TestBottomView_Previews: PreviewProvider {
    static var previews: some View {
        TestBottomView()
    }
}

答案 1 :(得分:0)

我认为最简单的方法是为container视图添加框架。

Group{ // container View
    Text("iner label")
}.frame(maxHeight: .infinity, alignment: .bottom)

如果不添加框架,则默认框架将包裹内部视图,并具有与内部视图相同的尺寸。如果添加框架,它将创建一个属于外部视图的空间,在UIView概念中,它是一个超级视图。然后,您将看到需要处理的内容。

答案 2 :(得分:0)

位置属性将帮助您尝试这种方式

Group{ // container View
     Text("iner label")
}.position(x: UIScreen.main.bounds.width/2, y: UIScreen.main.bounds.height-50)