有几件事情在这里发生,但主要的罪魁祸首是你的viewDidLayoutSubviews()
使用。这被称为任何时候系统必须重新评估布局。我看到你设置你的UIVisualEffectView
的alpha
到0
该方法:
if !returningFromTagView {
blurView.alpha = 0
}
我想你打算这个被称为只出现一次的观点之前,因为我看到你在动画alpha
到1
viewDidAppear(animated: Bool)
。但是,任何时候系统因任何原因重新评估布局,viewDidLayoutSubviews()
被调用,并且在blurView
将返回0
,如果returningFromTagView
是false
。这就是为什么当你召唤键盘(触发布局的重新评估),该视图中消失。 Xcode中还会发出警告,在控制台使alpha
0
(直到不透明返回1
它打破了视觉效果)。把上面的代码中viewDidLoad()
方法来代替,你会看到blurView
回来。该alpha
只需要设置为0
视图一次加载时。
与其他视图的问题有点难以看清,但罪魁祸首再次是您使用viewDidLayoutSubviews()
。我想你很疑惑,为什么在你的方法设置好框架,把视图放到前面,确保它们没有被隐藏之后,你已经非常详细地了解了这些视图,然后记录下来所有。但keyboardNotification()
方法完成后,再次布局系统被触发了,我看到你在这里,有轻推意见框架:
if returningFromTagView {
setX(-titleView.frame.size.width, v: titleView)
setX(-tagView.frame.size.width, v: tagView)
setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton)
setX(-nextButton.frame.size.width, v: nextButton)
} else {
setX(-titleView.frame.size.width, v: titleView)
setX(view.frame.size.width, v: tagView)
setX(-cancelButton.frame.size.width, v: cancelButton)
setX(view.frame.size.width, v: nextButton)
}
你正在移动的观点离屏幕每一次布局变化被制造!在召唤键盘并使用Xcode 6卓越的新Capture View层次结构能力查看视图层次结构后暂停程序。它在Debug> View Debugging> Capture View Hierarchy中。这些意见只是隐藏在一边。
我只是在视图出现时尝试这样做,以支持过渡动画,但会调用视图是否刚刚出现或者是否出现类似键盘的小改变。我建议你以另一种方式实现这些动画,例如使用视图的变换或使用自动布局约束(尽管故事板中有很多缺失的约束)来执行动画。 viewDidLayoutSubviews()
是布局系统完成其工作之后,在布局中进行各种操作的地方。你应该有一个很好的使用它的理由。它具有覆盖你的自动布局的限制,让你制作动画的看法,并没有与约束玩弄(因为该方法发生在updateConstraints()
和layoutSubviews()
方法后)的不错的功能,这就是为什么我们不能把上面的代码中像viewWillAppear(animated: Bool)
的方法相反(因为自动布局约束会在布局结束后对抗动画),但viewDidLayoutSubviews()
只是不是一种旨在支持基本动画的方法。
尽管如此,这里有一些简单的事情让你的应用程序再次发生,并让你看看发生了什么: 为您的NewSessionVC视图控制器创建一个属性var comingFromSessionView: Bool
属性。在SessionVC的prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
,加nextVC.comingFromSessionView = true
然后代码块从viewDidLayoutSubviews()
改变上述这样的:
if returningFromTagView {
setX(-titleView.frame.size.width, v: titleView)
setX(-tagView.frame.size.width, v: tagView)
setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton)
setX(-nextButton.frame.size.width, v: nextButton)
} else if comingFromSessionView {
setX(-titleView.frame.size.width, v: titleView)
setX(view.frame.size.width, v: tagView)
setX(-cancelButton.frame.size.width, v: cancelButton)
setX(view.frame.size.width, v: nextButton)
}
我们将在viewDidAppear
切换这些Bool
s到false
它与它们完成后:
override func viewDidAppear(animated: Bool) {
...
if returningFromTagView {
...
returningFromTagView = false
} else if comingFromSessionView {
...
comingFromSessionView = false
}
}
现在,当键盘被召唤时,你的意见是正确的,你离开他们!
上面的代码并不好。我宁愿远离viewDidLayoutSubviews()
做这些动画。但希望你能看到现在发生了什么。你的viewsDidLayoutSubviews()
一直在搅乱你的观点。
如果有人认为这个问题太困难或需要详细得多的信息,我会很乐意给他们的项目文件鼓捣。 – nanothread59
你可以请附上演示项目吗? –
@LeoNatan当然,给我一分钟...... – nanothread59