注意:我已经检查了以下堆栈溢出问题:
27907570,32229252,26118141,31604300
我想要做的就是在附加到按钮的IBAction调用时在视图中淡化动画(通过alpha)。然后在视图上的按钮被击中时反转。
我的皱纹可能是我在故事板视图中使用ViewDock上的辅助视图。视图在viewDidLoad时被添加到子视图中,其中框架/边界设置为与超视图相同(用于完全中转)
这是作为叠加视图完成的原因,因为它是一个教程指示器。
结果(就像许多其他列出此问题的人一样)是视图(和包含的控件)只是立即出现并立即消失。没有褪色。
我已尝试使用延迟,带有和不带完成,带有转换的animationWithDuration,甚至以旧的UIView.beginAnimations开始。
什么都没有用。建议热烈欢迎。
代码与我能做到的一样直截了当:
修改:将代码扩展到相关的所有内容
Edit2: TL; DR Everything适用于UIViewAnimateWithDuration,它似乎忽略了块和持续时间,只是作为即时UI更改内联运行代码。 解决此问题获得赏金
@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()
}
请注意,我从以下开始:
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
})
}
答案 0 :(得分:38)
如果infoDetailView处于自动布局约束下,则需要在父视图里面调用layoutIfNeeded animateWithDuration:
func showInfoView() {
self.view.layoutIfNeeded() // call it also here to finish pending layout operations
UIView.animateWithDuration(2.0, animations: { () -> Void in
self.infoDetailView.alpha = 0.75
self.view.layoutIfNeeded()
})
}
理论上,如果您只是更改.alpha值,则不需要这样,但可能这可能是这种情况下的问题。
答案 1 :(得分:12)
我可以看到几件奇怪的事情,
首先,删除:
infoDetailView.layoutIfNeeded()
infoDetailView.setNeedsDisplay()
通常您不需要手动调用这些方法,除非您确切知道自己在做什么。
此外,当您更改尺寸时:
infoDetailView.frame = viewRect
infoDetailView.bounds = viewRect
您永远不需要同时设置bounds
和frame
。只需设置frame
。
此外,您应该通过设置确保视图实际上不会忽略该帧:
infoDetailView.translatesAutoresizingMaskIntoConstraints = true
不要重置帧,只需设置自动调整大小掩码:
infoDetailView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
导致:
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() {
...
}
我认为这实际上应该有所帮助,因为即时动画通常与尺寸问题有关。
如果问题仍然存在,您应该检查动画中的infoDetailView
是否与您要添加到控制器的infoDetailView
相同。
答案 2 :(得分:4)
如果动画似乎没有执行,那么在进入动画块之前,请考虑检查每个视图的状态。例如,如果alpha已经设置为0.4,那么调整视图alpha的动画几乎会立即完成,没有明显效果。
请考虑使用关键帧动画。这就是目标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;
}
这是一篇帖子,向您展示如何使用关键帧https://stackoverflow.com/a/18658081/1951992
调整alpha答案 3 :(得分:3)
确保infoDetailView
' s opaque
为假。
此属性为绘图系统提供了如何处理视图的提示。如果设置为true,则绘图系统将视图视为完全不透明,这允许绘图系统优化某些绘图操作并提高性能。如果设置为false,则绘图系统会正常地将视图与其他内容合成。此属性的默认值为true。
答案 4 :(得分:1)
使用此代码:
UIView.animateWithDuration(0.3, animations: { () -> Void in
self.infoDetailView.alpha = 0.0
})
答案 5 :(得分:1)
我已经复制了您的代码并且运行良好,一切正常。 您可能必须控制约束,IBOutlet和IBActions连接。如果有必要,请尝试将此代码隔离到新项目中。
更新:my code 和我的故事板和项目文件夹照片:
每个对象(视图和按钮)都使用默认设置。
我已经评论了所有AFLog专线(可能它只是#34;详细模式"来帮助你),其余的代码都没问题,它做了你所做的事情从中,如果按下打开按钮,视图会淡入,当您点按关闭按钮时,视图会淡出。
PS不相关,但我正在使用xCode 7.3,这是一个新的swift 2.2项目。
答案 6 :(得分:1)
尝试以下代码。只需使用alpha和持续时间来完善它。
隐藏功能
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)
}
显示功能
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)
}
答案 7 :(得分:1)
对于其他希望在加载视图时立即开始播放动画的人...
如果您在UIView.animate(...)
内调用viewDidLoad
,则动画将不起作用。相反,必须从 viewDidAppear
函数中调用它。
override func viewDidAppear(_ animated: Bool) {
UIView.animate(withDuration: 3) {
self.otherView.frame.origin.x += 500
}
}
答案 8 :(得分:0)
您是否尝试将showInfoView()
更改为更像toggleInfoView
的内容?
func toggleInfoView() {
let alpha = CGFloat(infoDetailView.alpha == 0 ? 1 : 0)
infoDetailView.alpha = alpha //this is where the toggle happens
}
它表示如果您的视图的alpha为0,则将其更改为1.否则,将其设为0.
如果你需要在动画中发生这种情况,请尝试
@IBAction func openInfoView(sender: UIButton) {
UIView.animate(withDuration: 2.0, animations: {
self.toggleInfoView() //fade in/out infoDetailView when animating
})
}
infoDetailView.alpha = 0.0
保留在viewDidLoad
的所有位置。答案 9 :(得分:0)
对于UILabel组件,请尝试更改图层的背景颜色。
试试这个(在Swift 4上测试):
Banana
答案 10 :(得分:0)
由于无法执行动画而遇到类似的问题。
以perform(aSelector: Selector, with: Any?, afterDelay: TimeInterval)
的形式更改了使用perform(#selector(functionThatDoesAnimationOfAlphaValue), with: nil, afterDelay: 0)
的函数调用,并且可以正常工作。即使将TimeInterval设置为0。
万一有人来这里寻求解决方案。