UIView遮罩导致视图移动位置(自动版式)

时间:2018-12-11 01:27:26

标签: swift uiview autolayout

在我的应用中,我有一个 UILabel ,我正在使用它掩盖 UIView 。我在整个应用程序中都使用了AutoLayout,并且发现在设置标签的遮罩时,其位置会突然改变。

这是添加标签时的代码;

// Label
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "Hello!"
label.font = UIFont.systemFont(ofSize: 50.0)
label.textColor = UIColor.white
view.addSubview(label)

// Constraints
label.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
label.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true

这将产生expected结果。但是,在添加遮罩时,请通过以下代码;

// Mask
let mask = UIView()
mask.translatesAutoresizingMaskIntoConstraints = false
mask.backgroundColor = UIColor.blue
mask.mask = label
view.addSubview(mask)

// Constraints
mask.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
mask.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
mask.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
mask.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true

我的标签最终重新定位,我正在寻求使文本保持在理想中心的位置。

enter image description here

1 个答案:

答案 0 :(得分:0)

您不能在用作遮罩的视图上使用“自动布局”。该视图位于普通视图层次结构之外。您不会通过调用addSubview(_:)将其添加到视图层次结构中,而只是通过将其设置为另一个视图的mask属性来将其添加为蒙版。

因此,您必须直接设置标签的框架以使标签居中。每当蒙版视图的框架更改时(例如,如果用户旋转设备),还必须重新设置一次。因此,您必须在viewDidLayoutSubviews()

中设置标签的框架

我试图通过仅将标签的中心设置为视图的中心来使其工作,但这不起作用。标签以某种方式不会显示。我可以通过将标签大小显式设置为其intrinsicContentSize来使其工作。我猜这是因为标签被用作蒙版,而不是视图层次结构的一部分。

这是一个可行的示例。我随意将命名从mask更改为maskedView,以避免与mask属性混淆;-)

class ViewController: UIViewController {

    var label = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .green

        // Label
        label.text = "Hello!"
        label.font = UIFont.systemFont(ofSize: 50.0)
        label.textColor = UIColor.white

        // Mask
        let maskedView = UIView()
        maskedView.translatesAutoresizingMaskIntoConstraints = false
        maskedView.backgroundColor = UIColor.blue
        maskedView.mask = label
        view.addSubview(maskedView)

        // Constraints
        maskedView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
        maskedView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        maskedView.widthAnchor.constraint(equalTo: self.view.widthAnchor).isActive = true
        maskedView.heightAnchor.constraint(equalTo: self.view.heightAnchor).isActive = true
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        let labelHeight = label.intrinsicContentSize.height
        let labelWidth = label.intrinsicContentSize.width
        label.frame = CGRect(
            x: view.center.x - labelWidth / 2,
            y: view.center.y - labelHeight / 2,
            width: labelWidth,
            height: labelHeight
        )
    }
}

您可以通过设置viewDidLayoutSubviews()

来缩短label.textAlignment = .center中的代码

那么这就足够了:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    label.frame = view.frame
}