2

我正在尝试为我的 UIButton 创建 isHighlighted Observable,以在每次 UIButton 的 isHiglighted 发生更改时发送序列。我写了这样的东西

extension Reactive where Base: UIButton {

    var isHighlighted: Observable<Bool> {

        let property = self.base.rx.controlProperty(editingEvents: .allTouchEvents,
                                                    getter: { _ in self.base.isHighlighted },
                                                    setter: { (_, _) in })
        return property
            .distinctUntilChanged()
            .asObservable()
    }
}

问题是,它不适用于.touchUpInside. 如果我将手指拖到 UIButton 外然后回来,它可以正常工作,但不适用于点击操作。我认为.touchUpInside它仍然在很短的时间内突出显示。

4

2 回答 2

7

谢谢@iWheelBuy 我已经创建了没有 RxOptional 的有效代码,我部分基于您的回答,所以谢谢!这是工作代码:

extension Reactive where Base: UIButton {
    var isHighlighted: Observable<Bool> {
        let anyObservable = self.base.rx.methodInvoked(#selector(setter: self.base.isHighlighted))

        let boolObservable = anyObservable
            .flatMap { Observable.from(optional: $0.first as? Bool) }
            .startWith(self.base.isHighlighted)
            .distinctUntilChanged()
            .share()

        return boolObservable
    }
}
于 2018-02-03T18:46:29.883 回答
1

我想我有一个解决办法。它可以简化,但我只是复制粘贴我拥有的完整解决方案。

public extension Reactive where Base: UIButton {

    public func isHighlighted() -> Observable<Bool> {
        let selector = #selector(setter: UIButton.isHighlighted)
        let value: ([Any]) -> Bool? = { $0.first(where: { $0 is Bool }) as? Bool }
        return base
            .observable(selector: selector, value: value)
            .filterNil()
            .startWith(base.isHighlighted)
            .distinctUntilChanged()
            .share(replay: 1, scope: .whileConnected)
    }
}

另外,要让它发挥作用。您需要RxOptional一些额外的代码:

public enum InvocationTime: Int {

    case afterMessageIsInvoked
    case beforeMessageIsInvoked
}

public extension NSObject {

    public func observable<T>(selector: Selector, value: @escaping ([Any]) -> T, when: InvocationTime = .afterMessageIsInvoked) -> Observable<T> {
        let observable: Observable<[Any]> = {
            switch when {
            case .afterMessageIsInvoked:
                return rx.methodInvoked(selector)
            case .beforeMessageIsInvoked:
                return rx.sentMessage(selector)
            }
        }()
        return observable
            .map({ value($0) })
            .share(replay: 1, scope: .whileConnected)
    }
}

希望对你有帮助(^

于 2018-02-03T04:50:09.283 回答