掩盖UIView和自动布局

时间:2015-01-28 02:07:27

标签: ios objective-c uiview autolayout

我有一个UIView,我想用另一个UIView掩盖,从中心打出一个洞。这是我的viewDidLoad

- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.viewToMask];
[self.view addSubview:self.theMask];

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.viewToMask attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.viewToMask attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[cyan(200)]" options:0 metrics:nil views:@{@"cyan": self.viewToMask}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[cyan(200)]" options:0 metrics:nil views:@{@"cyan": self.viewToMask}]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.theMask attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.viewToMask attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0]];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.theMask attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewToMask attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[mask(100)]" options:0 metrics:nil views:@{@"mask": self.theMask}]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[mask(100)]" options:0 metrics:nil views:@{@"mask": self.theMask}]];
}

它给了我我正在寻找的东西,减去了掩蔽:

views without masking

如果我再添加一行:

[self.viewToMask setMaskView:self.theMask];

两个视图都消失了---小视图(self.theMask)屏蔽了整个较大的视图(self.viewToMask),即使它只有一半大小。有谁知道这里发生了什么?您是否可以将UIView.maskView与自动布局一起使用?

3 个答案:

答案 0 :(得分:5)

正如Zev所解释的,掩码视图位于普通视图层次结构之外,因此无法与自动布局一起使用。我通过将其手动放入我的视图控制器viewDidLayoutSubviews

来解决这个问题
-(void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    CGRect viewToMaskRect = self.viewToMask.bounds;
    CGRect maskRect = CGRectMake(viewToMaskRect.origin.x + 50.0, viewToMaskRect.origin.y + 50.0, 100.0, 100.0);
    [self.theMask setFrame:maskRect];
    [self.viewToMask setMaskView:self.theMask];
}

proper masking

答案 1 :(得分:2)

根据Russ'回答,我做了自己的研究并得到了另一种解决方法。

下面的代码示例将使用10pt屏蔽主视图的左侧和右侧。重要

class SomeViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()

        self.view.backgroundColor = UIColor.whiteColor()

        self.setupMaskView()
    }

    private func setupMaskView() {

        let maskView = UIView()
        maskView.translatesAutoresizingMaskIntoConstraints = false
        maskView.backgroundColor = UIColor(white: 0.0, alpha: 1.0)

        let maskContainerView = UIView()
        maskContainerView.addSubview(maskView)

        self.view.addSubview(maskContainerView)

        maskView.leftAnchor.constraintEqualToAnchor(self.view.leftAnchor, constant: 10).active = true
        maskView.widthAnchor.constraintEqualToAnchor(self.view.widthAnchor, constant: -20).active = true
        maskView.heightAnchor.constraintEqualToAnchor(self.view.heightAnchor).active = true

        self.view.maskView = maskContainerView // this will not work it we place this line above the constraint code !!!
        /* I have no idea why this does not work and why nesting is required, maybe some sort of bug? */
    }
}

此代码使用iOS 9.0和Swift 2.0提供的AutoLayout语法。 (用Xcode 7 beta 4编写)

答案 2 :(得分:0)

通过使maskView只是一个普通的子视图(例如,在具有相关约束的故事板中),然后在viewWillLayoutSubviews中将其设置为maskView,可以使用maskView进行自动布局。即:

-(void)viewWillLayoutSubviews {
    [super viewWillLayoutSubviews];

    self.viewToBeMasked.maskView = self.maskViewWithLayoutConstraints;
}