从模态视图或推送视图调用父方法到presentingViewController
Posted
技术标签:
【中文标题】从模态视图或推送视图调用父方法到presentingViewController【英文标题】:Calling parent method from a modal or push view to presentingViewController 【发布时间】:2014-03-01 21:43:43 【问题描述】:我有一个 UINavigationGroup
和一个名为 MainViewController
的根视图控制器。在这个MainViewController
中,我将另一个UINavigationController
作为模态调用,如下所示:
- (IBAction)didTapButton:(id)sender
UINavigationController * someViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"someNavigationController"];
[self.navigationController presentViewController:someViewController animated:YES completion:nil];
在这个someNavigationController
中,用户正在经历一些过程,所以导航控制器被一些UIViewControllers
推送。用户完成该过程后,在最后一个名为finalStepViewController
的UIViewController
中,我将关闭模式如下:
[self dismissViewControllerAnimated:YES completion:nil];
模态确实被解除了,用户又回到了最初的MainViewController
。
但是,我想将另一个UIViewController
推送到MainViewController
的 NavigationController(例如:表示用户成功完成该过程的视图)。最好在模态被解除之前。
我尝试了以下方法:
1.使用presentingViewController
UIViewController * successViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"successViewController"];
[self.presentingViewController.navigationController successViewController animated:YES];
结果:没有错误,但也没有发生任何事情。
2。委托/协议
在MainViewController.h
中导入finalStepViewController.h
并附加<finalStepViewControllerDelegate>
在MainViewController.m
内部添加了一个名为parentMethodThatChildCanCall
的方法,可以从finalStepViewController.m
调用
将以下内容添加到finalStepViewController.h
:
@protocol finalStepViewControllerDelegate <NSObject>
-(void)parentMethodThatChildCanCall;
@end
@property (assign) id <finalStepViewControllerDelegate> delegate;
和模型中的@synthesize delegate;
didTapButton
IBAction 中的delegate 属性设置为someViewController
为self。这显示了一个通知错误:Assigning to id<UINavigationControllerDelegate>' from incompatible type UIViewController *const __strong'
最后在关闭模式之前调用[self.delegate parentMethodThatChildCanCall]
。
结果:除了通知错误,没有失败但没有任何反应,因为没有调用parentMethodThatChildCanCall
。
知道我做错了什么/我应该做什么吗?这是我做 Objective-C 的第二周,大多数时候我不知道我在做什么,所以任何帮助/代码都将不胜感激!
谢谢。
【问题讨论】:
【参考方案1】:使用NSNotificationCenter
可以更轻松地实现这一目标。
在您的MainViewController
的-viewDidLoad
中添加以下代码
typeof(self) __weak wself = self;
[[NSNotificationCenter defaultCenter] addObserverForName:@"successfullActionName"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note)
SuccessViewController *viewController; // instantiate it properly
[wself.navigationController pushViewController:viewController animated:NO];
];
在 dealloc 时从 NSNotificationCenter 中移除你的控制器
- (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
在FinalStepViewController
中,在关闭发布通知之前关闭视图控制器的操作
- (IBAction)buttonTapped:(id)sender
[[NSNotificationCenter defaultCenter] postNotificationName:@"successfullActionName" object:nil];
[self dismissViewControllerAnimated:YES completion:nil];
这个例子非常粗略,并不理想,你应该为你的通知名称使用常量,并且在某些情况下存储NSNotificationCenter
返回的观察者以删除特定的。
-- 编辑
我还想提一下addObserverForName:object:queue:usingBlock:
方法实际上将观察者作为id
类型对象返回。您需要将对它的引用作为 iVar 存储在您的类中,并在调用 dealloc
方法时将其从 NSNotificationCenter
中删除,否则观察者将永远不会被释放。
【讨论】:
这行得通,感谢您的快速回答。您能否详细说明/提供有关您上一条评论的说明? 您应该创建具有不言自明名称的静态常量,并使用它们代替 NSStrings 作为 notificationName。例如,在您的情况下,您可能创建了一个常量static NSString *const MYSuccessfullActionNotification = @"MYSuccessfullActionNotification";
并将常量值传递给[[NSNotificationCenter defaultCenter] postNotificationName:MYSuccessfullActionNotification object:nil];
。常量基本上可以帮助您避免拼写错误。以上是关于从模态视图或推送视图调用父方法到presentingViewController的主要内容,如果未能解决你的问题,请参考以下文章