我有一个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的兄弟,并保持约束?
答案 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)
{
}];
}