RxSwift - сделать один элемент интерфейса скрытым / не скрытым в соответствии с другим элементом

Я использую RxSwift а также RxCocoa в моем проекте.

у меня есть немного UITextField с именем "lastNameTF", и есть UILabel имя "lastNameTitle".

Я хочу знать, есть ли способ установить isHidden Значение lastNameTitle всегда будет равно isHidden значение lastNameTF, используя RxSwift,

3 ответа

Решение

Я полагаю, что вы можете использовать KVO, как описано здесь - https://github.com/ReactiveX/RxSwift/blob/master/Documentation/GettingStarted.md#kvo

Это супер простой в использовании КВО. Вот пример того, что вы пытаетесь сделать, просто без использования 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, попробуйте это:

// 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)
}

Поскольку вам нужны оба элемента управления видимости, связанные друг с другом, вы можете использовать Subject или Relay для достижения этого, в данном случае isControlHidden. Итак, если вы хотите показать / скрыть, вы просто излучаете новый сигнал:

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

@IBAction func show(_ sender: Any) {
  self.isControlHidden.accept(false)
}
Другие вопросы по тегам