我已经编写了一个自定义区域来获得淡入淡出效果,我试图通过在destination view controller
下面插入source view controller
并为alpha
设置动画来实现这一效果source view controller
为零。
但是,在源下面添加destination view controller
似乎会取消动画,而segue的表现就好像是一个禁用动画的常规present
。
import UIKit
class FadeSegue: UIStoryboardSegue {
override func perform() {
// Get the view of the source
let sourceViewControllerView = self.sourceViewController.view
// Get the view of the destination
let destinationViewControllerView = self.destinationViewController.view
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Make the destination view the size of the screen
destinationViewControllerView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
if let window = UIApplication.sharedApplication().keyWindow {
// Insert destination below the source
// Without this line the animation works but the transition is not smooth as it jumps from white to the new view controller
window.insertSubview(destinationViewControllerView, belowSubview: sourceViewControllerView)
// Animate the fade, remove the destination view on completion and present the full view controller
UIView.animateWithDuration(0.4, animations: {
sourceViewControllerView.alpha = 0.0
}, completion: { (finished) in
destinationViewControllerView.removeFromSuperview()
self.sourceViewController.presentViewController(self.destinationViewController, animated: false, completion: nil)
})
}
}
}
答案 0 :(得分:4)
你好我认为你需要的是这个
override func perform() {
// Get the view of the source
let sourceViewControllerView = self.sourceViewController.view
// Get the view of the destination
let destinationViewControllerView = self.destinationViewController.view
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
// Make the destination view the size of the screen
destinationViewControllerView.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
// Insert destination below the source
// Without this line the animation works but the transition is not smooth as it jumps from white to the new view controller
destinationViewControllerView.alpha = 0;
sourceViewControllerView.addSubview(destinationViewControllerView);
// Animate the fade, remove the destination view on completion and present the full view controller
UIView.animateWithDuration(10, animations: {
destinationViewControllerView.alpha = 1;
}, completion: { (finished) in
destinationViewControllerView.removeFromSuperview()
self.sourceViewController.presentViewController(self.destinationViewController, animated: false, completion: nil)
})
}
}
我希望这能帮到你
答案 1 :(得分:2)
基于@ reinier-melian
的答案,略微修改了Swift 4.1兼容解决方案/// Performs a simple fade between source and destination view controller.
class Fade: UIStoryboardSegue {
override func perform() {
guard let destinationView = self.destination.view else {
// Fallback to no fading
self.source.present(self.destination, animated: false, completion: nil)
return
}
destinationView.alpha = 0
self.source.view?.addSubview(destinationView)
UIView.animate(withDuration: CATransaction.animationDuration(), animations: {
destinationView.alpha = 1
}, completion: { _ in
self.source.present(self.destination, animated: false, completion: nil)
})
}
}
答案 2 :(得分:1)
这就是我最终为了我的目的所做的事情。一旦屏幕上的所有内容都已动画显示并在占位符中淡入淡出,它会将placeholder view
的基本ui元素放在顶部,然后显示destination view controller
并删除placeholder
。 destination view controller
然后在其所有元素中设置动画,实质上使转换不可见,看起来像一个动画:
import UIKit
class FadeSegue: UIStoryboardSegue {
var placeholderView: UIViewController?
override func perform() {
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
if let placeholder = placeholderView {
placeholder.view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
placeholder.view.alpha = 0
sourceViewController.view.addSubview(placeholder.view)
UIView.animateWithDuration(0.4, animations: {
placeholder.view.alpha = 1
}, completion: { (finished) in
self.sourceViewController.presentViewController(self.destinationViewController, animated: false, completion: {
placeholder.view.removeFromSuperview()
})
})
} else {
self.destinationViewController.view.alpha = 0.0
self.sourceViewController.presentViewController(self.destinationViewController, animated: false, completion: {
UIView.animateWithDuration(0.4, animations: {
self.destinationViewController.view.alpha = 1.0
})
})
}
}
}
和放松:
import UIKit
class FadeSegueUnwind: UIStoryboardSegue {
var placeholderView: UIViewController?
override func perform() {
let screenWidth = UIScreen.mainScreen().bounds.size.width
let screenHeight = UIScreen.mainScreen().bounds.size.height
if let placeholder = placeholderView {
placeholder.view.frame = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight)
placeholder.view.alpha = 0
sourceViewController.view.addSubview(placeholder.view)
UIView.animateWithDuration(0.4, animations: {
placeholder.view.alpha = 1
}, completion: { (finished) in
self.sourceViewController.dismissViewControllerAnimated(false, completion: nil)
})
} else {
self.destinationViewController.view.alpha = 0.0
self.sourceViewController.dismissViewControllerAnimated(false, completion: {
UIView.animateWithDuration(0.4, animations: {
self.destinationViewController.view.alpha = 0.0
})
})
}
}
}