セグエに関する他の投稿を読みましたが、私の質問を解決できるものはありません。
簡単に言えば、私のViewController
sは本のように注文されます。後方へのトランジション(例:ページ9から8)を常に左から右に表示(スライド)したい。順方向遷移(9〜10ページ)を右から左に表示したい。
はい、ページごとにページングする場合、nav-controllerの戻るボタン(左上)はこのように表示されます。ただし、インデックスからジャンプすると、navコントローラの戻る機能によりインデックスに戻ります。
私の目的は、ユーザーがインデックスから(たとえば)ページ9にジャンプしてから右にスワイプすると、ページを右にフリックしてページ8を表示することです。左にフリックすると、再び9ページ目になります。
すべてのViewController
sは、デフォルトでは、右から左にスライドして表示されます。
例:インデックスを使用して第4章に移動し、右にスワイプしてスタックからビューをポップすると、本のように考えると、インデックスに戻ります。しかし、394ページの第4章にいて右にスワイプした場合、インデックスに戻りたくありません! 393ページの第3章の最後のページに移動します!そのため、ナビゲーションスタックは役に立たない。
終了例
詳細:1.ボタンタップの新しいXcode「表示」を使用して、ViewControllerを切り替えます。
左上の「戻る」ボタンの機能に、Navigation Controllerを使用しています。これはnavスタックを使用し、正常に機能します。
ただし、下部に独自のカスタムナビゲーションバー(戻るボタン、ホームボタン、インデックスボタン、進むボタン)とジェスチャーがあります。これらは、本のような機能を持ちたいものです。
Swiftでのコーディング。
Xcode 6.3での作業
アニメーションコードがあることを読みました。私は、使用できるプログラム遷移を詳細に読んだことがあります。左から提示したいセグエを選択して、簡単にアニメーションを反転させる簡単な方法はないのはおかしいようです。
ありがとう!
試行ログ:
I tried DCDC's code:
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
このエラーは、バックスワイプのためにDCDCのコードをIBAction
に挿入すると返されます
これは、nav-controllerを必要とせずに効果を達成する方法です。代わりにこれを試してください:
スウィフト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)
}
)
}
}
スウィフト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)
}
)
}
}
次に、ストーリーボードで、変更するセグエをクリックします。属性インスペクターで、タイプを「Custom」に変更し、クラスを「SegueFromLeft」に変更します
以下は、Swiftで左から右へのセグエを実行するために使用できるカスタムセグエクラスです。 QuartzCoreフレームワークと最小限のアニメーションが必要です。
スイフト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
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)
}
}
「戻る」ボタンは、移行されたView ControllerのNavigation Barに表示されたままですが、そのView ControllerのNavigation Controllerを簡単に無効化/設定できます。
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)
}
)
}
}
承認済み回答Swift 3に更新(2017年6月現在)
セグエからleft to right
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
}
}
}
right to leftからセグエ
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)
}
}
}
TransitionWithViewメソッドで事前宣言されたタイプの遷移を使用できます
UIView.transitionWithView(self.window!, duration: 0.5, options:.TransitionFlipFromLeft, animations: { () -> Void in
self.window!.rootViewController = mainVC
}, completion:nil)
.TransitionFlipFromLeftが望ましいものだと思います
タスクを完了するには、新しいView Controllerをストーリーボードにドラッグし、IDを付けて名前を付けます。これが移行の宛先になります。
次に、コードからこのView Controllerをインスタンス化します
let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let mainVC = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
これは、IBAction内またはViewDidLoadなどで実行できますが、おそらくIBActionの方が適しています。ストーリーボードとView Controllerの両方に正しい識別子を入力するよう注意してください。また、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)
}
これが期待したものでない場合は、おそらくカスタムアニメーションを作成することをお勧めします。この記事は本当に役に立ちます: http://mathewsanders.com/animated-transitions-in-Swift/
デフォルトの戻るボタンのように、UINavigationControllerのスタックからView Controllerをポップしようとしているようです。
次の2つのいずれかを実行できます。最も簡単な方法は、カスタムバックボタンをpopViewControllerAnimated()を呼び出すIBActionに接続することです。
@IBAction func tappedCustomBackButton(sender: AnyObject) {
self.navigationController?.popViewControllerAnimated(true)
}
または、2番目のView Controllerから最初のView Controllerに nwind segue を作成できます。
右からセグエ。以下のようにセグエのperform関数をオーバーライドできます。この関数をカスタムセグエクラス内に配置し、このクラスをセグエに割り当てます。 Navigation Controllerを備えたコントローラーとNavigation Controllerを備えていないコントローラーの両方で機能します
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)
} }
)
}
左からセグエが必要な場合は、これを使用します
CGAffineTransformMakeTranslation(-src.view.frame.size.height, 0)
私の場合、サイドバーメニューを作成していました...
新しいView Controllerと2つの税関セグエを作成しました
メニューを開くには:
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)
}
)
}
}
メニューを閉じるには:
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)
}
)
}
}
お役に立てば幸いです...
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)
})
}
}
これを受け入れられた回答にコピーして、このコメントを削除してください。 (これは単純な更新であり、新しいものはありません。)
やあ、私は完全なソリューションを持っているので、このコードをコピーしてSwiftに貼り付けるだけです。3。
func menu(){
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "MyAccountViewController") as! MyAccountViewController
let transition: CATransition = CATransition()
let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.duration = 0.5
transition.timingFunction = timeFunc
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromLeft
self.navigationController?.view.layer.add(transition, forKey: kCATransition)
self.navigationController?.pushViewController(vc, animated: false)
}
注:ViewControllerの名前を「MyAccountViewController」テキストで変更します。
アニメーションのような「戻るボタン」を作成するには、これを使用します。
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)
}
}