【问题标题】:UIViewController parentViewController access propertiesUIViewController parentViewController 访问属性
【发布时间】:2010-03-09 21:25:37
【问题描述】:

我知道这个问题已经被问过好几次了,我确实阅读了关于这个主题的现有帖子,但我仍然需要帮助。

我有 2 个UIViewControllers - 父母和孩子。我使用presentModalViewController 显示孩子UIViewController,如下所示:

ChildController *child = 
 [[ChildController alloc] initWithNibName:@"ChildView" bundle:nil];
[self presentModalViewController:child animated:YES];
[child release];

子视图有一个UIPickerView。当用户从UIPickerView 中选择一个项目并单击完成时,我必须关闭模式视图并在父视图的UITextField 上显示所选项目。

在孩子的按钮点击delegate,我执行以下操作:

ParentController *parent = 
 (ParentController *)[self.navigationController parentViewController];
[parent.myTextField setText:selectedText];
[self dismissModalViewControllerAnimated:YES];

一切正常,没有错误。但我不知道如何加载父视图以显示更新的UITextField

我试过了

[parent reloadInputViews];

不起作用。请帮忙。

【问题讨论】:

    标签: objective-c uiviewcontroller parentviewcontroller


    【解决方案1】:

    委托是要走的路。我知道有些人可能正在寻找更简单的解决方案,但相信我,我已经尝试过其他人,没有什么比委派更好的了。所以任何有同样问题的人,去阅读委托并一步一步地遵循它。

    在您的 subviewcontroller.h - 声明一个协议并在其中声明委托方法。

    @protocol myDelegate
     -(void)clickedButton:(subviewcontroller *)subController;
    @end
    

    在您的 subviewcontroller.h 中,在 @interface 内:

    id<myDelegate> delegate;
    @property (nonatomic, assign) id<myDelegate> delegate;    
    NSString *data;
    -(NSString *)getData;
    

    在您的 subviewcontroller.m 中,合成 myDelegate。将以下代码添加到您要通知父视图控制器子视图已完成应做的任何事情的位置:

     [delegate clickedButton:self];
    

    然后处理 getData 以返回您要发送到父视图控制器的任何数据

    在你的 parentviewcontroller.h 中,导入 subviewcontroller.h 并使用它的委托

     #import "subviewcontroller.h"
     @interface parentviewcontroller : VUIViewController <myDelegate>
     {}
    

    在你的 parentviewcontroller.m 中,实现委托方法

     - (void)clickedButton:(subviewcontroller *)subcontroller
     {
       NSString *myData = [subcontroller getData];
       [self dimissModalViewControllerAnimated:YES];
       [self reloadInputViews];
     }
    

    不要忘记内存管理!

    【讨论】:

    • 那是埃芬史诗般的答案,伙计。谢谢!。 :-)
    【解决方案2】:

    如果在模态视图显示期间出现内存不足警告,则父视图将被卸载。然后parent.myTextField 不再引用正确的文本字段,直到重新加载视图。你可以通过调用parent.view;来强制重新加载视图

    然而,一个更好的主意可能是让父视图有一个可以由子视图设置的 String 属性。然后,当父视图重新出现时,将该数据放入文本字​​段中,例如在 viewWillAppear: 中。您希望将值设置为父视图最初显示时的某个默认值。

    【讨论】:

    • viewWillAppear 在子模式被解除时不会触发。 “完成”按钮位于子视图内,我在其中获取选择器视图的选定文本,然后关闭模式。父母就在那里,不必重新出现。我猜这就是为什么它不会触发 viewWillAppear。
    • 如果你做的一切都是正确的,按照它应该使用的方式使用框架,viewWillAppear 应该被调用。你确定你在正确的类中覆盖了正确的方法吗?
    【解决方案3】:

    -(void) viewWillAppear:(BOOL) 动画也不会被我调用,正是当它是模态视图控制器时。不知道为什么。在这个应用程序的任何地方都没有被错误地覆盖,同样的问题发生在我正在处理的其他 2 个应用程序上。我真的不认为它有效。

    我以前使用过委托方法,但我认为下面的方法也很好。

    我通过向 UIViewController 添加一个私有类别来解决这个问题,如下所示:

    .h 文件:

    @interface UIViewController(Extras)
    // returns true if this view was presented via presentModalViewController:animated:, false otherwise.
    @property(readonly) BOOL isModal;
    // Just like the regular dismissModalViewController, but actually calls viewWillAppear: on the parent, which hasn't been working for me, ever, for modal dialogs.
    - (void)dismissModal: (BOOL) animated;
    @end
    

    和.m文件:

    @implementation UIView(Extras)
    -(BOOL) isModal
    {
        return self == self.parentViewController.modalViewController;
    }
    
    - (void)dismissModal: (BOOL) animated
    {
        [self.parentViewController viewWillAppear: animated];
        [self dismissModalViewControllerAnimated: animated];
    }
    @end
    

    当我想关闭对话框时,我现在可以这样调用:

    // If presented as a modal view, dismiss yourself. 
    if(self.isModal)
        [self dismissModal: YES];
    

    现在 viewWillAppear 被正确调用了。

    是的,我捐赠了一个额外的“isModal”属性,以便模态视图可以判断它是如何呈现的,并适当地关闭它自己。

    【讨论】:

      猜你喜欢
      • 2013-05-20
      • 1970-01-01
      • 2012-07-01
      • 1970-01-01
      • 2012-08-02
      • 2012-02-05
      • 2010-11-26
      • 1970-01-01
      • 2011-12-12
      相关资源
      最近更新 更多