为 UIButton isHighlighted 属性设置 Observable
Posted
技术标签:
【中文标题】为 UIButton isHighlighted 属性设置 Observable【英文标题】:Make Observable for UIButton isHighlighted property 【发布时间】:2018-02-02 22:18:26 【问题描述】:我正在尝试为我的 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
之后它仍然会在很短的时间内突出显示。
【问题讨论】:
我希望找到专门解决此问题的 Apple 文档,但失败了。我找到了将按钮状态设置为highlighted
- “例如,当用户点击带有标题的按钮时,该按钮将移动到突出显示状态。” - 但不是设置它的原因。 ..default
?但它是有道理的(至少对我来说)直到其他东西收到“焦点”(使用 MSFT 术语)操作系统可能被设计为将“焦点”保持在按钮上。因此,移除高亮状态的“延迟”。
@dfd 您还有其他想法如何为 isHighlighted UIButton 属性创建 Observable 吗?没有子类化 UIButton
我不使用 [rx-swift],但你能否创建一个简单的扩展 UIButton
并覆盖 isHightlighted
,在 didSet
中做你需要的事情。我刚试过这个,没有错误。
【参考方案1】:
感谢@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
【讨论】:
不错!我会选择 methodInvoked 作为默认实现,而不是 sentMessage。但这取决于你? 你说得对,应该在方法调用后调用谢谢!【参考方案2】:我想我有一个解决办法。它可以简化,但我只是复制粘贴我拥有的完整解决方案。
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)
希望对你有帮助(^
【讨论】:
以上是关于为 UIButton isHighlighted 属性设置 Observable的主要内容,如果未能解决你的问题,请参考以下文章