我正在做我的第一个自定义segue动画。我想要的是一个列表视图,当我选择一行时,它不是从侧面滑入,而是从所选行扩展到位。类似的东西:
因此用户选择绿色行,这会导致新控制器以绿色行大小开始并展开以填充屏幕。到目前为止,这部分工作正常。
我遇到的问题是解开segue,试图做相反的事情,将整个屏幕缩回原来的行,然后解散。它会变得很好,但是暴露的区域仍然是黑色,然后在动画完成时突然闪烁到位。想要的东西是这样的:
但正在发生的事情更像是这样:
我用于展开perform
的代码如下:
class FromScheduleFocusSegue: UIStoryboardSegue {
override func perform() {
let fromView = self.source.view!
let toView = self.destination.view!
let window = UIApplication.shared.keyWindow!
let schedulesList = self.destination as! SchedulesListController
let cell = schedulesList.tableView.cellForRow(at: schedulesList.tableView.indexPathForSelectedRow!)!
var stripe = cell.bounds
stripe.size.height = 60
let targetFrame = cell.convert(stripe, to: window).insetBy(dx: 0, dy: 0)
schedulesList.tableView.selectRow(at: nil, animated: false, scrollPosition: .none)
UIView.animateWithDuration(4000.milliseconds, delay: 0.seconds, options: .curveEaseInOut, animations: {
fromView.frame = targetFrame
}) { (finished) in
self.source.dismiss(animated: false, completion: nil)
}
}
}
所以基本上,当动画发生时,我如何得到我正在展开的视图?
为了完整起见,这里是前向segue代码:
class ToScheduleFocusSegue: UIStoryboardSegue {
override func perform() {
let fromView = self.source.view!
let toView = self.destination.view!
let window = UIApplication.shared.keyWindow!
let box = UIScreen.main.bounds
let schedulesList = self.source as! SchedulesListController
let cell = schedulesList.tableView.cellForRow(at: schedulesList.tableView.indexPathForSelectedRow!)!
toView.frame = cell.convert(cell.bounds, to: window).insetBy(dx: 0, dy: 0)
window.insertSubview(toView, aboveSubview: fromView)
UIView.animateWithDuration(4000.milliseconds, delay: 0.seconds, options: .curveEaseInOut, animations: {
toView.frame = box
}) { (finished) in
self.source.present(self.destination, animated: false, completion: nil)
}
}
}
(这是在XCode8中,使用Swift3针对iOS10)
答案 0 :(得分:0)
尝试让执行演示的视图控制器也执行解散。
所以在你的解开赛中:
UIView.animateWithDuration(4000.milliseconds, delay: 0.seconds, options: .curveEaseInOut, animations: {
fromView.frame = targetFrame
}) { (finished) in
self.destination.dismiss(animated: false, completion: nil) // the destination is the one that presented the current view
}