【问题标题】:Reference to calling viewcontroller / Method depending on type of calling view controller调用视图控制器/方法的参考取决于调用视图控制器的类型
【发布时间】:2014-05-14 18:54:14
【问题描述】:

我有一个视图控制器,它是从其他几个视图控制器调用的。这个视图控制器包含一个 UITextField,它收集不同的信息,具体取决于哪个视图控制器调用了它。 信息必须在收集后存储。为了尽可能独立,存储信息的方法应该位于调用视图控制器中。 因此,我在方法中使用以下代码来收集信息:

- (void) collectContent
{
    NSString *info = [textField text];
    [textField resignFirstResponder];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"NewValueA" object:info];

    [[self navigationController] popToRootViewControllerAnimated:YES];
}

在调用视图控制器中,我在它的 init 方法中有以下行:

- (id) init
{
    ...
    if (self)
    {
        ...
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(storeNewValueA) name:"NewValueA" object:nil];
    }
return self;
}

但是现在,我想从另一个视图控制器中使用这个视图控制器来收集 ValueB 或 ValueC。如何引用调用视图控制器来调用存储收集值的方法?我想决定,如果视图控制器是从 vcB 调用的,则输入的值必须是 valueB,依此类推...

【问题讨论】:

    标签: ios objective-c cocoa-touch uiviewcontroller uikit


    【解决方案1】:

    嗯,如果你想在应用程序关闭的情况下保留这个简单的字符串,我会使用NSUserDefaults

    存储字符串:

    [[NSUserDefaults standardUserDefaults] setObject:@"MyValue" ForKey:@"USER_DEFAULTS_VIEWCONTROLLER_VALUES"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    

    获取字符串:

    [[NSUserDefaults standardUserDefaults] objectForKey:@"USER_DEFAULTS_VIEWCONTROLLER_VALUES"];
    

    【讨论】:

    • 虽然我不会引用调用控制器,但这正是我试图实现的!而且,视图控制器没有 tio 知道,谁打电话给他,真的是松散耦合的...... :-)
    • 不过我必须知道要存储哪个值,即我必须为存储在 NSUserDefaults 中的值调用方法。
    • 谁调用谁的方法? :-) ViewControllerA 是否调用 ViewControllerA 或 ViewControllerA->TextFieldViewController 甚至 TextFieldViewController->TextFieldViewController 的选择器? :)
    【解决方案2】:

    你可以为这个常用的视图控制器创建一个协议,并通过调用视图控制器来实现这个协议:

    @protocol TextFieldViewControllerDelegate : NSObject {
        - (void)contentCollected;
    }
    

    在您的文本字段(通用)视图控制器中定义一个委托属性:

    @property (nonatomic, strong) id<TextFieldViewControllerDelegate> delegate;
    

    调用视图控制器会将自己设置为委托并实现所需的方法:

    - (void) contentCollected:(NSString *)value
    {
        // Store the value where needed
    }
    

    在通用(文本字段)视图控制器中,在需要时通知委托:

    - (void) collectContent
    {
        NSString *info = [textField text];
        [textField resignFirstResponder];
    
        [_delegate contentCollected:info];
    
        [[self navigationController] popToRootViewControllerAnimated:YES];
    
        _delegate = nil;
    }
    

    这样你的通用视图控制器就不需要知道是哪个视图控制器调用了它。使用委托将通知调用视图控制器。

    【讨论】:

    • 我已经考虑过委托和实现协议。如果我这样做,我会在控制器之间建立一个相对紧密的耦合。这是我想要避免的......
    • 这不是紧密耦合,因为公共视图控制器不知道也不关心谁是它的委托人,它只需要委托人实现协议方法才能正确得到通知。
    • 是的,你是对的!通过调用委托方法,我可以传递任何我想要的信息——不管它是什么类型的!
    • 没错,在推送文本字段控制器之前不要忘记将委托设置为 self(调用控制器)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-26
    • 2014-10-19
    相关资源
    最近更新 更多