更改UIView的边界原点时约束未更新

时间:2019-06-18 08:00:59

标签: ios uiview autolayout

我有一个UIView A,其中包含另一个UIView B(A的子视图)。还有另一个UIView C(UIView A父级的子视图),并且已应用了一些约束,以使UIView C的顶部锚点与UIView B的底部锚点对齐,UIView C的左侧锚点与UIView的左侧锚点对齐。 B。

现在,当我尝试更改UIView A的边界原点时,会更新UIView B的位置,但不会更改UIView C的位置,从而破坏了原始约束。

我尝试做setNeedsLayout和updateConstraints,但没有任何效果。

当UIView C是UIView A的子级时,它可以正常工作。

如何在更改UIView A的边界原点的同时,将UIView C保持为UIView A的兄弟,并保持约束?

2 个答案:

答案 0 :(得分:0)

首先,您有一个小错误

  

UIView C的左锚与UIView B的左锚对齐。

NSLayoutConstraint *left = [myView.leftAnchor constraintEqualToAnchor:secondView.rightAnchor constant:0];

尝试致电

[self.view layoutIfNeeded];

边界更改后

答案 1 :(得分:0)

您正在尝试将显式框架/边界设置与自动布局约束混合搭配。如您所见,那是行不通的。

运行此行时:

[[recognizer view] setBounds:CGRectMake(100, 100, bounds.size.width, bounds.size.height)];

您正在更改视图的 bounds 。这不会改变任何约束。 (实际上,设置bounds甚至不会更改frame,但这是另一个问题。)

如果要移动视图并维持该视图与其他元素之间的约束,则需要更新该视图上的 约束 ,而不是其边界(或框架)。

因此,您想保留对约束的引用,或者在需要时查找约束,并根据需要更新.constant值。

以下是通过查找CenterX和CenterY约束(而不是保存引用)来更改拍击视图中心的示例:

- (void)handleGesture:(UIGestureRecognizer*)recognizer
{

    // get the view that was tapped
    UIView *tappedView = [recognizer view];

    // get that view's constraints
    NSArray *constraints = [tappedView constraints];

    // we want to find the CenterX constraint
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeCenterX];
    NSArray *filteredArray = [constraints filteredArrayUsingPredicate:predicate];

    // if it doesn't have a CenterX constraint, return
    if(filteredArray.count == 0){
        return;
    }
    NSLayoutConstraint *centerX =  [filteredArray objectAtIndex:0];

    // we want to find the CenterY constraint
    predicate = [NSPredicate predicateWithFormat:@"firstAttribute = %d", NSLayoutAttributeCenterY];
    filteredArray = [constraints filteredArrayUsingPredicate:predicate];

    // if it doesn't have a CenterY constraint, return
    if(filteredArray.count == 0){
        return;
    }
    NSLayoutConstraint *centerY =  [filteredArray objectAtIndex:0];

    // we now have references to the CenterX and CenterY constraints of the tapped view,
    // so we can change the .constant values and the related constraints to the other view will be maintained

    [UIView animateWithDuration:0.15
                     animations:^
     {
         centerX.constant -= 100.0;
         centerY.constant -= 100.0;
     }
                     completion:^(BOOL finished)
     {

     }];

}