我最近经常使用容器VC,我一直想知道主Vc和容器VC之间的最佳通信方式是什么.现在我正在使用通知,但我宁愿使用更好的东西.如何获取指向容器VC的指针,以便至少可以使用委托?有更好的方法吗?
rob*_*off 22
容器视图控制器在其prepareForSegue:sender:方法中设置自身与嵌入式视图控制器之间的任何必要连接.
在iOS编程中,我们在视图控制器之间有这种通信方式.您可以在*View Controller Programming Guide for iOS中的"协调视图控制器之间的工作"中阅读它.
但我认为用一个具体的例子来理解它会更容易.让我们使用适用于iPhone的Google地图应用:
我不确切知道这个应用程序是如何实现的.但是我们假设有一个顶级AppViewController管理搜索栏(位于顶部)和位置栏(位于底部),它将一个嵌入MapViewController到容器视图中.
视图控制器之间存在一些交互.当用户搜索时,AppViewController需要告诉它MapViewController放置一些地图标记并放大其中一个.当用户点击地图标记时,MapViewController需要告诉AppViewController在底部的位置栏中显示有关该标记的信息.
所以这是模式.
首先,我们为MapViewController(它是嵌入式视图控制器)将发送给AppViewController(它是容器视图控制器)的消息定义一个协议:
@class MapMarker;
@class MapViewController;
@protocol MapViewControllerDelegate <NSObject>
- (void)mapViewController:(MapViewController *)mapViewController didSelectMarker:(MapMarker *)marker;
@end
Run Code Online (Sandbox Code Playgroud)
我们将AppViewController遵守此协议.所以MapViewController不需要AppViewController具体了解.它只需要引用一些符合协议的对象.该MapViewController还必须明白,将其标记信息和缩放到一个特定的标记的消息.所以我们这样声明MapViewController:
@interface MapViewController : UIViewController
@property (nonatomic, weak) id<MapViewControllerDelegate> delegate;
- (void)setMarkers:(NSArray *)markers;
- (void)zoomToMarker:(MapMarker *)marker;
@end
Run Code Online (Sandbox Code Playgroud)
请注意,该delegate属性是weak为了避免保留周期.
的AppViewController需要,以符合MapViewControllerDelegate协议.通常我们在类扩展中声明一致性AppViewController.m,因为一致性不需要AppViewController是公共接口的一部分.该AppViewController还需要将一个参考MapViewController.
@interface AppViewController () <MapViewControllerDelegate>
@property (nonatomic, strong) MapViewController *mapViewController;
@end
Run Code Online (Sandbox Code Playgroud)
接下来,我们进入故事板,选择嵌入segue,并给它一个标识符:
现在我们可以实现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.
}
Run Code Online (Sandbox Code Playgroud)
注意,AppViewController还必须实现mapviewController:didSelectMarker:,并MapViewController需要实现setMarkers:和zoomToMarker:.
| 归档时间: |
|
| 查看次数: |
2448 次 |
| 最近记录: |