2015-01-01 117 views
4

我已经包括了一个链接,显示我有什么问题视频:如何解决消失意见当键盘出现在Xcode 6?

https://dl.dropboxusercontent.com/u/39330138/Bug_Demo1.mov

有两个视图控制器,第一是不模糊的,不那么重要了。当点击了加号按钮,该应用塞格斯到一个新的控制器(无动画)和prepareForSegue()我使用UIGraphicsBeginImageContextUIGraphicsGetImageFromCurrentImageContext从当前视图捕获UIImage并将其传递到下一个。

当新视图出现我用UIVisualEffectView创建一个模糊视图,并将其添加为子视图图像认为是“背景”。然后,在其不透明度的同时在2次和2个按钮的动画在屏幕上与UIView动画和动画springWithDamping,赋予视图模糊以上和物品动画过顶的错觉。

顶视图有一个UITextField嵌在它其中,窃听电话becomeFirstResponder()时,作出了覆盖(新建会话,标签&按钮),包括视觉效果观的背景图片浏览嵌入消失的看法。

我之所以进入这么多的细节是,因为我不知道到底是什么问题。不过,我怀疑它是与Xcode 6中的AutoLayout/Size Classes有关。

有没有人知道为什么会发生这种情况,以及如何解决它? 如果你需要更多的信息,只是让我知道。

谢谢!

编辑:

当我登录的意见后,我点击文本字段,所有的帧似乎是相同的。

编辑2:

下面是一个示范项目的链接将全部从视频功能: https://dl.dropboxusercontent.com/u/39330138/DEMO%20APP.zip

+0

如果有人认为这个问题太困难或需要详细得多的信息,我会很乐意给他们的项目文件鼓捣。 – nanothread59

+0

你可以请附上演示项目吗? –

+0

@LeoNatan当然,给我一分钟...... – nanothread59

回答

1

有几件事情在这里发生,但主要的罪魁祸首是你的viewDidLayoutSubviews()使用。这被称为任何时候系统必须重新评估布局。我看到你设置你的UIVisualEffectViewalpha0该方法:

if !returningFromTagView { 
    blurView.alpha = 0 
} 

我想你打算这个被称为只出现一次的观点之前,因为我看到你在动画alpha1viewDidAppear(animated: Bool)。但是,任何时候系统因任何原因重新评估布局,viewDidLayoutSubviews()被调用,并且在blurView将返回0,如果returningFromTagViewfalse。这就是为什么当你召唤键盘(触发布局的重新评估),该视图中消失。 Xcode中还会发出警告,在控制台使alpha0(直到不透明返回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()一直在搅乱你的观点。

+0

非常感谢,这真是一个非常棒的答案。我不知道,'viewDidLayoutSubviews()'调用时键盘的出现,以及(虽然现在我想想很有道理)。完美解决了我的问题! – nanothread59

+0

我upvoted,接受,并会在6小时内奖励赏金(我有授予之前需要等待至少1天) – nanothread59