SwiftUI Toggle 更改值时运行代码

Posted

技术标签:

【中文标题】SwiftUI Toggle 更改值时运行代码【英文标题】:Running code when SwiftUI Toggle Changes Value 【发布时间】:2021-07-30 21:07:59 【问题描述】:

我的代码的一般结构是我有一个 UIKit 应用程序,我试图在其中嵌入一个 swiftui 视图。所以我有一个名为 SettingsViewController 的文件,如下所示:

class SettingsViewController: UIViewController 
    ...
    var items: [(SettingsView.Setting)] = ...
    var actionsForItems: [() -> Void = []

    @State var isOn: Bool = false

    override func viewDidLoad() 
        super.viewDidLoad()
        actionsForItems = ...
        ...
        addSettingCell(isOn: isOn)

        let childView = UIHostingController(rootView: SettingsView(settings: items, actionsForSettings: actionsForItems))
        addChild(childView)
        childView.view.frame = container.bounds
        container.addSubview(childView.view)
        childView.didMove(toParent: self)
    

...

    func addCell(isOn: Bool) 
        items.insert((settingName, $isOn as AnyObject) as SettingsView.Setting)
        actionsForItems.insert(
            self.onSwitchValueChanged(isOn: isOn) //defined later
        )
    

它创建了一个名为 Settings View 的视图,其结构如下:

struct SettingsView: View 
    typealias Setting = (key: String, value: AnyObject?)
    var settings: [Setting]
    var actions: [() -> Void]
    
    var body: some View 
        List(settings.indices)  index in
            ...
            SettingsWithSwitchView(setting: settings[index], action: actions[index], isOn: setting.value as Binding<Bool>)
        
        Spacer()
    

和SettingsWithSwitchView如下:

struct SettingsWithSwitchView: View 
    var setting: SettingsView.Setting
    var action: () -> Void
    @Binding var isOn: Bool 
        willSet 
            print("willSet: newValue =\(newValue)  oldValue =\(isOn)")
        
        didSet 
            print("didSet: oldValue=\(oldValue) newValue=\(isOn)")
            action()
        
    
    
    var body: some View 
        HStack 
            Text(setting.key)
                .foregroundColor(Color("GrayText"))
                .font(Font.custom("OpenSans", size: 15))
            Spacer()
            Toggle(isOn: $isOn) 
        
    

我在 Stack Overflow 上的另一篇文章中读到,在 isOn 属性上调用 didSet 应该是实现此目的的方法,但是当更新 Toggle 值时我需要调用 onSwitchValueChanged,但我当前的设置不起作用。我真的很感激一些帮助来弄清楚如何做到这一点。如有必要,我可以更新一些其他信息。

【问题讨论】:

State 用于 SwiftUI 视图而不是 UIViewControllers 那么我需要做什么替代方案呢?我尝试在 SettingsWithSwitchView 中使用 state 变量,但这也不起作用,因为它不会更新 ViewController 类中的值。 好像你想要ObservableObject(我遇到了类似的问题here) 委托、ObservableObjects、传递动作等。SO 中有很多关于 SwiftUI 和 UIViewController 通信的问题 【参考方案1】:

最终为我工作的事情是创建一个 ViewModel,它也是一个 ObservableObject,然后为 .onTapGesture 内部的切换设置操作

【讨论】:

以上是关于SwiftUI Toggle 更改值时运行代码的主要内容,如果未能解决你的问题,请参考以下文章

UserDefaults 在 SwiftUI 中与 Toggle 绑定

切换 swiftUI toggle() 时如何触发操作?

更改 SwiftUI 切换的输出

在 SwiftUI 中动态更改动画的持续时间

SwiftUI:更改数据源时选择器无法正确更新

根据 SwiftUI 中的切换值更改文本