我正在尝试创建一个水平滑动的segue,它将从一个视图平移到下一个视图。我已经向下平移了,但它显示了一个区域中的黑色空间,它应该显示下一个视图控制器。这就是我实现我的segue
的方式class SlideSegue: UIStoryboardSegue {
enum Direction {
case Left
case Right
}
// MARK: - Properties
var direction = Direction.Left
// MARK: -
override func perform() {
let srcVc = self.sourceViewController
let destVc = self.destinationViewController
let destView = destVc.view.snapshotViewAfterScreenUpdates(true)
var frame = destView.frame
frame.origin.x = CGFloat(valForDirection()) * srcVc.view.frame.width
destView.frame = frame
srcVc.view.addSubview(destView)
UIView.animateWithDuration(0.3, animations: { () -> Void in
let x = CGFloat(self.valForDirection()) * srcVc.view.bounds.width
let slide = CGAffineTransformMakeTranslation(x, 0)
srcVc.view.transform = slide
}) { (finished: Bool) -> Void in
srcVc.presentViewController(destVc, animated: false, completion: nil)
destView.removeFromSuperview()
}
}
func valForDirection() -> Int {
return direction == Direction.Left ? -1 : 1
}
}
class SlideLeftSegue: SlideSegue {
override func perform() {
self.direction = Direction.Left
super.perform()
}
}
class SlideRightSegue: SlideSegue {
override func perform() {
self.direction = Direction.Right
super.perform()
}
}
修改
编辑(已解决) 这是最终的工作解决方案,感谢下面的两个答案
class SlideSegue: UIStoryboardSegue {
enum Direction: Int {
case Left = 1
case Right = -1
}
// MARK: - Properties
var direction = Direction.Left
// MARK: -
override func perform() {
let srcVc = self.sourceViewController
let destVc = self.destinationViewController
let destView = destVc.view.snapshotViewAfterScreenUpdates(true)
var frame = destView.frame
frame.origin.x = CGFloat(direction.rawValue) * srcVc.view.frame.width
destView.frame = frame
srcVc.view.addSubview(destView)
UIView.animateWithDuration(0.3, animations: { () -> Void in
let x = -CGFloat(self.direction.rawValue) * srcVc.view.bounds.width
let slide = CGAffineTransformMakeTranslation(x, 0)
srcVc.view.transform = slide
}) { (finished: Bool) -> Void in
srcVc.presentViewController(destVc, animated: false, completion: nil)
destView.removeFromSuperview()
}
}
}
class SlideLeftSegue: SlideSegue {
override func perform() {
self.direction = Direction.Left
super.perform()
}
}
class SlideRightSegue: SlideSegue {
override func perform() {
self.direction = Direction.Right
super.perform()
}
}
答案 0 :(得分:2)
尝试将您的SlideSegue
课改为此课程,删除valForDirection
功能(如果您不介意的话,我可以自由地重构一下)
class FirstCustomSegue: UIStoryboardSegue {
enum Direction: Int {
case Left = 1
case Right = -1
}
// MARK: - Properties
var direction = Direction.Left
// MARK: - Perform
override func perform() {
let srcVc = self.sourceViewController
let destVc = self.destinationViewController
destVc.view.frame = srcVc.view.frame
destVc.view.frame.origin.x = CGFloat(direction.rawValue) * srcVc.view.frame.width
let window = UIApplication.sharedApplication().keyWindow
window?.insertSubview(destVc.view, aboveSubview: srcVc.view)
UIView.animateWithDuration(0.3, animations: { () -> Void in
let x = CGFloat(self.direction.rawValue) * srcVc.view.bounds.width
destVc.view.frame.origin.x = 0
srcVc.view.frame.origin.x = -x
}) { (finished: Bool) -> Void in
srcVc.presentViewController(destVc, animated: false, completion: nil)
}
}
}
我还没有测试过这个,所以我不能100%确定语法是否正确。
更新:MatthewLuiHK似乎是正确的。你所要做的就是翻转价值观。
答案 1 :(得分:2)
我通过以下修改进行测试,效果很好。
func valForDirection() -> Int {
return direction == Direction.Left ? 1 : -1
}
如果向左滑动,destView的originX应该是它的宽度。 else -width。
答案 2 :(得分:0)
这段代码对我有用,它显示VC下方的新视图控制器被刷掉,但是当segue完成时,视图控制器会短暂地闪烁黑色。
任何想法如何确保每次平稳过渡?
import UIKit
class SlideSegue: UIStoryboardSegue {
enum Direction: Int {
case Left = 1
case Right = -1
}
// MARK: - Properties
var direction = Direction.Left
// MARK: -
override func perform() {
let srcVc = self.sourceViewController
let destVc = self.destinationViewController
let destView = destVc.view.snapshotViewAfterScreenUpdates(true)
var frame = destView.frame
frame.origin.x = CGFloat(direction.rawValue) * srcVc.view.frame.width
destView.frame = frame
srcVc.view.addSubview(destView)
UIView.animateWithDuration(0.3, animations: { () -> Void in
let x = -CGFloat(self.direction.rawValue) * srcVc.view.bounds.width
let slide = CGAffineTransformMakeTranslation(x, 0)
srcVc.view.transform = slide
}) { (finished: Bool) -> Void in
srcVc.presentViewController(destVc, animated: false, completion: nil)
destView.removeFromSuperview()
}
}
}
class SlideLeftSegue: SlideSegue {
override func perform() {
self.direction = Direction.Left
super.perform()
}
}
class SlideRightSegue: SlideSegue {
override func perform() {
self.direction = Direction.Right
super.perform()
}
}
非常感谢