我正在实现一个自定义URL方案,它将实体添加到我的数据模型中。实体的详细信息包含在URL中。基本的想法是,电子邮件链接(或来自其他应用程序的链接)将打开我的应用程序并添加新实体。
问题是,我无法确定我的应用在响应时会处于哪种状态。可能会有任意数量的视图控制器。如果实体列表在视图中,我需要为该实体插入一个新行。如果屏幕上显示其他视图,我需要做出不同的反应。有些观点也可能是模态的。
当发生这种情况时,我会对一个简单的模式感到满意 - 中止用户当前正在做的任何事情,然后弹出到根视图控制器。从这里开始,我可能会推送到一个控制器,在那里我将展示要添加的新实体。
我尝试总是忽略任何显示的模态并弹出到根目录,其好处是不需要知道究竟是什么显示:
[(UINavigationController *)self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:NO];
这种方法运作得相当好,但至少有两种情况不足:
UIActionSheet
,则所有投注均已关闭。我不能在不知道显示它的控制器,有权访问该控制器,并向其发送消息以解除操作表的情况下解雇这一点。如果不这样做,则会弹出根视图控制器,但操作表将保留在屏幕上。操作表上的后续点击当然会导致崩溃,因为显示它的控制器已经消失。我怎么能强有力地处理这个问题?我是否应该尝试专门找出当前呈现的视图控制器,并依次处理每个场景?或者是否有一个更具可扩展性的解决方案,每次添加控制器或更改我的应用程序流程时都不需要更新?
答案 0 :(得分:3)
听起来你正在尝试做几件事:
EntityListViewController
显示此新实体,这可能是也可能不在ViewController堆栈上。EntityListViewController
上方的所有视图控制器。EntityViewController
,或者如果视图控制器堆栈中当前有EntityViewController
,您希望使用新实体的数据重新加载。听起来你已经准备好了第1项了,因为你没有明确地询问有关处理url点击和插入新模型对象的信息。
对于其他人来说,灵活的MVC-ish模式将是使用NSNotificationCenter。
插入新模型对象的代码将“发布”通知:
[[NSNotifcationCenter defaultCenter] postNotificationName:@"entity_added" object:myNewEntity];
然后你的各种UI元素(例如,UIAlertView和UIViewController子类)将监听此通知并采取一些有用的操作(如关闭自己,或者在EntityListViewController
或EntityViewController
的情况下,重新加载自己)。
例如,UIViewController
子类可能会这样做:
-(void) viewDidLoad
{
[super viewDidLoad];
[[NSNoticationCenter defaultCenter] addObserver:self selector:@selector(onNewEntity:) name:@"entity_added" object:nil];
-(void) onNewEntity:(MyEntity*)entity
{
// close, or redraw or...
}
-(void) dealloc
{
[[NSNoticationCenter defaultCenter] removeObserver:self];
// if not using ARC, also call [super dealloc];
}
为了让您的生活变得简单(并且不要过多担心所有不同的UI状态),我会考虑在通知发生时执行此操作:
EntityListViewController
重绘自己(如果有什么东西在它上面并不重要)。如果采用这种方法,那么对用户正在/正在做的事情的影响微乎其微,但当他们导航回EntityListViewController
时,它已经显示了所有新实体。
显然,如果单击自定义URL可能会删除现有实体,那么弹出与该实体相关的任何视图控制器会更为重要。但这也是你可以使用相同的模式做的事情 - 让模型或控制器发布通知,然后让各种UI元素听取它并采取适当的行动。