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

Posted

技术标签:

【中文标题】在不使用垫片的情况下定位视图底部【英文标题】:Position view bottom without using a spacer 【发布时间】:2019-12-03 20:50:52 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

如果不加frame,默认frame会包裹inner view,大小和inner View一样。如果添加一个框架,它会创建一个属于外部视图的空间,在 UIView 概念中,它是一个超级视图。然后你会看到你需要处理什么。

【讨论】:

【参考方案2】:

尝试不同的方法后,我最终创建了自己的自定义容器,它有一些已知的限制,完全满足了我的需求。希望对其他人有帮助。

演示:

优点: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()
    

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于在不使用垫片的情况下定位视图底部的主要内容,如果未能解决你的问题,请参考以下文章

在不停止 stackView 自动调整大小的情况下对齐图像视图

如何在此扩展程序中创建一个按钮,在不使用操作按钮的情况下在主应用程序中打开特定视图?

如何定位 UITableViewCell 内容视图

在不修改视图的情况下使用 GeometryReader

我可以在不使用 xml 文件的情况下在列表视图中添加视图吗

如何在不显示中间视图的情况下通过多个视图展开