【问题标题】:RxSwift - make one UI element hidden/not hidden according to other elementRxSwift - 根据其他元素隐藏/不隐藏一个 UI 元素
【发布时间】:2018-07-12 12:38:22
【问题描述】:

我在我的项目中使用RxSwift 和RxCocoa。

我有一些UITextField 名为“lastNameTF”,还有一个UILabel 名为“lastNameTitle”。

我想知道是否有任何方法可以使用RxSwift 将lastNameTitle 的isHidden 值设置为始终等于lastNameTF 的isHidden 值。

【问题讨论】:

    标签: swift rx-swift rx-cocoa


    【解决方案1】:

    【讨论】:

      【解决方案2】:

      KVO 超级好用。 Here is an example 正是你想要做的事情,只是没有使用 RxSwift(不知道那是什么......)

      这里是重点

      class ViewController: UIViewController {
          private var lastNameTextFieldHiddenContext = 0
          private var lastNameObservingView:UIView? = nil
          @IBOutlet weak var lastNameLabel: UILabel!
          @IBOutlet weak var lastNameTextField: UITextField!
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // add the observer
              lastNameTextField.addObserver(
                  self,
                  forKeyPath: "hidden",
                  options: [.new],
                  context: &self.lastNameTextFieldHiddenContext
              )
          }
      
          /// function will be called whenever an added observer is triggered
          override func observeValue(
              forKeyPath keyPath: String?,
              of object: Any?,
              change: [NSKeyValueChangeKey : Any]?,
              context: UnsafeMutableRawPointer?
          ) {
              // make sure it is our text field isHidden observer
              if context == &self.lastNameTextFieldHiddenContext {
                  // get the new value that was set
                  if let newValue = change?[NSKeyValueChangeKey.newKey] as? Bool {
                      // do what needs to be done when the observer is triggered
                      self.lastNameLabel.isHidden = newValue
                  }
              }
          }
      
          deinit {
              // remove the observer
              if let view = self.lastNameObservingView {
                  view.removeObserver(self, forKeyPath: "hidden")
                  self.lastNameObservingView = nil
              }
          }
      
          @IBAction func showHideButtonAction(_ sender: Any) {
              self.lastNameTextField.isHidden = !self.lastNameTextField.isHidden
          }
      }
      

      【讨论】:

      • 您的答案并不完全符合我的要求,但它在某种程度上帮助了我。 RxSwift 很棒,你应该去看看。我的问题是我试图用名为“isHidden”的“keyPath”收听属性,但在阅读了你的答案后,我看到你使用“hidden”作为keyPath,它对我有用:)
      • 这解释了为什么它是“隐藏的”而不是“隐藏的”。 stackoverflow.com/questions/41746751/…
      【解决方案3】:

      如果你仍然需要一个简单的 RxSwift 方法,请试试这个:

      // Controls are visible by default (isHidden = false)
      let isControlHidden = BehaviorRelay<Bool>(value: false)
      
      override func viewDidLoad() {
        super.viewDidLoad()
      
        let isHiddenDriver = self.isControlHidden.asDriver()
      
        isHiddenDriver
          .drive(self.lastNameTitle.rx.isHidden)
          .disposed(by: disposeBag)
      
        isHiddenDriver
          .drive(self.lastNameTF.rx.isHidden)
          .disposed(by: disposeBag)
      }
      

      由于您需要相互绑定的两个控件可见性,您可以使用主题或中继来实现这一点,在本例中为 isControlHidden。所以,如果你想显示/隐藏,你只需发出一个新信号:

      @IBAction func hide(_ sender: Any) {
        self.isControlHidden.accept(true)
      }
      
      @IBAction func show(_ sender: Any) {
        self.isControlHidden.accept(false)
      }
      

      【讨论】:

      • 看起来不错,但有编译错误 - 'Binder' 类型的值没有成员 'asDriver'
      • 你是对的。 'lastNameTF.rx.isHidden' 不是 ControlProperty,而是 Binder。但是,我用一个可能对您有帮助的仍然干净可行的解决方案更新了我的答案。
      猜你喜欢
      • 2018-11-06
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2015-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多