「A」、「B」、「C」というラベルの付いた3つのビューコントローラがあるとします。現在、「A」はウィンドウのrootViewControllerであり、ボタンをタップすると「B」がモーダルに表示されます。 「B」では、ボタンをタップすると「A」で消えてしまい、「A」はすぐにCをモーダルに表示します。どうすればいいですか?これがこの目標を達成することを期待する私のコードですが、私はそれを達成することに失敗しました。
「A」viewControllerで、「B」viewControllerが「A」によって却下されたときに呼び出されるヘッダーファイルにブロックを保持するプロパティを宣言しました。
@property (nonatomic, copy) void (^presentZapLaunch)(void);
これは、「B」を提示するための「A」viewControllerpresentメソッドです。
-(void)presentNextViewCon
{
CYCGestureZapZapViewController *gestureViewCon = [[CYCGestureZapZapViewController alloc]init];
if (!self.presentZapLaunch) {
__weak CYCZapZapViewController *weakRefCon = self;
self.presentZapLaunch = ^{
CYCZapZapViewController *preventWeakRefCon = weakRefCon;
CYCZapZapLaunchViewController *zapLaunch = [[CYCZapZapLaunchViewController alloc]init];
NSLog(@"Called");
[preventWeakRefCon presentViewController:zapLaunch animated:YES completion:nil];
};
}
[self presentViewController:gestureViewCon animated:YES completion:nil];
}
これは「A」によって却下される「B」却下方法であり、「A」は「C」をすぐに提示する必要があります
-(void)presentNextViewCon
{
NSLog(@"Hello");
[self.presentingViewController dismissViewControllerAnimated:self completion:^{[(CYCZapZapViewController *)self.presentingViewController presentZapLaunch];}];
}
*ウィンドウのrootViewControllerとして「A」ビューコントローラーを使用していることに注意してください。「A」は「B」ビューコントローラーをモーダルに表示します。 「A」、「B」、「C」はすべてビューコントローラです。
あなたはプロトコルを使用して行うことができます例えば以下のようにしましょう:-
B viewController設定プロトコルに:
@class Bviewcontroller;
@protocol BviewControllerDelegate <NSObject>
- (void)BviewcontrollerDidTapButton:
(Bviewcontroller *)controller;
@end
@interface Bviewcontroller : UIViewcontroller
@property (nonatomic, weak) id <BviewControllerDelegate> delegate;
- (IBAction)ButtonTap:(id)sender;
@end
。mクラス
- (IBAction)ButtonTap:(id)sender
{
[self.delegate BviewcontrollerDidTapButton:self];
}
A_viewController .h class:
#import "Bviewcontroller.h"
@interface A_viewController : UIViewcontroller<BviewControllerDelegate>
.mクラス
- (void)BviewcontrollerDidTapButton:
(Bviewcontroller *)controller
{
[self dismissViewControllerAnimated:YES completion:^{
// here you can create a code for presetn C viewcontroller
}];
}
[〜#〜]重要[〜#〜]A_viewControllerからBviewcontrollerをプリセットする場合、次のようなオブジェクトでデリゲートを設定しないでください。
-(void)presentNextViewCon
{
bViewcontroller *gestureViewCon = [[bViewcontroller alloc]init];
gestureViewCon.delegate = self;
[self presentViewController:gestureViewCon animated:YES completion:nil];
}
[〜#〜]更新[〜#〜]
これが私が次のように機能するデモを作成することです:
サンプルコードリンクhttp://speedy.sh/2acSC/modelDemo.Zip
ボタンについては、controlButtonという名前を付けます。カスタムinitメソッドを使用してBとCでそのボタンを渡します。これは、UIViewControllerAがcontrollButton参照を持っていることを意味します。メソッドの使用
- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents
aにトリガーブロックを設定し、このようにします
[_controllButton addTarget:self action:@selector(controllButtonTapped:)....];
- (void)controllButtonTapped:(id)sender {
[self dismissViewControllerAnimated:YES completion:^{
// present you c here
[self presentViewController:c animated:YES completion:NULL];
}];
}
しかし、最良の選択肢は、コーディネーターがあなたの現在の行動を調整し、行動を却下する「メディエーターデザインパターン」を採用することです。
Bを却下してCを同時に提示することはできません。
このタスクを実行するには、いくつかのタスクに従う必要があります。
-(void)viewDidAppear:(BOOL)アニメーションの「A」
if(bool){[self presentViewController:cアニメーション:YES完了:nil]; }
専門家ではないように見えるAを簡単に表示せずにBからCに移動することは不可能のようです。ただし、Cにアニメーション化するまで、Aの上に黒いサブビューを配置できます。
In Swift 3:
class A : UIViewController {
...
func showB() {
// Adding the black view before dismissing B does not work;
// the view is not displayed.
let black = UIView()
black.backgroundColor = UIColor.black
black.frame = self.view.bounds // assumes A is not zoomed
let b = B()
self.present(b, animated:true, completion: {
self.view.addSubview(black)
})
// Note: self.present() will start the animation,
// then b.imDone will be set. It is done here for
// clarity of what happens next, as if it were all
// one function.
b.imDone = {
b.dismiss(animated:false, completion: {
self.present(C(), animated:true, completion: {
black?.removeFromSuperview()
})
})
}
}
}
class B : UIViewController {
var imDone : (() -> Void)?
...
func f()
{
imDone?()
}
...
}
class C : UIViewController
{
...
}