ios UIView.animateWithDuration 不动画 Swift(再次)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36436576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UIView.animateWithDuration Not Animating Swift (again)
提问by Dru Freeman
Note: I've already checked the following stack overflow issues:
注意:我已经检查了以下堆栈溢出问题:
27907570, 32229252, 26118141, 31604300
27907570,32229252,26118141,31604300
All I am trying to do is fade animate in a view (by alpha) when called by an IBAction attached to a button. Then reverse when a button on the view is hit.
当被附加到按钮的 IBAction 调用时,我想要做的就是在视图中淡入淡出动画(通过 alpha)。然后在点击视图上的按钮时反转。
My wrinkle may be that I'm using a secondary view that is on the ViewDock in the storyboard View. The view is added to the subview at the time of viewDidLoad where the frame/bounds are set to the same as the superview (for a full layover)
我的问题可能是我正在使用故事板视图中 ViewDock 上的辅助视图。视图在 viewDidLoad 时添加到子视图,其中框架/边界设置为与超级视图相同(对于完整停留)
The reason this is done as an overlay view since it is a tutorial indicator.
这是作为一个覆盖视图完成的原因,因为它是一个教程指示器。
The result (like many others who've listed this problem) is that the view (and contained controls) simply appears instantly and disappears as instantly. No fade.
结果(与列出此问题的许多其他人一样)是视图(和包含的控件)只是立即出现并立即消失。没有褪色。
I have tried animationWithDuration with delay, with and without completion, with transition, and even started with the old UIView.beginAnimations.
我尝试过带延迟、带完成和不带完成、带过渡的 animationWithDuration,甚至从旧的 UIView.beginAnimations 开始。
Nothing is working. Suggestions warmly welcomed.
没有任何工作。热烈欢迎建议。
The code is about as straight forward as I can make it:
Edit:Expanded the code to everything relevant
Edit2:TL;DR Everything works with the exception of UIViewAnimateWithDuration which seems to ignore the block and duration and just run the code inline as an immediate UI change. Solving this gets the bounty
代码与我所能做到的一样直接:
编辑:将代码扩展到所有相关的
Edit2:TL;DR 除了 UIViewAnimateWithDuration 似乎忽略块和持续时间并直接运行内联代码之外,一切都有效界面变化。解决这个问题得到赏金
@IBOutlet var infoDetailView: UIView! // Connected to the view in the SceneDock
override func viewDidLoad() {
super.viewDidLoad()
// Cut other vDL code that isn't relevant
setupInfoView()
}
func setupInfoView() {
infoDetailView.alpha = 0.0
view.addSubview(infoDetailView)
updateInfoViewRect(infoDetailView.superview!.bounds.size)
}
func updateInfoViewRect(size:CGSize) {
let viewRect = CGRect(origin: CGPointZero, size: size)
infoDetailView.frame = viewRect
infoDetailView.bounds = viewRect
infoDetailView.layoutIfNeeded()
infoDetailView.setNeedsDisplay()
}
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
updateInfoViewRect(size)
}
func hideInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.0
},
completion:
{ (finished) in
return true
}
)
AFLog.exit(thisClass)
}
func showInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.75
},
completion:
{ (finished) in
return true
}
)
AFLog.exit(thisClass)
}
// MARK: - IBActions
@IBAction func openInfoView(sender: UIButton) {
showInfoView()
}
@IBAction func closeInfoView(sender: UIButton) {
hideInfoView()
}
Please note, I started with the following:
请注意,我从以下几点开始:
func showInfoView() {
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.75
})
}
func hideInfoView() {
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.00
})
}
回答by Darko
If you infoDetailView is under auto layout constraints you need to call layoutIfNeeded on the parentview insideanimateWithDuration:
如果 infoDetailView 处于自动布局约束下,则需要在animateWithDuration内的父视图上调用 layoutIfNeeded :
func showInfoView() {
self.view.layoutIfNeeded() // call it also here to finish pending layout operations
UIView.animate(withDuration: 2.0, animations: {
self.infoDetailView.alpha = 0.75
self.view.layoutIfNeeded()
})
}
Theoretically this should not be needed if you just change the .alpha value, but maybethis could be the problem in this case.
从理论上讲,如果你只是改变了阿尔法值,但是这应该没有必要,也许这可能是在这种情况下的问题。
回答by Sulthan
There are several strange things I can see,
我可以看到一些奇怪的东西,
first, remove:
首先,删除:
infoDetailView.layoutIfNeeded()
infoDetailView.setNeedsDisplay()
Usually you don't need to call those methods manually unless you know exactly what you are doing.
通常您不需要手动调用这些方法,除非您确切地知道自己在做什么。
Also, when you are changing the size:
此外,当您更改大小时:
infoDetailView.frame = viewRect
infoDetailView.bounds = viewRect
You never need to set both bounds
and frame
. Just set frame
.
您永远不需要同时设置bounds
和frame
。刚设置frame
。
Also, you should probably make sure that the view actually doesn't ignore the frame by setting:
此外,您可能应该通过设置来确保视图实际上不会忽略框架:
infoDetailView.translatesAutoresizingMaskIntoConstraints = true
Instead of resetting the frame, just set autoresize mask:
而不是重置框架,只需设置自动调整大小掩码:
infoDetailView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
Resulting in:
导致:
override func viewDidLoad() {
super.viewDidLoad()
// Cut other vDL code that isn't relevant
setupInfoView()
}
func setupInfoView() {
infoDetailView.alpha = 0.0
infoDetailView.translatesAutoresizingMaskIntoConstraints = true
infoDetailView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
infoDetailView.frame = view.bounds
view.addSubview(infoDetailView)
}
func hideInfoView() {
...
}
I think this should actually help because immediate animations are often connected to size problems.
我认为这实际上应该会有所帮助,因为即时动画通常与尺寸问题有关。
If the problem persists, you should check whether the infoDetailView
in your animation is the same object as the infoDetailView
you are adding to the controller.
如果问题仍然存在,您应该检查infoDetailView
动画中的是否与您infoDetailView
添加到控制器中的对象相同。
回答by Sulthan
If the animation does not seem to execute then consider examining the state of each of your views, before you enter the animation block. For example, if the alpha is already set to 0.4 then the animation that adjusts your view alpha, will complete almost instantly, with no apparent effect.
如果动画似乎没有执行,那么在进入动画块之前,请考虑检查每个视图的状态。例如,如果 alpha 已经设置为 0.4,那么调整视图 alpha 的动画将几乎立即完成,没有明显效果。
Consider using a keyframe animation instead. This is what a shake animation in objective c looks like.
考虑改用关键帧动画。这就是目标 c 中的抖动动画的样子。
+(CAKeyframeAnimation*)shakeAnimation {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
animation.values = @[[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(-10.0, 0.0, 0.0)],
[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(10.0, 0.0, 0.0)]];
animation.autoreverses = YES;
animation.repeatCount = 2;
animation.duration = 0.07;
return animation;
}
Here is a post that shows you how to adjust alpha with keyframes https://stackoverflow.com/a/18658081/1951992
这是一篇文章,向您展示如何使用关键帧调整 alpha https://stackoverflow.com/a/18658081/1951992
回答by spencer.sm
For others looking to start an animation immediately when a view loads...
对于希望在视图加载时立即开始动画的其他人...
The animation won't work if you call UIView.animate(...)
inside viewDidLoad
. Instead it must be called from the viewDidAppear
function.
如果您调用UIView.animate(...)
inside动画将不起作用viewDidLoad
。相反,它必须从viewDidAppear
函数中调用。
override func viewDidAppear(_ animated: Bool) {
UIView.animate(withDuration: 3) {
self.otherView.frame.origin.x += 500
}
}
回答by Jeff
Make sure infoDetailView
's opaque
is false.
确保infoDetailView
'sopaque
是假的。
This property provides a hint to the drawing system as to how it should treat the view. If set to true, the drawing system treats the view as fully opaque, which allows the drawing system to optimize some drawing operations and improve performance. If set to false, the drawing system composites the view normally with other content. The default value of this property is true.
该属性为绘图系统提供了一个关于它应该如何处理视图的提示。如果设置为 true,绘图系统会将视图视为完全不透明,这允许绘图系统优化某些绘图操作并提高性能。如果设置为 false,绘图系统通常会将视图与其他内容合成。此属性的默认值为 true。
回答by Arun Gupta
Try Below code. Just play with alpha and duration time to perfect it.
试试下面的代码。只需使用 alpha 和持续时间来完善它。
Hide func
隐藏功能
func hideInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.8
},
completion:
{ (finished) in
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.4
},
completion:
{ (finished) in
self.infoDetailView.alpha = 0.0
}
)
}
)
AFLog.exit(thisClass)
}
Show func
显示功能
func showInfoView() {
AFLog.enter(thisClass)
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.3
},
completion:
{ (finished) in
UIView.animateWithDuration(
2.0,
animations:
{
self.infoDetailView.alpha = 0.7
},
completion:
{ (finished) in
self.infoDetailView.alpha = 1.0
}
)
}
)
AFLog.exit(thisClass)
}
回答by shikha kochar
Use this code:
使用此代码:
Swift 2
斯威夫特 2
UIView.animateWithDuration(0.3, animations: { () -> Void in
self.infoDetailView.alpha = 0.0
})
Swift 3, 4, 5
斯威夫特 3、4、5
UIView.animate(withDuration: 0.3, animations: { () -> Void in
self.infoDetailView.alpha = 0.0
})
回答by Alessandro Ornano
I've replicated your code and it work well, it's all ok. Probably you must control constraints, IBOutlet and IBActions connections. Try to isolate this code into a new project if it's necessary.
我已经复制了您的代码并且运行良好,一切正常。可能您必须控制约束、IBOutlet 和 IBActions 连接。如有必要,请尝试将此代码隔离到新项目中。
Update: my codeand my storyboard and project folder photo:
更新:我的代码和我的故事板和项目文件夹照片:
Every object (view and buttons) are with default settings.
每个对象(视图和按钮)都具有默认设置。
I've commented all AFLog lines (probably it's only any more "verbose mode" to help you) , the rest of your code is ok and it do what do you aspected from it, if you press open button the view fade in, and when you tap close button the view fade out.
我已经评论了所有 AFLog 行(可能只是更多的“详细模式”可以帮助您),您的其余代码还可以,并且可以执行您从中获得的操作,如果您按下打开按钮,视图会淡入,并且当您点击关闭按钮时,视图会淡出。
PS Not relevant but i'm using xCode 7.3 , a new swift 2.2 project.
PS 不相关,但我使用的是 xCode 7.3,这是一个新的 swift 2.2 项目。
回答by Rudi Wever
Have you tried changing your showInfoView()
to something more like toggleInfoView
?
你有没有试过把你showInfoView()
的改成更像toggleInfoView
?
func toggleInfoView() {
let alpha = CGFloat(infoDetailView.alpha == 0 ? 1 : 0)
infoDetailView.alpha = alpha //this is where the toggle happens
}
It says that if your view's alpha is 0, then change it to 1. Else, make it 0.
它说,如果您的视图的 alpha 为 0,则将其更改为 1。否则,将其设为 0。
If you need that to happen in an animation, try
如果您需要在动画中发生这种情况,请尝试
@IBAction func openInfoView(sender: UIButton) {
UIView.animate(withDuration: 2.0, animations: {
self.toggleInfoView() //fade in/out infoDetailView when animating
})
}
- You'll still want to keep that
infoDetailView.alpha = 0.0
where you have it, coming from theviewDidLoad
.
- 您仍然希望将其保留
infoDetailView.alpha = 0.0
在拥有它的地方,来自viewDidLoad
.
回答by Wanpaya
For UILabel component try to changes layer's background color instead.
对于 UILabel 组件,请尝试更改图层的背景颜色。
Try this (Tested on Swift 4):
试试这个(在 Swift 4 上测试过):
UIView.animate(withDuration: 0.2, animations: {
self.dateLabel.layer.backgroundColor = UIColor.red.cgColor;
})