SwiftUI中使用self.<变量>修改变量失败(KeyboardKit自定义键盘)
问题根源
你犯了SwiftUI状态管理的基础错误:@State属性包装器只能用在SwiftUI的View结构体里,不能用在UIKit的ViewController类中。放在ViewController里的@State根本起不到状态绑定的作用,所以修改self.text不会触发视图更新,看起来像是无法修改。
解决方案
有两种常用的修复方式,根据你的需求选择:
方案1:把状态移到SwiftUI视图内部(推荐)
直接在嵌入的SwiftUI视图里定义@State,这是最符合SwiftUI设计逻辑的做法:
import UIKit import KeyboardKit import SwiftUI class KeyboardViewController: KeyboardInputViewController { override func viewWillSetupKeyboard() { super.viewWillSetupKeyboard() setup { controller in // 自定义SwiftUI视图,内部管理状态 CustomKeyboardView() } } } // 单独的SwiftUI视图,用@State管理状态 struct CustomKeyboardView: View { @State private var text = "init" var body: some View { VStack(spacing: 0) { Button(text) { text = "changed" // 直接修改,不需要self } Text(text) } } }
方案2:在ViewController中用ObservableObject管理状态
如果需要在ViewController层面控制状态,可以用ObservableObject:
import UIKit import KeyboardKit import SwiftUI // 定义状态管理类 class KeyboardState: ObservableObject { @Published var text = "init" // @Published会自动通知视图更新 } class KeyboardViewController: KeyboardInputViewController { // 用@StateObject持有状态对象(iOS 14+) private let keyboardState = KeyboardState() override func viewWillSetupKeyboard() { super.viewWillSetupKeyboard() setup { controller in CustomKeyboardView(state: self.keyboardState) } } } struct CustomKeyboardView: View { @ObservedObject var state: KeyboardState // 观察状态变化 var body: some View { VStack(spacing: 0) { Button(state.text) { state.text = "changed" } Text(state.text) } } }
额外说明
- 之前必须加
self.是因为闭包中Swift需要明确捕获self,但由于你的@State用错了位置,即使加了self.也无法正确更新状态。 - 方案1更轻量,适合状态只在SwiftUI视图内部使用的场景;方案2适合需要在ViewController和SwiftUI视图之间共享状态的场景。
内容的提问来源于stack exchange,提问作者Saihhold Chiu
相关产品推荐
相关产品推荐

