Objective-C:动画高度约束更改不起作用
Posted
技术标签:
【中文标题】Objective-C:动画高度约束更改不起作用【英文标题】:Objective-C: animating height constraint change not working 【发布时间】:2018-01-04 08:49:33 【问题描述】:我有两个代码块,一个有效,第二个无效。首先添加一个视图,将其高度限制为 0,然后在动画块中取消此约束,使其长大。完美运行。第二个应该重新激活0 height constraint
,使其高度缩回到0,然后将其删除,但它会立即被删除。代码如下:
self.pickupAddressViewModel.infoViewBlock = ^(MandatoryPickupView * _Nonnull pickupView)
if (weakSelf.mandatoryPickupView)
return;
weakSelf.mandatoryPickupView = pickupView;
[weakSelf.view addSubview:pickupView];
CGFloat gap = weakSelf.orderButton.originY;
[[pickupView.bottomAnchor constraintEqualToAnchor:weakSelf.view.bottomAnchor constant:-gap] setActive:YES];
[[pickupView.leadingAnchor constraintEqualToAnchor:weakSelf.view.leadingAnchor
constant:16.0] setActive:YES];
[[pickupView.trailingAnchor constraintEqualToAnchor:weakSelf.view.trailingAnchor
constant:-16.0] setActive:YES];
weakSelf.mandatoryPickupViewHeight = [pickupView.heightAnchor constraintEqualToConstant:0];
[weakSelf.mandatoryPickupViewHeight setActive:YES];
[weakSelf.view layoutIfNeeded];
[UIView animateWithDuration:0.5 animations:^
[weakSelf.mandatoryPickupViewHeight setActive:NO];
[weakSelf.view layoutIfNeeded];
];
;
self.pickupAddressViewModel.closeViewBlock = ^
if (!weakSelf.mandatoryPickupView)
return;
[weakSelf.view layoutIfNeeded];
[UIView animateWithDuration:10.5
animations:^
[weakSelf.mandatoryPickupViewHeight setActive:YES];
[weakSelf.view layoutIfNeeded];
completion:^(BOOL finished)
[weakSelf.mandatoryPickupView removeFromSuperview];
weakSelf.mandatoryPickupView = nil;
weakSelf.mandatoryPickupViewHeight = nil;
];
;
-
这一切都发生在主线程上。
我尝试将框架的高度设置为 0,但也没有用
weakSelf.mandatoryPickupViewHeight
是一个强大的属性,当我第二次激活时它不是 nil。
有什么建议吗?谢谢!
【问题讨论】:
mandatoryPickupViewHeight
是强属性吗?
是的,第二次激活时不为零
别叫这个[weakSelf.view layoutIfNeeded];
你可以像weakSelf.mandatoryPickupViewHeight.constant = 0
一样调整大小
常量已经设置为0,我只是想重新激活常量。你必须调用 layoutIfNeeded
@MilanNosáľ 我做到了,这是使用遮罩层来圆角。在回答问题之前,我仍在试图弄清楚为什么会发生这种情况。感谢您的帮助
【参考方案1】:
当你对动画使用自动布局时,你可以这样做:
确保自动布局已完成:
self.view.layoutIfNeeded()
然后您在动画块之前更改约束。比如:
someConstraint.constant = 0
然后在更改约束后,告诉自动布局约束已更改:
self.view.setNeedsLayout()
然后您只需调用 layoutIfNeeded()
即可添加一个动画块:
UIView.animate(withDuration: 1, animations:
self.view.layoutIfNeeded()
)
请注意,您没有停用约束 - 它必须始终处于活动状态。
我猜你的代码中的问题就在这里:
[UIView animateWithDuration:0.5 animations:^
[weakSelf.mandatoryPickupViewHeight setActive:NO];
[weakSelf.view layoutIfNeeded];
];
试试改成
[weakSelf.mandatoryPickupViewHeight setActive:NO];
[weakSelf.view setNeedsLayout];
[UIView animateWithDuration:0.5 animations:^
[weakSelf.view layoutIfNeeded];
];
虽然你在做的事情似乎有点晦涩难懂。如果约束被禁用,您确定自动布局有足够的约束来计算正确的高度吗?如果是这样,您确定mandatoryPickupViewHeight
约束与那些没有冲突吗?
【讨论】:
【参考方案2】:这是一种将视图缩小到零高度并使其与子视图一样高的方法。
-(void)manageViewCollapse
if(animationRunning)
return ;
animationRunning = YES;
if(supportShown)
// Hide the view by setting its height constant to zero
NSLayoutConstraint*full=[NSLayoutConstraint constraintWithItem:self.supportView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0.0];
[self.supportView addConstraint:full];
// retrieve the bottom constraint of the view with bottom most item and remove it
for (NSLayoutConstraint*con in self.supportView.constraints)
if (con.firstAttribute == NSLayoutAttributeBottom && con.firstItem == self.bottomItemView)
[self.supportView removeConstraint:con];
break;
[UIView animateWithDuration:0.5 animations:^
[self.view layoutIfNeeded];
completion:^(BOOL finished)
supportShown = NO;
animationRunning = NO ;
];
else
// show the view first by deleting it's zero height
for (NSLayoutConstraint*con in self.supportView.constraints)
if (con.firstAttribute == NSLayoutAttributeHeight)
[self.supportView removeConstraint:con];
break;
// hook the bottom of the view again to the bottom most item to make it have the correct height
NSLayoutConstraint*full1=[NSLayoutConstraint constraintWithItem:self.bottomItemView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.supportView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-15.0];
full1.priority = UILayoutPriorityDefaultHigh;
[self.supportView addConstraint:full1];
[UIView animateWithDuration:0.5 animations:^
[self.view layoutIfNeeded];
completion:^(BOOL finished)
supportShown = YES;
animationRunning = NO;
];
【讨论】:
奇怪,它第一次工作。重点是我希望通过内部约束来计算高度 也忘记活动/非活动方法以上是关于Objective-C:动画高度约束更改不起作用的主要内容,如果未能解决你的问题,请参考以下文章