簡體   English   中英

在展開 segue 后執行 push segue

[英]Perform push segue after an unwind segue

我正在開發一個相機應用程序,其中相機視圖以模態顯示。 在我完成裁剪之后。 我對MainPageViewController執行 unwind segue 。 (請看截圖)

故事板

我在MainPageViewController unwind 函數如下;

@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
    self.performSegueWithIdentifier("Categories", sender: self)
}

其中“categories”是從MainPageViewControllerCategoriesTableViewController的推送序列標識符。

程序進入unwindToMainMenu函數,但不執行 push segue。 知道如何解決這個問題嗎?

注意:我發現了同樣的問題,但答案建議更改故事板結構。

聚會有點晚了,但我找到了一種不使用州旗的方法

注意:這僅適用於 iOS 9+,因為只有自定義轉場支持 iOS9 之前的類名,並且您不能在故事板中將退出轉場聲明為自定義轉場

1. 使用 UIStoryboardSegueWithCompletion 子類 UIStoryboardSegue

class UIStoryboardSegueWithCompletion: UIStoryboardSegue {
    var completion: (() -> Void)?

    override func perform() {
        super.perform()
        if let completion = completion {
            completion()
        }
    }
}

2. 將 UIStoryBoardSegueWithCompletion 設置為退出轉場的類

注意:此 segue 的操作應該是unwindToMainMenu以匹配原始問題

從情節提要中選擇退出轉場 添加自定義類

3. 更新您的 unwind @IBAction 以執行完成處理程序中的代碼

@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 代碼)

  1. 使用 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
  1. 將 UIStoryBoardSegueWithCompletion 設置為退出 segue 的類

注意:此 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM