[英]Perform push segue after an unwind segue
我正在開發一個相機應用程序,其中相機視圖以模態顯示。 在我完成裁剪之后。 我對MainPageViewController
執行 unwind segue 。 (請看截圖)
我在MainPageViewController
unwind 函數如下;
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
self.performSegueWithIdentifier("Categories", sender: self)
}
其中“categories”是從MainPageViewController
到CategoriesTableViewController
的推送序列標識符。
程序進入unwindToMainMenu
函數,但不執行 push segue。 知道如何解決這個問題嗎?
注意:我發現了同樣的問題,但答案建議更改故事板結構。
聚會有點晚了,但我找到了一種不使用州旗的方法
注意:這僅適用於 iOS 9+,因為只有自定義轉場支持 iOS9 之前的類名,並且您不能在故事板中將退出轉場聲明為自定義轉場
class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?
override func perform() {
super.perform()
if let completion = completion {
completion()
}
}
}
注意:此 segue 的操作應該是unwindToMainMenu
以匹配原始問題
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
if let segue = segue as? UIStoryboardSegueWithCompletion {
segue.completion = {
self.performSegueWithIdentifier("Categories", sender: self)
}
}
}
您的代碼現在將在 exit segue 完成轉換后執行
我現在想為這個問題提供我自己的解決方案。 任何進一步的答案總是受歡迎的。
我將一個布爾變量和 viewDidAppear 函數放入MainPageViewController
。
var fromCamera = false
override func viewDidAppear(animated: Bool) {
if fromCamera {
self.performSegueWithIdentifier("categorySelection", sender: self)
self.fromCamera = false
}
}
在從CropViewController
執行 unwind segue 之前,我將fromCamera
設置為true
。 通過這種方式,只有在從裁剪視圖執行展開轉場時,我才會執行轉場到類別屏幕。
提出這個答案(我只有 Objective-C 代碼)
子類UIStoryBoardSegue
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegue
/**
This block is called after completion of animations scheduled by @p self.
*/
@property (nonatomic, copy) void(^completion)();
@end
並在動畫完成后調用此完成塊。
@implementation MyStoryboardSegue
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
繼續前兩個答案,這里有更多關於目標 c 版本的細節(我也只有 Objective-C 代碼)
使用 UIStoryboardSegueWithCompletion 子類 UIStoryboardSegue
class UIStoryboardSegueWithCompletion: UIStoryboardSegue { var completion: (() -> Void)?
override func perform() { super.perform() if let completion = completion { completion() } }
}
UIStoryboardSegueWithCompletion.h
#import <UIKit/UIKit.h>
@interface MyStoryboardSegue : UIStoryboardSegueWithCompletion
@property (nonatomic, copy) void(^completion)();
@end
UIStoryboardSegueWithCompletion.m
#import "UIStoryboardSegueWithCompletion.h"
@implementation UIStoryboardSegueWithCompletion
- (void)perform {
[super perform];
if (self.completion != nil) {
[self.destinationViewController.transitionCoordinator
animateAlongsideTransition:nil
completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
if (![context isCancelled]) {
self.completion();
}
}];
}
}
@end
注意:此 segue 的操作應該是 unwindToMainMenu 以匹配原始問題 [圖像顯示 segue ui][1] [圖像顯示 segue ui 2][2]
從故事板中選擇退出 segue 添加自定義類
-(IBAction)unwindToMainMenu(UIStoryboardSegue *)segue {
if([segue isKindOfClass:[UIStoryboardSegueWithCompletion class]]){
UIStoryboardSegueWithCompletion *segtemp = segue;// local prevents warning
segtemp.completion = ^{
NSLog(@"segue completion");
[self performSegueWithIdentifier:@"Categories" sender:self];
};
}
}
您的代碼現在將在 exit segue 完成轉換后執行
我猜 performSegue 沒有觸發,因為 unwind segue 還沒有完成。 目前我唯一能想到的是使用dispatch_after
延遲調用 performSegue 。 不過,這對我來說似乎非常“hacky”。
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
dispatch_after(1, dispatch_get_main_queue()) { () -> Void in
self.performSegueWithIdentifier("Categories", sender: self)
}
}
退出轉場 IBAction 方法在實際展開轉場完成之前發生。 我遇到了同樣的問題並以這種方式解決了它(如果你不介意我對你的代碼的解釋)。 它避免了依賴 ViewDidAppear 的額外時間和動畫。
@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
let categoriesTable = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("CategoryTableViewController")
self.navigationController?.viewControllers.append(categoriesTable)
self.navigationController?.showViewController(categoriesTable, sender: self)
}
希望這對遇到此問題並只想立即過渡的任何其他人有所幫助!
更新了@moride 對Swift 5的回答。 轉換協調器現在是可選的,所以如果是這種情況,我們會立即運行完成。
class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
var completion: (() -> Void)?
override func perform() {
super.perform()
guard let completion = completion else { return }
guard let coordinator = destination.transitionCoordinator else {
completion()
return
}
coordinator.animate(alongsideTransition: nil) { context in
guard !context.isCancelled else { return }
completion()
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.