gpt4 book ai didi

ios - 与容器 View 通信的最佳实践是什么

转载 作者:可可西里 更新时间:2023-11-01 03:36:15 24 4
gpt4 key购买 nike

我最近经常使用容器 VC,我一直想知道在主 Vc 和容器 VC 之间通信的最佳方式是什么。现在我正在使用通知,但我宁愿使用更好的东西。我怎样才能获得指向容器 VC 的指针,以便至少可以使用委托(delegate)?有什么更好的方法吗?

最佳答案

由容器 View Controller 在它的 prepareForSegue:sender: 方法中在它自己和嵌入式 View Controller 之间建立任何必要的连接。

在 iOS 编程中,我们有一种用于 View Controller 之间这种通信方式的模式。您可以在 “Coordinating Efforts Between View Controllers” in the *View Controller Programming Guide for iOS” 中阅读相关信息.

不过我觉得举个具体的例子更容易理解。让我们使用 iPhone 版 Google map 应用程序:

Google Maps app for iPhone

我不知道这个应用程序是如何实现的。但是让我们假设有一个顶层的 AppViewController 管理搜索栏(在顶部)和地址栏(在底部),并且它嵌入了一个 MapViewController容器 View 。

View Controller 之间有一些交互。当用户搜索时,AppViewController 需要告诉 MapViewController 放置一些 map 标记并放大其中之一。当用户点击 map 标记时,MapViewController 需要告诉 AppViewController 在底部的位置栏中显示有关该标记的信息。

这就是模式。

首先,我们为 MapViewController(嵌入式 View Controller )将发送到 AppViewController(容器 View Controller )的消息定义一个协议(protocol):

@class MapMarker;
@class MapViewController;

@protocol MapViewControllerDelegate <NSObject>

- (void)mapViewController:(MapViewController *)mapViewController didSelectMarker:(MapMarker *)marker;

@end

我们将使 AppViewController 符合此协议(protocol)。所以 MapViewController 不需要特别了解 AppViewController。它只需要引用一些符合协议(protocol)的对象。 MapViewController 还需要理解设置其标记的消息和缩放到特定标记的消息。所以我们这样声明 MapViewController:

@interface MapViewController : UIViewController

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

- (void)setMarkers:(NSArray *)markers;
- (void)zoomToMarker:(MapMarker *)marker;

@end

请注意,delegate 属性是 weak 以避免保留循环。

AppViewController 需要遵守MapViewControllerDelegate 协议(protocol)。通常我们在 AppViewController.m 的类扩展中声明一致性,因为一致性不需要成为 AppViewController 的公共(public)接口(interface)的一部分。 AppViewController 还需要引用 MapViewController

@interface AppViewController () <MapViewControllerDelegate>

@property (nonatomic, strong) MapViewController *mapViewController;

@end

接下来,我们进入 Storyboard,选择嵌入转场,并给它一个标识符:

embed segue identifier

现在我们可以实现 prepareForSegue:sender: 方法来连接属性:

@implementation AppViewController

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"MapEmbedding"]) {
[self prepareForMapEmbeddingSegue:segue sender:sender];
}
}

- (void)prepareForMapEmbeddingSegue:(UIStoryboardSegue *)segue sender:(id)sender {
self.mapViewController = segue.destinationViewController;
self.mapViewController.delegate = self;

// We can do any additional setup on mapViewController here,
// like set its initial viewport.
}

注意AppViewController也需要实现mapviewController:didSelectMarker:MapViewController需要实现setMarkers:zoomToMarker:

关于ios - 与容器 View 通信的最佳实践是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17396629/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com