Ok快速背景:我正在两个控制器之间进行搜索:我的家庭控制器和一个具有地图视图的控制器。当用户点击搜索栏的textField
时会触发segue我已经包含了动画前后的图像
流程如下:
我将搜索栏添加到let keyWindow = UIApplication.shared.keyWindow
,其位置与表格视图中的位置相同
let preLeadingConstraint = searchView.leadingAnchor.constraint(equalTo: keyWindow.leadingAnchor, constant: 8)
let preTrailingConstraint = searchView.trailingAnchor.constraint(equalTo: keyWindow.trailingAnchor, constant: -8)
let preTopConstraint = searchView.topAnchor.constraint(equalTo: keyWindow.topAnchor, constant: originY)
NSLayoutConstraint.activate([preLeadingConstraint, preTrailingConstraint, preTopConstraint])
keyWindow.layoutIfNeeded()
这里没问题。另外:搜索栏之前已激活高度约束:heightAnchor.constraint(equalToConstant: PlacesSearchView.height).isActive = true
下一步是这个动画(自定义segue):
UIView.animate(withDuration: self.duration, animations: {
homeController.view.frame.origin.x = -Global.width
self.destination.view.frame.origin.x = 0
}) { _ in
homeController.navigationController?.viewControllers.append(self.destination)
self.destination.navigationController?.setNavigationBarHidden(false, animated: true)
}
非常简单,再没问题
这部分是问题:
我停用旧的搜索栏限制:
NSLayoutConstraint.deactivate(preConstraints)
我创建了关闭按钮并将其锚定到keyWindow:
let side: CGFloat = 25
let margin: CGFloat = 8
closeButton?.topAnchor.constraint(equalTo: keyWindow.layoutMarginsGuide.topAnchor, constant: margin).isActive = true
closeButton?.centerXAnchor.constraint(equalTo: keyWindow.centerXAnchor).isActive = true
closeButton?.heightAnchor.constraint(equalToConstant: side).isActive = true
closeButton?.widthAnchor.constraint(equalTo: closeButton!.heightAnchor).isActive = true
然后我将新约束应用于搜索栏。
topAnchor.constraint(equalTo: closeButton!.bottomAnchor, constant: yAxisMargin).isActive = true
leadingAnchor.constraint(equalTo: keyWindow.leadingAnchor, constant: 0).isActive = true
trailingAnchor.constraint(equalTo: keyWindow.trailingAnchor, constant: 0).isActive = true
锚定键盘:
bottomKeyboardConstraint = bottomAnchor.constraint(equalTo: keyWindow.bottomAnchor, constant: -keyboardHeight)
heightConstraint.isActive = false
bottomKeyboardConstraint?.isActive = true
instantiateTableView()
subviewTableView()
然后我当然应用了神奇的公式:
UIView.animate(withDuration: 0.5, animations: {
keyWindow.layoutIfNeeded()
// (I also animate background color)
}
但是!令我惊讶的是......它会跳过动画。直奔最终状态。就像直接到图片2.我试图做(愚蠢)的东西让某种动画进行一次(比如我用这个简化版测试:没有添加也没有停用任何约束,只是尝试将topConstraint.constant更改为0和......同样的事情:搜索栏直接向上,没有任何动画)
我没有得到什么?感谢您对我的回答,我期待您的见解!
更新:出于某种原因,我忘了将最后一个UIView.animate
块放在DispatchQueue.main.async
块中。这样做会导致...有时会有动画而大多数时候都没有动画。这变得越来越奇怪了。另外,在此之前,我从来没有把动画放在DispatchQueue.main.async
块中,即使在其他自定义段中也是如此,这也很奇怪。
答案 0 :(得分:0)
好的我明白了,这就是发生的事情:
基本上...... DispatchQueue.main.async
是问题的根源。让我解释一下。
首先,让我们清楚,我在DispatchQueue.main.async
区块内执行segue:
DispatchQueue.main.async {
self.performSegue(withIdentifier: HomeViewController.storyboardData.segueIdentifiers.places, sender: self)
}
但显然......这还不够。
然后我有了将override func perform()
代码放在DispatchQueue.main.async
内的想法(是的......我知道!)。所以它看起来像这样:
override func perform() {
DispatchQueue.main.async {
...
}
}
而且......每次都是动画!
动画很奇怪所以我基本上决定尝试在块中放置不同部分的代码,直到它工作并且...它最终起作用。 (我承认这样做的一种耻辱)。现在感兴趣的人详情如下:
DispatchQueue.main.async
块中之前有效,所以...我回滚到工作版本现在对于负责动画的部分,如果用户点击了textField:它现在基本上看起来像这样(segueToEditing是我创建closeButton,删除旧约束,添加新约束和动画):
DispatchQueue.main.async { self.segueToEditing() }
我仍然对我的解决方案如何运作感到困惑,但我现在知道我不会混淆DispatchQueue.main.async
块。