簡體   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