animationintrinsicContentSize更改

我有一个UIView子类绘制一个圆的半径变化(有很好的弹性animation)。 视图决定了圆的大小。

我想要这个UIView子类改变其框架大小,以匹配animation的变化圆的半径,我想这些变化修改任何NSLayoutConstraints连接到视图(以便限制到圆的边缘视图将移动为圈子大小)。

我明白,实现-(CGSize)intrinsicContentSize和调用invalidateIntrinsicContentSize时,半径变化会告诉限制更新,但我不知道如何animation的变化intrinsicContentSize

从[UIView animateWith …]块中调用invalidateIntrinsicContentSize只是立即更新布局。

这是甚至可能的,是否有一个解决方法/更好的方法?

invalidateIntrinsicContentSize适用于animation和layoutIfNeeded 。 唯一需要考虑的是,更改内在内容大小会使超级视图的布局无效。 所以这应该工作:

 [UIView animateWithDuration:0.2 animations:^{ [self invalidateIntrinsicContentSize]; [self.superview setNeedsLayout]; [self.superview layoutIfNeeded]; }]; 

宽度/高度限制不起作用? 继续参考这个约束和…

 [NSLayoutConstraint constraintWithItem:view attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:myViewInitialWidth]; 

…当你想要animationmyViewresize,做到这一点…

 self.viewWidthConstraint.constant = 100; // new width [UIView animateWithDuration:0.3 animations:^{ [view layoutIfNeeded]; }]; 

…做同样的事情的高度。

取决于你的其他限制,也许你会被迫提出这两个约束的优先级。

或者你可以UIView ,添加- (void)invalidateIntrinsicContentSize:(BOOL)animated并自行伪装。 从- (CGSize)intrinsicContentSize获取新的大小,并通过animation宽度/高度约束来animation。 或者添加属性以启用/禁用animation并覆盖invalidateIntrinsicContentSize ,并在此方法内执行。 很多方法 …

在下面的代码中,内部类是在更改variables时刚刚改变其大小的类。 内部类的animation只使用下面的代码。 如果它影响视图层次结构中较高层的其他对象,则使用setNeedsLayout和layoutIfNeeded的顶层视图replaceself.intrinsic类。

 [UIView animateWithDuration:.2 animations:^{ self.intrinsicClass.numberOfWeeks=8; [self.intrinsicClass setNeedsLayout]; [self.intrinsicClass layoutIfNeeded]; }]; 

这一切都没有为我工作。 我有一个UILabel,我正在设置一个NSAttributedString。 文本是多行,并包装在单词边界。 因此高度是可变的。 我试过这个:

 [UIView animateWithDuration:1.0f animations:^{ self.label = newLabelText; [self.label invalidateIntrinsicContentSize]; [self.view setNeedsLayout]; [self.view layoutIfNeeded]; }]; 

和一些变化。 没有工作。 标签立即改变其大小,然后滑入新的位置。 所以标签位置在屏幕上的animation正在工作。 但标签大小变化的animation不是。

@ stigi的答案的快速版本,为我工作:

 UIView.animate(withDuration: 0.2, animations: { self.invalidateIntrinsicContentSize() self.superview?.setNeedsLayout() self.superview?.layoutIfNeeded() }) 

那么对于Swift 4/3这个作品,我认为这是最好的做法。 如果你有一个带有UILabel的UIView,并且UIView使用UILabel的框架,使用这个:

 self.theUILabel.text = "text update" UIView.animate(withDuration: 5.0, animations: { self.theUIView.layoutIfNeeded() }) 

正常的self.view.layoutIfNeeded()也会在大多数情况下工作。