iOS 转场 - 从左到右 -
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30763519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS Segue - Left to Right -
提问by Dave G
I've read the other posts on segues but none solve my question.
我已经阅读了关于 segue 的其他帖子,但没有一个能解决我的问题。
Simply put, my ViewController
s are ordered, like a book. I want backward transitions (example: from page 9 to 8) to always present (slide over) from left to right. I want forward transitions (from page 9 to 10) to present from right to left.
简单地说,我的ViewController
s是有序的,就像一本书。我希望向后过渡(例如:从第 9 页到第 8 页)始终从左到右呈现(滑过)。我希望向前过渡(从第 9 页到第 10 页)从右到左呈现。
Yes, my nav-controller back button (top left) presents like this if you are paging through page by page. However, if you jump in from an Index then the back function on the nav controller takes you back to the index.
是的,如果您逐页翻阅,我的导航控制器后退按钮(左上角)会显示这样。但是,如果您从索引跳转,则导航控制器上的返回功能会将您带回索引。
My objective is that if a user jumps to page 9 (for example) from an index, then swipes right, it'll flick the page off to the right and show page 8. Once on page 8, if they flick left the page will get flicked off to the left and they'll be on page 9 again.
我的目标是,如果用户从索引跳转到第 9 页(例如),然后向右滑动,它会将页面向右滑动并显示第 8 页。一旦在第 8 页上,如果他们向左滑动,页面将向左轻弹,它们将再次出现在第 9 页。
All my ViewController
s are by, default, presenting by sliding in from right to left.
ViewController
默认情况下,我的所有s 都是通过从右向左滑动来呈现的。
Example: Think of it like a book, if I use the Index to hop to chapter 4, then swipe right and pop a view from the stack, I'll be back at the Index. But if you're on Chapter 4, page 394 and you swipe right, you don't want to go back to the index! You want to go to the last page of chapter 3, page 393! So the nav stack is no help to me.
示例:把它想象成一本书,如果我使用索引跳到第 4 章,然后向右滑动并从堆栈中弹出一个视图,我将回到索引处。但是,如果您在第 4 章第 394 页上向右滑动,您就不想返回索引!你要翻到第3章的最后一页,第393页!所以导航堆栈对我没有帮助。
End Example
结束示例
Details: 1. I'm using the new Xcode "Show" on button-tap to switch between ViewControllers.
详细信息: 1. 我正在使用新的 Xcode“显示”按钮点击在 ViewControllers 之间切换。
I'm using a navigation controller, for the top-left "Back" button functionality. This uses the nav stack and works fine.
However I have my own custom nav-bar at the bottom (Back Button, Home Button, Index Button, Forward Button) and gestures. These are what I want to have book-like functionality with.
Coding in swift.
Working with Xcode 6.3
我正在使用导航控制器,用于左上角的“后退”按钮功能。这使用导航堆栈并且工作正常。
但是,我在底部有自己的自定义导航栏(后退按钮、主页按钮、索引按钮、前进按钮)和手势。这些就是我想要的书本功能。
快速编码。
使用 Xcode 6.3
I've read that there's animation code. I've read there's in depth programatic transitions that can be used. It just seems crazy that there's no simple way to just select the segues I want to present from the left and easily reverse the animation.
我读过有动画代码。我已经阅读了可以使用的深度编程转换。没有简单的方法可以从左侧选择我想要呈现的转场并轻松反转动画,这似乎很疯狂。
Thanks!
谢谢!
Attempt log:
尝试日志:
I tried DCDC's code:
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
This error is returned when I insert DCDC's code into an IBAction
for my back-swipe
当我将 DCDC 的代码插入到IBAction
我的向后滑动时,会返回此错误
回答by Michael Hudson
This is how I achieve the effect without requiring a nav-controller. Try this instead:
这就是我在不需要导航控制器的情况下实现效果的方式。试试这个:
Swift 4:
斯威夫特 4:
import UIKit
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src = self.source
let dst = self.destination
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: .curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
}
)
}
}
Swift 3:
斯威夫特 3:
import UIKit
class SegueFromLeft: UIStoryboardSegue
{
override func perform()
{
let src = self.sourceViewController
let dst = self.destinationViewController
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransformMakeTranslation(-src.view.frame.size.width, 0)
UIView.animateWithDuration(0.25,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
dst.view.transform = CGAffineTransformMakeTranslation(0, 0)
},
completion: { finished in
src.presentViewController(dst, animated: false, completion: nil)
}
)
}
}
Then in the storyboard, click on the segue you'd like to change. In the attributes inspector change the type to 'Custom' and change the class to 'SegueFromLeft'
然后在情节提要中,单击要更改的转场。在属性检查器中将类型更改为“自定义”并将类更改为“SegueFromLeft”
回答by rambossa
Here is a custom-segue class you can use to perform a left-to-right segue in Swift. It requires QuartzCore framework and minimal animation.
这是一个自定义转场类,可用于在 Swift 中执行从左到右的转场。它需要 QuartzCore 框架和最少的动画。
Swift 2.2
斯威夫特 2.2
import UIKit
import QuartzCore
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src: UIViewController = self.sourceViewController
let dst: UIViewController = self.destinationViewController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.25
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
src.navigationController!.view.layer.addAnimation(transition, forKey: kCATransition)
src.navigationController!.pushViewController(dst, animated: false)
}
}
Swift 3.0
斯威夫特 3.0
import UIKit
import QuartzCore
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src: UIViewController = self.source
let dst: UIViewController = self.destination
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.25
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
src.navigationController!.view.layer.add(transition, forKey: kCATransition)
src.navigationController!.pushViewController(dst, animated: false)
}
}
The "Back" button will still appear in the navigation bar on the transitioned view controller, but you can easily disable/configure the navigation controller for that view controller.
“返回”按钮仍将出现在转换后的视图控制器的导航栏中,但您可以轻松禁用/配置该视图控制器的导航控制器。
回答by Mark Barrasso
Updated accepted answer in Swift 3:
更新了 Swift 3 中接受的答案:
import UIKit
class SegueFromLeft: UIStoryboardSegue
{
override func perform()
{
let src = self.source
let dst = self.destination
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
}
)
}
}
回答by AnBisw
Accepted answerupdated for Swift 3(as of Jun 2017)
已为Swift 3更新的已接受答案(截至 2017 年 6 月)
Segue from left to right
Segue公司自左到右
import UIKit
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src = self.source //new enum
let dst = self.destination //new enum
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0) //Method call changed
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil) //Method call changed
}
}
}
Segue from right to left
Segue公司自右至左
import UIKit
class SegueFromRight: UIStoryboardSegue {
override func perform() {
let src = self.source
let dst = self.destination
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: src.view.frame.size.width*2, y: 0) //Double the X-Axis
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil)
}
}
}
回答by theDC
You can use of the predeclared type of transition in transitionWithView method
您可以在 transitionWithView 方法中使用预先声明的过渡类型
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
I guess .TransitionFlipFromLeft is the desired one
我猜 .TransitionFlipFromLeft 是想要的
To complete the task, drag a new view controller to your storyboard and name it with some id. This is going to be the destination of the transition.
要完成任务,请将一个新的视图控制器拖到您的故事板中,并用一些 id 命名它。这将是过渡的目的地。
then instantiate this view controller from code
然后从代码实例化这个视图控制器
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
You can do this either inside the IBAction or for example in ViewDidLoad but probably IBAction will be the better choice. Pay attention to type the correct identifiers for both storyboard and view controller. Also, you have to declare your appDelegate instance. Here is the implemented IBAction
您可以在 IBAction 内部或例如在 ViewDidLoad 中执行此操作,但 IBAction 可能是更好的选择。注意为故事板和视图控制器输入正确的标识符。此外,您必须声明您的 appDelegate 实例。这是实现的 IBAction
@IBAction func push(sender: UIButton) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("secondVC") as! UIViewController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
UIView.transitionWithView(appDelegate.window!, duration: 0.5, options: .TransitionFlipFromLeft , animations: { () -> Void in
appDelegate.window!.rootViewController = mainVC
}, completion:nil)
}
If this is not what you have expected, probably you might want to make a custom animation. This article is really helpful : http://mathewsanders.com/animated-transitions-in-swift/
如果这不是您所期望的,您可能想要制作自定义动画。这篇文章真的很有帮助:http: //mathewsanders.com/animated-transitions-in-swift/
回答by Richard Venable
It sounds like you are just trying to pop a view controller off the UINavigationController's stack, just like the default back button would.
听起来您只是想从 UINavigationController 的堆栈中弹出一个视图控制器,就像默认的后退按钮一样。
You can do one of two things. The easiest is to connect your custom back button to an IBAction that calls popViewControllerAnimated():
你可以做两件事之一。最简单的方法是将自定义后退按钮连接到调用 popViewControllerAnimated() 的 IBAction:
@IBAction func tappedCustomBackButton(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
Or you can create an unwind seguefrom your second view controller back to your first.
或者你可以创建一个从你的第二个视图控制器回到你的第一个视图控制器的unwind segue。
回答by Ashwin Felix
Segue from right.You can override the perform function in segue like below. put this function inside a custom segue class and assign this class to the segue. it will work for both controllers with navigation controller and without navigation controller
Segue 从右边开始。您可以像下面这样覆盖 segue 中的执行功能。将此函数放在自定义 segue 类中,并将此类分配给 segue。它适用于带导航控制器和不带导航控制器的控制器
override func perform()
{
let src = self.sourceViewController
print(src)
let dst = self.destinationViewController
print(dst)
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransformMakeTranslation(src.view.frame.size.height, 0)
UIView.animateWithDuration(0.35,
delay: 0.0,
options: UIViewAnimationOptions.CurveEaseInOut,
animations: {
dst.view.transform = CGAffineTransformMakeTranslation(0, 0)
},
completion: { finished in
if let navController = src.navigationController {
navController.pushViewController(dst, animated: false)
} else {
src.presentViewController(dst, animated: false, completion: nil)
} }
)
}
if you want the segue from left then use this
如果你想从左边开始转场,那么使用这个
CGAffineTransformMakeTranslation(-src.view.frame.size.height, 0)
回答by Thialyson Martins
In my case I used to make a sidebar menu...
就我而言,我曾经制作侧边栏菜单...
I created a new view controller and two customs segues
我创建了一个新的视图控制器和两个自定义 segue
TO OPEN THE MENU:
打开菜单:
import Foundation
import UIKit
class SegueFromLeft: UIStoryboardSegue {
override func perform() {
let src = self.source as UIViewController
let dst = self.destination as UIViewController
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
}
)
}
}
TO CLOSE THE MENU:
关闭菜单:
import Foundation
import UIKit
class SegueFromRight: UIStoryboardSegue {
override func perform() {
let src = self.source as UIViewController
let dst = self.destination as UIViewController
src.view.superview?.insertSubview(dst.view, belowSubview: src.view)
src.view.transform = CGAffineTransform(translationX: 0, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
src.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
},
completion: { finished in
src.dismiss(animated: false, completion: nil)
}
)
}
}
I hope it helped you...
我希望它对你有帮助...
回答by aestusLabs
Updated the accepted answer to Swift 4:
将接受的答案更新为 Swift 4:
class SegueFromLeft: UIStoryboardSegue
{
override func perform(){
let src = self.source
let dst = self.destination
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width, y: 0)
UIView.animate(withDuration: 0.25,
delay: 0.0,
options: UIViewAnimationOptions.curveEaseInOut,
animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
},
completion: { finished in
src.present(dst, animated: false, completion: nil)
})
}
}
Feel free to copy this into the accepted answer and delete this comment. (It's a straight update, nothing new.)
随意将其复制到已接受的答案中并删除此评论。(这是一个直接的更新,没什么新鲜的。)
回答by Felecia Genet
To create a "back button" like animation, use this.
要创建类似动画的“后退按钮”,请使用它。
class SegueRightToLeft: UIStoryboardSegue {
override func perform() {
let src = self.source //new enum
let dst = self.destination //new enum
src.view.superview?.insertSubview(dst.view, aboveSubview: src.view)
dst.view.transform = CGAffineTransform(translationX: -src.view.frame.size.width/2, y: 0)
//slice the x axis translation in half
UIView.animate(withDuration: 0.25, delay: 0.0, options: UIViewAnimationOptions.curveEaseInOut, animations: {
dst.view.transform = CGAffineTransform(translationX: 0, y: 0)
}) { (finished) in
src.present(dst, animated: false, completion: nil)
}
}