Cocoa touch 设置intrinsicContentSize更改的动画
我有一个UIView子类,它绘制一个半径变化的圆(带有漂亮的反弹动画)。视图决定了圆的大小 我希望此UIView子类更改其帧大小以匹配对圆半径的动画更改,并希望这些更改修改连接到视图的任何NSLayoutConstraints(以便约束到圆边缘的视图将随着圆的大小调整而移动) 我知道在半径更改时实现Cocoa touch 设置intrinsicContentSize更改的动画,cocoa-touch,uiview,nslayoutconstraint,Cocoa Touch,Uiview,Nslayoutconstraint,我有一个UIView子类,它绘制一个半径变化的圆(带有漂亮的反弹动画)。视图决定了圆的大小 我希望此UIView子类更改其帧大小以匹配对圆半径的动画更改,并希望这些更改修改连接到视图的任何NSLayoutConstraints(以便约束到圆边缘的视图将随着圆的大小调整而移动) 我知道在半径更改时实现-(CGSize)intrinsicContentSize并调用invalidateIntrinsicContentSize将通知约束进行更新,但我不知道如何设置对intrinsicContentSi
-(CGSize)intrinsicContentSize
并调用invalidateIntrinsicContentSize
将通知约束进行更新,但我不知道如何设置对intrinsicContentSize
的更改的动画
从[UIView animateWith…块中调用invalidateIntrinsicContentSize
,即可立即更新布局
这是否可能,是否有解决方法/更好的方法?宽度/高度约束没有帮助?请保留此约束的引用并
[NSLayoutConstraint constraintWithItem:view
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1
constant:myViewInitialWidth];
…如果确实要设置myView大小的动画,请执行以下操作
self.viewWidthConstraint.constant = 100; // new width
[UIView animateWithDuration:0.3 animations:^{ [view layoutIfNeeded]; }];
…对高度做同样的事情
取决于您的其他约束,可能您将被迫提高这两个约束的优先级
或者您可以将
UIView
子类化,添加-(void)invalidateIntrinsicContentSize:(BOOL)animated
,并自己伪造。从-(CGSize)获取新尺寸intrinsicContentSize
并通过设置宽度/高度约束的动画来设置动画。或者添加属性以启用/禁用动画并覆盖invalidateIntrinsicContentSize
,并在该方法内执行此操作。许多方法…在下面的代码中,内在类是在更改va时刚刚更改其大小的类变量。要设置内部类的动画,请仅使用下面的代码。如果它影响视图层次结构中更高级别的其他对象,请使用setNeedsLayout和LayoutIfNeed的顶级视图替换self.infrance类
[UIView animateWithDuration:.2 animations:^{
self.intrinsicClass.numberOfWeeks=8;
[self.intrinsicClass setNeedsLayout];
[self.intrinsicClass layoutIfNeeded];
}];
<代码> SuffiTrimePixCieldCistNosis与动画和<代码> LayuthI需用很好地结合。唯一需要考虑的是,改变内部内容大小使超级视图的布局无效。因此,这应该起作用:
[UIView animateWithDuration:0.2 animations:^{
[self invalidateIntrinsicContentSize];
[self.superview setNeedsLayout];
[self.superview layoutIfNeeded];
}];
所有这些对我都不起作用。我有一个UILabel,我正在使用NSAttributed字符串设置它。文本是多行的,并在单词边界上换行。因此高度是可变的。我尝试过以下方法:
[UIView animateWithDuration:1.0f animations:^{
self.label = newLabelText;
[self.label invalidateIntrinsicContentSize];
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
还有很多变化。都不起作用。标签会立即改变它的大小,然后滑动到它的新位置。因此,屏幕上标签位置的动画可以工作。但是标签大小变化的动画不起作用。Swift版本@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.layoutifneed()文件大部分时间都可以。我感觉这是不可能的。以
UILabel
为例,它的intrinsicContentSize
是字体大小的函数。但是,没有很好的方法来设置字体更改的动画。标签的解决方法是设置其层的变换更改的动画(使用CAAnimation
)然后在动画完成后更改字体-不太好。如果添加行[self.superview setNeedsLayout],则可以正常工作在中间,更新了@Ash的反馈。这对于UIView
s和intrinsicContentSize
insideUIStackView
。为了使堆栈视图在调整大小时具有动画效果,必须在堆栈的父级上调用layoutIfNeeded
,而不是在堆栈本身上。我刚刚被它咬了一口!这可能是评论,因为它不提供答案。