iOS14下SwiftUI ToolbarItem双按钮组件异常间隙问题求助
iOS 14 SwiftUI Toolbar 自定义双按钮组件间隙异常问题
问题描述
在iOS 14环境下开发SwiftUI应用时,将自定义LanguageButtonView组件放入ToolbarItem(placement设为.topBarTrailing)后,组件内两个按钮之间出现明显异常间隙。但将组件放在VStack顶部时显示完全符合预期;仅在Toolbar中放置单个按钮时显示正常,双按钮场景才会触发问题,且异常仅出现在左侧按钮,右侧按钮位置无偏差。
相关代码
Toolbar 代码
.toolbar { ToolbarItem(placement: .topBarTrailing) { LanguageButtonView(buttonBackgroundColor: .clear) .environmentObject(appManager) } }
LanguageButtonView 完整代码
var body: some View { HStack(spacing: 0) { Button { self.hideKeyboard() appManager.language = .th LocalizeManager.setLanguage(langCode: .th) } label: { ZStack { Rectangle() .fill(appManager.language == .th ? colorPalette.color(style: .color434B24) : Color.white) .cornerRadius(6, corners: [.topLeft, .bottomLeft]) .frame(width: 40, height: 32) Text("common_th".localized(appManager.language.rawValue)) .foregroundColor(appManager.language == .th ? .white : colorPalette.color(style: .color434B24)) .font(fontSet.font(style: .header1)) } } Button { self.hideKeyboard() appManager.language = .en LocalizeManager.setLanguage(langCode: .en) } label: { ZStack { Rectangle() .fill(appManager.language == .en ? colorPalette.color(style: .color434B24) : Color.white) .cornerRadius(6, corners: [.topRight, .bottomRight]) .frame(width: 40, height: 32) Text("common_en".localized(appManager.language.rawValue)) .foregroundColor(appManager.language == .en ? .white : colorPalette.color(style: .color434B24)) .font(fontSet.font(style: .header1)) } } } .frame(width: 80, height: 32) .overlay( RoundedRectangle(cornerRadius: 6) .stroke(colorPalette.color(style: .color434B24), lineWidth: 1) ) }
LanguageButtonView 最小复现代码
struct LanguageButtonView: View { var buttonBackgroundColor: Color var borderColor: Color = .white var body: some View { HStack(spacing: 0) { Button { self.hideKeyboard() } label: { ZStack { Rectangle() .fill(.clear) .cornerRadius(6, corners: [.topLeft, .bottomLeft]) .frame(width: 40, height: 32) Text("TH") } } Button { self.hideKeyboard() } label: { ZStack { Rectangle() .fill(Color.white) .cornerRadius(6, corners: [.topRight, .bottomRight]) .frame(width: 40, height: 32) Text("EN") } } } .frame(width: 80, height: 32) .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color(hex: "434B24"), lineWidth: 1) ) } } #Preview { LanguageButtonView(buttonBackgroundColor: .blue) .environmentObject(AppManager()) }
![组件在Toolbar(上方)和VStack(下方)的显示对比图]
解决办法
核心原因
iOS 14的Toolbar会给内部可交互元素(如Button)添加默认内边距,多个按钮叠加时会触发异常间隙;同时Toolbar的布局优先级逻辑会优先拉伸可交互元素,导致自定义组件的尺寸约束失效。
具体修复方案
移除Button默认内边距
给每个Button添加.buttonStyle(PlainButtonStyle()),去掉系统默认的按钮样式内边距;同时给按钮label添加明确的frame和contentShape,确保点击区域符合预期。固定组件尺寸+提升布局优先级
在LanguageButtonView外层添加.fixedSize()强制保留组件原始尺寸,同时给ToolbarItem内的组件添加.layoutPriority(1),让Toolbar优先遵循自定义组件的尺寸约束。
修改后的代码示例
修改后的LanguageButtonView
struct LanguageButtonView: View { var buttonBackgroundColor: Color var borderColor: Color = .white var body: some View { HStack(spacing: 0) { Button { self.hideKeyboard() } label: { ZStack { Rectangle() .fill(.clear) .cornerRadius(6, corners: [.topLeft, .bottomLeft]) .frame(width: 40, height: 32) Text("TH") } .frame(width: 40, height: 32) .contentShape(Rectangle()) } .buttonStyle(PlainButtonStyle()) Button { self.hideKeyboard() } label: { ZStack { Rectangle() .fill(Color.white) .cornerRadius(6, corners: [.topRight, .bottomRight]) .frame(width: 40, height: 32) Text("EN") } .frame(width: 40, height: 32) .contentShape(Rectangle()) } .buttonStyle(PlainButtonStyle()) } .frame(width: 80, height: 32) .fixedSize() .overlay( RoundedRectangle(cornerRadius: 6) .stroke(Color(hex: "434B24"), lineWidth: 1) ) } private func hideKeyboard() { // 实现隐藏键盘逻辑 } }
修改后的Toolbar代码
.toolbar { ToolbarItem(placement: .topBarTrailing) { LanguageButtonView(buttonBackgroundColor: .clear) .environmentObject(appManager) .layoutPriority(1) .fixedSize() } }
内容的提问来源于stack exchange,提问作者Noppakun Anantakitthawon
相关产品推荐
相关产品推荐

