web-dev-qa-db-ja.com

巻き戻しセグエの後にプッシュセグエを実行する

カメラビューがモーダルで表示されるカメラアプリに取り組んでいます。トリミングが終わった後。 MainPageViewControllerにアンワインドセグエを実行します。 (スクリーンショットを参照してください)

storyboard

MainPageViewController内のアンワインド関数は次のとおりです。

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

ここで、「categories」はMainPageViewControllerからCategoriesTableViewControllerへのプッシュセグエ識別子です。

プログラムはunwindToMainMenu関数に入りますが、プッシュセグエは実行しません。これを修正する方法はありますか?

注:同じ 質問 を見つけましたが、答えはストーリーボードの構造を変更することを示唆しています。

34
Berkan Ercan

パーティーに少し遅れましたが、州の旗を使わずにこれを行う方法を見つけました

注:これはiOS 9以降でのみ機能します。これは、カスタムセグエのみがiOS9より前のクラス名をサポートし、ストーリーボードで終了セグエをカスタムセグエとして宣言できないためです。

1.UIStoryboardSegueWithCompletionを使用してUIStoryboardSegueをサブクラス化します

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

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

2.UIStoryBoardSegueWithCompletionを出口セグエのクラスとして設定します

注:このセグエのアクションは、元の質問と一致するようにunwindToMainMenuである必要があります

Select exit segue from storyboardAdd custom class

3. unwind @IBActionを更新して、完了ハンドラーでコードを実行します

@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
    if let segue = segue as? UIStoryboardSegueWithCompletion {
        segue.completion = { 
            self.performSegueWithIdentifier("Categories", sender: self) 
        }
    }
}

出口セグエが遷移を完了した後、コードが実行されます

48
wyu

今のところ、この問題に対する独自の解決策を提供したいと思います。それ以上の回答はいつでも歓迎します。

ブール変数とviewDidAppear関数をMainPageViewControllerに配置しました。

var fromCamera = false

override func viewDidAppear(animated: Bool) {
    if fromCamera {
        self.performSegueWithIdentifier("categorySelection", sender: self)
        self.fromCamera = false
    }
}

fromCameraからアンワインドセグエを実行する前に、trueCropViewControllerに設定しました。このように、クロップビューからのアンワインドセグエが実行された場合にのみ、カテゴリ画面へのセグエを実行します。

12
Berkan Ercan

前進 この答え (私は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
6
Ayush Goel

前の2つの答えを先に進めると、ここにObjective Cバージョンについてもう少し詳しく説明します(私もObjective-Cコードしか持っていませんでした)

  1. UIStoryboardSegueWithCompletionを使用したサブクラスUIStoryboardSegue

    クラスUIStoryboardSegueWithCompletion:UIStoryboardSegue {var complete:(()-> 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を出口セグエのクラスとして設定します

注:このセグエのアクションは、元の質問と一致するようにunwindToMainMenuである必要があります[セグエUIを示す画像] [1] [セグエUI2を示す画像] [2]

ストーリーボードからexitsegueを選択しますカスタムクラスを追加します

-(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];
        };
    }
}

出口セグエが遷移を完了した後、コードが実行されます

5
moride

アンワインドセグエがまだ終わっていないので、performSegueが起動していないと思います。現時点で私が考えることができる唯一のことは、dispatch_afterを使用してperformSegueの呼び出しを遅らせることです。しかし、これは私には非常に「ハッキー」に思えます。

@IBAction func unwindToMainMenu(segue: UIStoryboardSegue) {
    dispatch_after(1, dispatch_get_main_queue()) { () -> Void in
        self.performSegueWithIdentifier("Categories", sender: self)
    }
}
4
Ron Fessler

終了セグエ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)
}

これがこれに遭遇し、ただ瞬時の移行を望んでいる他の人にとって役立つことを願っています!

3
Cole