簡體   English   中英

SwiftUI 在 .safeAreaInset 中添加 menu 導致奇怪的布局問題

[英]SwiftUI add `menu` in `.safeAreaInset` cause strange layout issue

這是示例項目源代碼: sample code

import SwiftUI

struct TestMenuInSafeAreaInset: View {
    @State private var message = ""

    var body: some View {
        VStack {
            Rectangle()
                .fill(Color.blue)
        }
            .safeAreaInset(edge: .bottom) {
                HStack {
                    TextField("Input your message", text: $message)
                        .padding()
                        .background(Color.brown)
                        .cornerRadius(12)
                        .foregroundColor(.white)
                    Menu {
                        Button {

                        } label: {
                            Text("Confirm")
                        }

                        Button {

                        } label: {
                            Text("Cancel")
                        }

                    } label: {
                        Image(systemName: "square.and.arrow.up.fill")
                            .tint(.white)
                            .padding()
                            .background(Color.brown)
                            .cornerRadius(50)
                    }
                }
                .padding()
            }
    }
}

struct TestMenuInSafeAreaInset_Previews: PreviewProvider {
    static var previews: some View {
        TestMenuInSafeAreaInset()
    }
}

當鍵盤出現時,操作菜單按鈕(右下角)向上移動一點,點擊菜單會導致奇怪的布局,如圖 gif 所示。

我認為這是一個錯誤,有解決辦法嗎? 我用 iOS 16 和 iOS 15 測試上面的代碼,行為相同。

正常狀態,沒問題

第一次顯示鍵盤時,右操作菜單按鈕向上推一點。

[更新於 2022.10.10 11:31 +8]

作為@Saket Kumar 的解決方案,我更新代碼如下,即使我給menu設置size ,問題也會重現。

用iPhone 14 pro模擬器測試 iOS 16.

struct TestMenuInSafeAreaInset: View {
    @State private var message = ""

    var body: some View {
        VStack {
            TextField("Input your user name", text: $message)
                .padding()
                .background(Color.gray.opacity(0.3))
                .cornerRadius(12)
                .padding()
            Spacer()
        }
        .safeAreaInset(edge: .bottom) {
            HStack {
                Spacer()
                    .frame(height: 70)
                Menu {
                    Button {

                    } label: {
                        Text("Confirm")
                    }

                    Button {

                    } label: {
                        Text("Cancel")
                    }
                } label: {
                    Image(systemName: "square.and.arrow.up.fill")
                        .padding()
                        .tint(.white)
                        .background(Color.brown)
                        .cornerRadius(50)
                }
                .frame(width: 50, height: 50)
            }
            .padding(.horizontal, 20)
            .background(Color.blue)
        }
    }
}

第一次出現鍵盤時,菜單圖標向上移動。

似乎是 SwiftUI 的問題。我測試了您的代碼並且能夠重現該問題。

我有預感,這種奇怪的行為可能是由 TextField 的框架和菜單的框架重疊引起的,SwiftUI 正試圖適應這種情況。

所以我嘗試手動給他們框架,它似乎解決了這個問題。

只需更改這部分代碼即可。

    .safeAreaInset(edge: .bottom) {
        HStack {
            TextField("Input your message", text: $message)
                .padding()
                .background(Color.brown)
                .cornerRadius(12)
                .foregroundColor(.white)
                .frame(width: UIScreen.main.bounds.width*0.75, height: 50, alignment: .leading)
            Spacer()
            Menu {
                Button {

                } label: {
                    Text("Confirm")
                }

                Button {

                } label: {
                    Text("Cancel")
                }

            } label: {
                Image(systemName: "square.and.arrow.up.fill")
                    .tint(.white)
                    .padding()
                    .background(Color.brown)
                    .cornerRadius(50)
            }.frame(width: UIScreen.main.bounds.width*0.10, height: 50, alignment: .trailing)
        }
        .padding()
    }

公平的警告。 我放的那些框架可能與您想要的不完全一樣。 我已經測試了這段代碼它有效。

在此處輸入圖像描述

[剛剛在演示項目中添加了你的代碼來模擬它]

我的建議是給菜單固定寬度和高度,比如 60*60。 然后從屏幕的寬度中取出 60,考慮填充。 並為 TextField 提供合適的框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM