import SwiftUI // MARK: - 通用键盘工具栏组件 struct KeyboardToolbarView: View { let onDone: () -> Void let showDoneButton: Bool let additionalButtons: [KeyboardToolbarButton] init( onDone: @escaping () -> Void = {}, showDoneButton: Bool = true, additionalButtons: [KeyboardToolbarButton] = [] ) { self.onDone = onDone self.showDoneButton = showDoneButton self.additionalButtons = additionalButtons } var body: some View { Group { // 左侧按钮 HStack(spacing: 12) { ForEach(additionalButtons.filter { $0.position == .left }, id: \.id) { button in Button(action: button.action) { HStack(spacing: 4) { if let icon = button.icon { Image(systemName: icon) .font(.system(size: 16, weight: .medium)) } Text(button.title) .font(.system(size: 16, weight: .medium)) } .foregroundColor(button.color) } } } Spacer() // 右侧按钮 HStack(spacing: 12) { ForEach(additionalButtons.filter { $0.position == .right }, id: \.id) { button in Button(action: button.action) { HStack(spacing: 4) { if let icon = button.icon { Image(systemName: icon) .font(.system(size: 16, weight: .medium)) } Text(button.title) .font(.system(size: 16, weight: .medium)) } .foregroundColor(button.color) } } if showDoneButton { Button("完成", action: onDone) .foregroundColor(.blue) .font(.system(size: 16, weight: .medium)) } } } .toolbar { ToolbarItemGroup(placement: .keyboard) { // 左侧按钮 HStack(spacing: 12) { ForEach(additionalButtons.filter { $0.position == .left }, id: \.id) { button in Button(action: button.action) { HStack(spacing: 4) { if let icon = button.icon { Image(systemName: icon) .font(.system(size: 16, weight: .medium)) } Text(button.title) .font(.system(size: 16, weight: .medium)) } .foregroundColor(button.color) } } } Spacer() // 右侧按钮 HStack(spacing: 12) { ForEach(additionalButtons.filter { $0.position == .right }, id: \.id) { button in Button(action: button.action) { HStack(spacing: 4) { if let icon = button.icon { Image(systemName: icon) .font(.system(size: 16, weight: .medium)) } Text(button.title) .font(.system(size: 16, weight: .medium)) } .foregroundColor(button.color) } } if showDoneButton { Button("完成", action: onDone) .foregroundColor(.blue) .font(.system(size: 16, weight: .medium)) } } } } } } // MARK: - 键盘工具栏按钮 struct KeyboardToolbarButton { let id = UUID() let title: String let icon: String? let color: Color let position: ButtonPosition let action: () -> Void enum ButtonPosition { case left, right } init( title: String, icon: String? = nil, color: Color = .blue, position: ButtonPosition = .right, action: @escaping () -> Void ) { self.title = title self.icon = icon self.color = color self.position = position self.action = action } } // MARK: - 预定义的工具栏按钮 extension KeyboardToolbarButton { static func clear( text: Binding, position: ButtonPosition = .left ) -> KeyboardToolbarButton { KeyboardToolbarButton( title: "清空", icon: "trash", color: .red, position: position ) { text.wrappedValue = "" } } static func copy( text: String, position: ButtonPosition = .left ) -> KeyboardToolbarButton { KeyboardToolbarButton( title: "复制", icon: "doc.on.doc", color: .blue, position: position ) { UIPasteboard.general.string = text } } static func paste( text: Binding, position: ButtonPosition = .left ) -> KeyboardToolbarButton { KeyboardToolbarButton( title: "粘贴", icon: "doc.on.clipboard", color: .green, position: position ) { if let pastedText = UIPasteboard.general.string { text.wrappedValue = pastedText } } } static func next( action: @escaping () -> Void, position: ButtonPosition = .right ) -> KeyboardToolbarButton { KeyboardToolbarButton( title: "下一个", icon: "arrow.right", color: .blue, position: position, action: action ) } static func previous( action: @escaping () -> Void, position: ButtonPosition = .left ) -> KeyboardToolbarButton { KeyboardToolbarButton( title: "上一个", icon: "arrow.left", color: .blue, position: position, action: action ) } } // MARK: - 预定义的工具栏样式 extension KeyboardToolbarView { static func simple(onDone: @escaping () -> Void = {}) -> KeyboardToolbarView { KeyboardToolbarView(onDone: onDone) } static func withClear( text: Binding, onDone: @escaping () -> Void = {} ) -> KeyboardToolbarView { KeyboardToolbarView( onDone: onDone, additionalButtons: [ .clear(text: text) ] ) } static func withCopyPaste( text: Binding, onDone: @escaping () -> Void = {} ) -> KeyboardToolbarView { KeyboardToolbarView( onDone: onDone, additionalButtons: [ .copy(text: text.wrappedValue), .paste(text: text) ] ) } static func withNavigation( onPrevious: @escaping () -> Void, onNext: @escaping () -> Void, onDone: @escaping () -> Void = {} ) -> KeyboardToolbarView { KeyboardToolbarView( onDone: onDone, additionalButtons: [ .previous(action: onPrevious), .next(action: onNext) ] ) } } #Preview { VStack(spacing: 16) { Text("简单工具栏") .font(.headline) Text("带清空按钮的工具栏") .font(.headline) Text("带复制粘贴的工具栏") .font(.headline) Text("带导航的工具栏") .font(.headline) } .padding() }