RxSwift:如何使用视图的大小自动调整子图层的大小

时间:2019-07-07 02:34:51

标签: swift rx-swift

我正在学习RxSwift。

我在TextField中添加了一个边框作为CALayer。我想在扩展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)

以第二种方式,当在pickerView中选择标题时,我还尝试在删除上一个边框后手动重新设置边框。但是显然,上一次选择的项目的宽度会得到反映。

初始宽度

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 :(得分:0)

UIView上的frame属性是不可观察到的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并设置约束以确保边框大小正确。