RxSwift: Как автоматически изменить размер подслоя с изменением размера представления - PullRequest
1 голос
/ 07 июля 2019

Я изучаю RxSwift.

Я добавил границу как CALayer в TextField.Я хотел бы сделать эту границу реактивно изменяемой автоматически при расширении textField (inputView изменен на pickerView, поэтому я хочу, чтобы его можно было изменить, выбирая заголовки)

Я пробовал .rx.observe(CGRect.self, "frame"), но он не работает должным образом.

extension UITextField {

    func addBorderBottom(height: CGFloat, color: UIColor, width: CGFloat){
        let border = CALayer()
        border.frame = CGRect(x: 0, y: self.frame.height - height, width: width, height: height)
        border.backgroundColor = color.cgColor
        self.layer.addSublayer(border)
    }

}
// viewContrller

func listDetailUISetup() {
        let yellowColor = UIColor.hex(string: "FFB500", alpha: 1)
        tagTextField.addBorderBottom(height: 1.0, color: yellowColor, width: tagTextField.frame.width)
}

//
picker.rx.modelSelected(String.self)
            .subscribe(onNext: { tags in
                self.tagTextField.text = tags[0]
            })
            .disposed(by: disposeBag)

tagTextField.rx.observe(CGRect.self, "frame")
            .subscribe(onNext: { frame in
                print("field frame changed")
                let layer = self.tagTextField.layer.sublayers![0]
                layer.frame = frame!
            })
            .disposed(by: disposeBag)

Вторым способом я также попытался вручную переустановить границу после удаления предыдущей, когда выбран заголовок в окне выбора.Но, по-видимому, отражается ширина элемента, выбранного в предыдущий раз.

начальная ширина

enter image description here

ширина всего

enter image description here

Ширина фаворита

enter image description here

icker.rx.modelSelected(String.self)
            .subscribe(onNext: { tags in
                self.tagTextField.text = tags[0]
                self.tagTextField.layer.sublayers = nil
                self.listDetailUISetup()
            })
            .disposed(by: disposeBag)

Надеюсь, вы могли бы помочьрешить эту проблему.

Спасибо.

1 Ответ

0 голосов
/ 07 июля 2019

Свойство frame в UIView не является наблюдаемым KVO, поэтому вы не можете наблюдать его. Метод layoutSubviews текстового поля вызывается всякий раз, когда он меняет размер, поэтому вы можете использовать его.

extension UIView {
    func addDynamicBorderBottom(height: CGFloat, color: UIColor) -> Disposable {
        let border = CALayer()
        border.frame = CGRect(x: 0, y: frame.height - height, width: frame.width, height: height)
        border.backgroundColor = color.cgColor
        layer.addSublayer(border)

        return rx.methodInvoked(#selector(UIView.layoutSubviews))
            .bind(onNext: { [frame] _ in
                border.frame = CGRect(x: 0, y: frame.height - height, width: frame.width, height: height)
            })
    }
}

Но было бы лучше сделать вашу рамку UIView и установить ограничения, чтобы она оставалась нужного размера.

...