ios 如何以编程方式调用`UISwitch`的操作?

piwo6bdm  于 2023-08-08  发布在  iOS
关注(0)|答案(1)|浏览(113)

我有一个UIViewController,在一个SPM包中,有一个UITableView和一些简单的单元格--它们要么是细节披露,要么有一个UISwitch
我试图编写单元测试来确认当特定行中的开关被切换时,所需的操作被调用。该操作由其他代码提供,因此单元格配置如下所示:

let toggle = UISwitch(frame: .zero, primaryAction: UIAction(handler: { action in
    guard let toggle = action.sender as? UISwitch else { return }
    toggleAction(toggle.isOn)
}))
cell.accessoryView = toggle

字符串
(其中,toggleAction是传递给VC的init的众多函数之一)
我的测试可以找到感兴趣的行,以及它上面的开关。它可以通过.isOn修改值,但这不会触发操作。我知道需要一个UIApplication才能让.sendActions(for:)工作,所以我使用解决方案here,并确认它适用于UIButton s。我尝试向UISwitch发送各种事件(.touchUpInside.valueChanged.primaryActionTriggered),但没有一个事件导致调用注册的操作。这可能吗?

mtb9vblg

mtb9vblg1#

UISwitch是一个UIControl。由于您使用UIAction为主要操作设置了交换机,因此可以在交换机上调用sendActions

let switch = ... // a reference to the UISwitch from the table cell
switch.isOn = true // or false as needed
switch.sendActions(for: .primaryActionTriggered)

字符串
这将导致开关的操作被调用,而开关的操作又调用toggleAction方法。
为此,不需要对UIApplication的引用。
下面是一些示例代码,演示了使用sendActionsUISwitchUIButton都有效,并且无论控件是用主操作还是用目标/选择器设置的,它都有效。
以下内容可在iOS Swift Playground中运行。

class Controls {
    func toggleAction(_ isOn: Bool) {
        print("toggleAction: \(isOn)")
    }
    @objc func toggleHandler(_ sender: UIControl) {
        print("toggleHandler: \(sender)")
    }

    lazy var toggle = UISwitch(frame: .zero, primaryAction: UIAction(handler: { action in
        guard let toggle = action.sender as? UISwitch else { return }
        self.toggleAction(toggle.isOn)
    }))
    lazy var button = UIButton(primaryAction: UIAction(handler: { action in
        self.toggleAction(false)
    }))
    lazy var other = UIButton(type: .custom)

    func doStuff() {
        other.addTarget(self, action: #selector(toggleHandler), for: .touchUpInside)
        toggle.isOn.toggle()
        toggle.sendActions(for: .primaryActionTriggered)
        other.sendActions(for: .touchUpInside)
        button.sendActions(for: .primaryActionTriggered)
    }
}

let x = Controls()
x.doStuff()


输出内容如下所示:
切换操作:真的
触发器处理程序:用户界面按钮:0x 7 fb 77 f406320帧=(0 0; 0 0);不透明=否;图层=<CALayer: 0x6000037e2fc0>>
切换操作:假的

相关问题