Ios ReactiveSwift/ReactiveCocoa:如何使用UIButton禁用的样式,但在操作进行时不使用?

Ios ReactiveSwift/ReactiveCocoa:如何使用UIButton禁用的样式,但在操作进行时不使用?,ios,reactive-cocoa,reactive-swift,Ios,Reactive Cocoa,Reactive Swift,ui按钮可以配置为在按钮启用或禁用时使用不同的样式、标题等,例如使用ui按钮。设置标题(字符串,forState:uicontrol状态) ReactiveCocoa让我将ReactiveSwift.Action连接到按钮的reactive.pressed属性,如果Action被禁用,按钮将显示禁用的样式:这太棒了 但是,ReactiveSwift.Action在有一个SignalProducer正在进行时也被禁用。此锁定对于附加到慢速操作(例如网络请求)的UI元素非常有用,但当操作快速但不是即

ui按钮
可以配置为在按钮启用或禁用时使用不同的样式、标题等,例如使用
ui按钮。设置标题(字符串,forState:uicontrol状态)

ReactiveCocoa
让我将
ReactiveSwift.Action
连接到按钮的
reactive.pressed
属性,如果
Action
被禁用,按钮将显示禁用的样式:这太棒了

但是,
ReactiveSwift.Action
在有一个
SignalProducer
正在进行时也被禁用。此锁定对于附加到慢速操作(例如网络请求)的UI元素非常有用,但当操作快速但不是即时时,会产生不希望的视觉闪烁

一个简单的解决方法是不使用内置的
ui按钮
禁用样式:相反,我们可以在某个地方公开
属性
,并使用它来启用/禁用
操作
和显式更改按钮的样式。然而,这有点笨拙和尴尬,因此我的问题是:是否有一种“干净”的方式将
ui按钮
内置禁用样式与通过显式禁用
操作
内部
ui按钮。被动。按下
,禁用按钮相结合,当操作正在进行时,没有显示禁用的样式?

我们最终使用显式编码:

extension UIControlState {
    public static var myActionIsExecuting = UIControlState(rawValue: 1 << 16)
}

public class ReactiveAwareStylingButton: UIButton {
    override public var state: UIControlState {
        return [super.state, customState]
    }
    var customState: UIControlState {
        if reactive.pressed?.isExecuting.value == true {
            return [.myActionIsExecuting]
        }
        return []
    }
}
如果需要,我们还可以选择在执行操作时使用禁用的样式(这可能适用于慢速操作,例如网络请求),只需忽略
.myActionIsExecuting
状态即可

如果应用此技术,请注意编译器将愉快地允许您犯语义错误:您可以将上述样式应用于一个
UIButton
实例,该实例不是自定义子类
ReactiveAwareStylingButton
,它将永远不会进入状态
。myActionIsExecuting
。您应该防止出现此错误,例如,仅在使用
ReactiveAwareStylingButton
参数的函数中应用样式

button.setTitleColor(normalColor, for: .normal)
button.setTitleColor(normalColor, for: [.disabled, .myActionIsExecuting])
button.setTitleColor(disabledColor, for: .disabled)