我已添加了一个视频链接,其中显示了我遇到的问题:
https://dl.dropboxusercontent.com/u/39330138/Bug_Demo1.mov
有两个视图控制器,第一个是非模糊的,不太重要。单击加号按钮时,应用程序将切换到新控制器(无动画),并在prepareForSegue()
中使用UIGraphicsBeginImageContext
和UIGraphicsGetImageFromCurrentImageContext
从当前视图中捕获UIImage
并将其传递给下一个。
当新视图出现时,我使用UIVisualEffectView
创建模糊视图,并将其作为子视图添加到图像视图中,即背景'。然后,在屏幕上使用UIView
动画和springWithDamping
对2个视图和2个按钮进行动画处理时,其不透明度会生成动画,从而产生视图模糊和顶部项目动画的错觉。 / p>
顶部视图中嵌入了UITextField
,当点按时调用becomeFirstResponder()
并使所有重叠(新会话,标记和按钮)视图包含嵌入在背景中的视觉效果视图Image视图消失。
我进入这么多细节的原因是因为我不确定究竟是什么问题。但是,我怀疑它与Xcode 6中的AutoLayout / Size Classes有关。
有谁知道为什么会发生这种情况以及如何解决这个问题? 如果您需要其他信息,请告诉我们。
谢谢!
编辑:
单击TextField后,当我记录视图时,所有帧看起来都是一样的。
编辑2:
这里是一个演示项目的链接,它将是视频中的所有功能: https://dl.dropboxusercontent.com/u/39330138/DEMO%20APP.zip
答案 0 :(得分:1)
这里发生了一些事情,但主要的罪魁祸首是你使用viewDidLayoutSubviews()
。只要系统必须重新评估布局,就会调用此方法。我看到您在该方法中将UIVisualEffectView
alpha
0
设置为if !returningFromTagView {
blurView.alpha = 0
}
:
alpha
我认为您打算在视图显示之前调用此功能一次,因为我看到您在1
中将viewDidAppear(animated: Bool)
设为动态viewDidLayoutSubviews()
。但是,每当系统因任何原因重新评估布局时,如果alpha
为{{blurView
,则0
会被调用,returningFromTagView
上的false
将返回alpha
1}}。这就是为什么当您召唤键盘(触发布局重新评估)时,此视图会消失。 Xcode还警告您在控制台中创建0
1
(它会破坏视觉效果,直到不透明度返回到viewDidLoad()
)。将上面的代码改为blurView
方法,您将看到alpha
回来。视图加载时,0
只需设置为viewDidLayoutSubviews()
。
其他观点的问题看起来有点困难,但罪魁祸首又是你对keyboardNotfication()
的使用。我想你甚至感到困惑的是,即使在你使用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)
}
方法完成后,布局系统再次被触发,我看到您正在轻视视图'框架在这里和那里:
viewDidLayoutSubviews()
每次进行布局更改时,您都会在屏幕外移动视图!在召唤键盘后使用Xcode 6的全新Capture View Hierarchy功能查看视图层次结构后暂停程序。它在Debug>中查看调试>捕获视图层次结构。这些观点只是隐藏在一边。
为了支持您的过渡动画,我想象您只是在视图出现时尝试执行此操作一次,但无论视图是刚刚出现还是出现像键盘这样的小变化,都会调用它。我建议你以另一种方式实现这些动画,比如使用视图'转换或使用autolayout约束(尽管故事板中有很多缺少的约束)来制作动画。在布局系统完成工作后,updateConstraints()
真的是一个在布局中随处捏造东西的地方。你应该有充分的理由使用它。它有一个很好的功能,可以覆盖你的自动布局约束,并让你在不使用约束的情况下为这些视图设置动画(因为该方法在layoutSubviews()
和viewWillAppear(animated: Bool)
方法之后发生),这就是我们为什么这样做的原因不能将上述代码放在像viewDidLayoutSubviews()
这样的方法中(因为自动布局约束会在布局后对抗动画),但var comingFromSessionView: Bool
只是不是一种方法。支持基本动画。
尽管如此,这里还有一些简单的方法可以让你的应用程序重新开始并让你看看发生了什么:
为NewSessionVC视图控制器创建属性prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
属性。在SessionVC的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)
}
更改为:
Bool
我们会在false
完成viewDidAppear
之后将这些override func viewDidAppear(animated: Bool) {
...
if returningFromTagView {
...
returningFromTagView = false
} else if comingFromSessionView {
...
comingFromSessionView = false
}
}
切换为viewDidLayoutSubviews()
:
viewsDidLayoutSubviews()
现在,当召唤键盘时,您的视图就在您离开它们的位置!
上面的代码并不是很好。我宁愿远离{{1}}做这些动画。但希望你能看到现在正在发生的事情。您的{{1}}一直在窃听您的观点。