[英]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.