我正在实现一个自定义URL方案,该方案会将实体添加到我的数据模型中。实体的详细信息包含在URL中。基本想法是,电子邮件链接(或其他应用程序的链接)将打开我的应用程序并添加新实体。

问题是,我永远无法确定响应时我的应用程序将处于哪种状态。视图中可以包含任意数量的视图控制器。如果查看实体列表,则需要为该实体插入新行。如果屏幕上还有其他视图,我需要做出不同的反应。一些观点可能也是模态的。

当发生这种情况时,我会对一个简单的模式感到满意-中止用户当前正在执行的操作,然后弹出到根视图控制器。从这里我可能会推送到一个控制器,在其中显示要添加的新实体。

我一直尝试关闭所有显示的模式并弹出到根目录,这样做的好处是不需要知道确切显示的内容:

[(UINavigationController *)self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
[(UINavigationController *)self.window.rootViewController popToRootViewControllerAnimated:NO];

这相当有效,但是至少有两种情况不足:
  • 如果在显示模态时创建了某个对象(然后使用模态修改新对象),并且如果用户取消,则委托人有责任删除该对象,则实体将保持 Activity 状态。
  • 如果正在显示UIActionSheet,则所有投注均关闭。在不知道显示该控制器的控制器,无法访问该控制器并向其发送消息以消除操作表的情况下,我无法将其消除。如果不这样做,则会弹出根视图控制器,但操作表会保留在屏幕上。当然,随后点击操作表会导致崩溃,因为显示该操作表的控制器已消失。

  • 我该如何稳健处理?我是否应该尝试专门找出当前提供的视图控制器,然后依次处理每种情况?还是有一个更具可扩展性的解决方案,每次添加控制器或更改应用程序流程时都不需要更新?

    最佳答案

    听起来您正在尝试做几件事:

  • 当用户单击您的自定义URL时,您要向模型添加“实体”。
  • 您想以某种EntityListViewController显示此新实体,它可能会或可能不在ViewController堆栈中。
  • 您(可能)想弹出EntityListViewController上方的所有视图控制器。
  • 您希望用户知道添加了一个新实体(也许只是通过执行第2项)。
  • 您想推送某种EntityViewController,或者如果视图控制器堆栈中当前有一个EntityViewController,那么您想重新加载新实体的数据。

  • 听起来好像您准备好了第1项,因为您没有明确询问要处理url单击并插入新的模型对象。

    对于其他情况,一种灵活的MVC模式将是使用NSNotificationCenter。

    插入新模型对象的代码将“发布”通知:
    [[NSNotifcationCenter defaultCenter] postNotificationName:@"entity_added" object:myNewEntity];
    

    然后,您的各种UI元素(例如,UIAlertView和UIViewController子类)将侦听此通知并采取一些有用的操作(例如关闭自身,或者在EntityListViewControllerEntityViewController的情况下,重新加载自身)。

    例如,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元素侦听通知并采取适当的措施。

    关于ios - 在不知道当前 View 状态的情况下实现openURL,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14096009/

    10-09 16:15
    查看更多