繁体   English   中英

如何制作具有绝对 position 和 SwiftUI 的底栏

[英]how to make a bottom bar which has absolute position with SwiftUI

嗨,我是 SwiftUI 的新手,遇到了问题。

我想制作一个底栏(可重用模块)以在多个视图中使用。

但是它的 position 在每个视图中都不同,因为它的兄弟视图

这些是我尝试过的:

  1. GeometryReader 但是每个 View 的几何图形都是不同的。
  2. 覆盖 & 位置(x:y:) 这也不起作用
  3. ZStack

我的问题是

  1. 如何制作固定的 position 视图? (如 position:css 中的绝对值)
  2. 这个问题的正常解决方案是什么?
  3. SwiftUI 是否有任何有用的参考资料?

我想将此模块用作底部按钮栏

struct BaseBottomButton: View {
    let screen = UIScreen.main.bounds
    
    var body: some View {
        Button(action: {
            print("hello")
        }) {
            Text("Hello")
        }
        .frame(width: self.screen.width ,height: 40)
        .background(Color.red)
    }
}

在这个视图中,它有效

struct ContentView: View {
    var body: some View {
        GeometryReader { proxy in
            VStack {
                VStack {
                    Text("What")
                        .frame(width: 400, height: 50)
                        .background(Color.green)
                }
                
                Spacer()
                
                Group {
                    VStack {
                        Text("Some Text")
                        Text("")
                        .frame(width: 200, height: 200)
                            .background(Color.yellow)
                    }
                }
                
                Spacer()
                
                BaseBottomButton()
            }
        }
    }
}

但是在这个复杂的视图中,它不起作用

struct NewView: View {
    var body: some View {
        GeometryReader { geometry in
            ScrollView(showsIndicators: false) {
                VStack(spacing: 0) {
                    Text("hello")
                        .frame(width: 200, height: 200)
                        .background(Color.blue)
                    ZStack(alignment: .leading) {
                        VStack {
                            Spacer()
                                .frame(height: 24)
                            
                        }
                        .padding(.leading, 20)
                        .padding(.bottom, 138)
                        
                        Text("some box")
                        .frame(width: 200, height: 100)
                        .background(Color.yellow)
                        
                    }
                    .frame(minWidth: 0, maxWidth: .infinity)
                    .background(Color.gray)
                    
                    Spacer(minLength: 40)
                }
                
                BaseBottomButton()
            }
        }
    }
}

这不是问题的答案

如何制作固定的 position 视图? (如 position : css中的绝对值

但你可以先使用这样的东西:

VStack(spacing: 0) {
     Spacer()
     Button(action: {
         print("button clicked")
     }) {
         Text("MY BUTTON")
     }
}

这将为您提供一个出现在屏幕底部的按钮。 如果您希望视图显示在屏幕的顶部,只需将其放在 Spacer 之前,如下所示:

VStack(spacing: 0) {
     SomeView()
     Spacer()
     Button(action: {
         print("button clicked")
     }) {
         Text("MY BUTTON")
     }
}

最后,如果 View 在垂直方向上太大,只需将其放在 ScrollView 中(但不要将按钮放在其中)。 因此,您将获得一种效果,其中按钮始终显示在底部和前面,并且视图可在其后面滚动。

如果您复制并粘贴我的简单示例的以下最终代码,您将看到这种效果,并很快了解它的工作原理以及如何将其应用到您的场景中:

VStack(spacing: 0) {
    ScrollView(.vertical, showsIndicators: false) {
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
       Text("some text").font(.system(size: 60)).padding()
    }
    Spacer()
    Button(action: {
       print("button clicked")
    }) {
       Text("MY BUTTON")
    }
}

您需要明确的视图容器来管理底栏,例如

struct BottomBarContainer<Content: View>: View {
    let content: () -> Content

    init(@ViewBuilder _ content: @escaping () -> Content) {
        self.content = content
    }

    var body: some View {
        VStack {
            content()
            Spacer() // << always pushes below bar to bottom
            BaseBottomButton() // or any bar container here
        }
    }
}

因此独立于使用的内容底部栏将始终位于底部。

因此,我们可以从NewView中删除BaseBottomButton()并以与使用的其他 SwiftUI 容器相同的方式使用它:

BottomBarContainer {
   NewView()
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM