【问题标题】:How to understand/create a delegate to dismiss a view controller如何理解/创建委托以关闭视图控制器
【发布时间】:2014-12-08 20:01:09
【问题描述】:

试图更好地了解 iOS delegation。我使用UIImagePickerController 作为参考,但有什么好的代码示例可以使用委托来关闭我的视图控制器?

我有一个调用 AViewController 的 TabBarViewController 并且想使用 delegation 来关闭 AViewController。

【问题讨论】:

标签: ios uiviewcontroller delegates uitabbarcontroller


【解决方案1】:

在这种情况下,想法是呈现新视图控制器的类也应该是关闭它的类。 AViewController 可能不知道它是如何呈现的,所以它想让呈现器 TabBarViewController 以任何需要的形式处理解除。因此,我们需要定义一个协议,比如 AViewControllerProtocol,它允许对解除调用有一个标准定义:

这在 AViewControllerProtocol.h 中:

@protocol AViewControllerProtocol <NSObject>
@required
- (void) dismissWithDone:(UIViewController *)viewController;
- (void) dismissWithCancel:(UIViewController *) viewController;
@optional
- (void)dismissWithDone:(UIViewController *)viewController andPlaySoundFile:(NSString *)soundPath;
@end

这在一个名为 AViewControllerProtocol.h 的文件中。 TabBarViewController.m 和 AViewController.m 都会导入它。将此视为 AViewController 的任何用户必须同意才能使用它的协议。同样,如果没有约定遵守 UITableViewDelegate 和 UITableViewDataSource 协议(它们是两个独立的协议),您也不能使用 UITableView。

任何想要呈现 AViewController 的类,都可以从协议定义中看到 AViewController 需要两个必需的方法才能被正确地解除。它还有一个可选的第三种方法,请求演示者在关闭后播放声音。

为了让 AViewController 履行其职责,它需要获取并存储有关演示者是谁的信息。那就是所谓的委托。委托是在AViewController的@interface中定义的一个属性,在AViewController.h中:

这在 AViewController.h 中:

@property (nonatomic, weak) id<AViewControllerProtocol> delegate;

现在,演示者 TabBarViewController 需要发挥作用。它需要定义两个必需的方法,加上可能是最优的一个,还需要设置委托值:

在 TabBarViewController.m 中,在 @implementation 中:

这在 TabBarViewController.m 中:

- (void) dismissWithDone:(UIViewController *)viewController
{
    [self saveData:viewController.dataToSave];  // this could be the results that need to be saved
    [viewController dismissViewControllerAnimated:YES completion:^{
        ;
    }];
}


- (void) dismissWithCancel:(UIViewController *)viewController
{
    // don't save data
    [viewController dismissViewControllerAnimated:YES completion:^{
        ;
    }];
}

委托值是在 AViewController 首次创建和/或呈现之前设置的:

这也在 TabBarViewController.m 中:

    AViewController * aVC = [AViewController.alloc init];
    aVC.delegate = self;
    aVC.data = ...; // this may be the data you want changed by the VC
    [self presentViewController:aVC animated:YES completion:^{
    }];

在这里设置委托是 AViewController 类与其呈现的 viewController 的唯一连接——这就是这里的重点:子类真的不需要知道很多关于使用它们的类。

最后,AViewController 类需要添加以下内容,以便通过委托调用回呈现类 - 所以在 AViewController.m 中:

这在 AViewController.m 中:

-(IBAction)userHitButton:(id)sender
{
    if (sender == doneButton) {
        if ([_delegate respondsToSelector:@selector(dismissWithDone:)]) {
            [_delegate dismissWithDone:self];
        }
    } else {
        if ([_delegate respondsToSelector:@selector(dismissWithCancel:)]) {
            [_delegate dismissWithCancel:self];
        }
    }
}

如果你想知道为什么调用类必须:

    aVC.delegate = self;

这是因为在某些情况下,实际创建子类的类不是处理委托调用的类。在这种情况下,您可以放置​​一个将处理委托回调的类的实例,而不是 self。例如,假设您有 AViewController、BViewController 和 CViewController。他们都从用户那里获取需要保存的数据。假想名称为 ABCDataHandler 的类可以处理dismissWithDone: 和dismissWithCancel: 回调并根据需要保存数据,并且TabBarViewController 可以远离任何数据处理活动。

尽可能简单地说。我希望我没有在这里打错字:-)

【讨论】:

    猜你喜欢
    • 2011-07-03
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多