效果图
AppDelegate.h
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, copy) NSString *sharedString;
@end
AppDelegate.m
#import "AppDelegate.h"
#import "TestViewControllerA.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
TestViewControllerA *vcA = [[TestViewControllerA alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vcA];
self.window.rootViewController = nav;
[self.window makeKeyAndVisible];
return YES;
}
TestViewControllerA.h
#import <UIKit/UIKit.h>
@interface TestViewControllerA : UIViewController
@end
TestViewControllerA.m
#import "TestViewControllerA.h"
#import "TestViewControllerB.h"
#import "AppDelegate.h"
@interface TestViewControllerA ()<TestViewControllerBDelegate>
{
UILabel *_delegateLabel;
UILabel *_blockLabel;
UILabel *_notificationLabel;
UILabel *_mediatorLabel;
}
@end
@implementation TestViewControllerA
- (instancetype)init
{
self = [super init];
if (self)
{
[self.navigationItem setTitle:@"ViewController A"];
self.edgesForExtendedLayout = UIRectEdgeNone;
}
return self;
}
- (void)loadView
{
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor whiteColor];
self.view = view;
//property button
UIButton *propertyButton = [[UIButton alloc] init];
[propertyButton setBackgroundColor:[UIColor lightGrayColor]];
[propertyButton setTitle:@"next VC (property)" forState:UIControlStateNormal];
[propertyButton addTarget:self action:@selector(propertyButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
propertyButton.frame = CGRectMake(50, 50, 200, 30);
[view addSubview:propertyButton];
//initializer button
UIButton *initializerButton = [[UIButton alloc] init];
[initializerButton setBackgroundColor:[UIColor lightGrayColor]];
[initializerButton setTitle:@"next VC (initializer)" forState:UIControlStateNormal];
[initializerButton addTarget:self action:@selector(initializerButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
initializerButton.frame = CGRectMake(50, CGRectGetMaxY(propertyButton.frame) + 30, 200, 30);
[view addSubview:initializerButton];
//delegate button
UIButton *delegateButton = [[UIButton alloc] init];
[delegateButton setBackgroundColor:[UIColor lightGrayColor]];
[delegateButton setTitle:@"next VC (delelgate)" forState:UIControlStateNormal];
[delegateButton addTarget:self action:@selector(delegateButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
delegateButton.frame = CGRectMake(50, CGRectGetMaxY(initializerButton.frame) + 30, 200, 30);
[view addSubview:delegateButton];
_delegateLabel = [[UILabel alloc] init];
[_delegateLabel setBackgroundColor:[UIColor lightGrayColor]];
[_delegateLabel setTextColor:[UIColor whiteColor]];
[_delegateLabel setFont:[UIFont systemFontOfSize:15]];
_delegateLabel.textAlignment = NSTextAlignmentCenter;
_delegateLabel.frame = CGRectMake(CGRectGetMaxX(delegateButton.frame) + 5, CGRectGetMinY(delegateButton.frame), 150, 30);
[view addSubview:_delegateLabel];
//block button
UIButton *blockButton = [[UIButton alloc] init];
[blockButton setBackgroundColor:[UIColor lightGrayColor]];
[blockButton setTitle:@"next VC (block)" forState:UIControlStateNormal];
[blockButton addTarget:self action:@selector(blockButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
blockButton.frame = CGRectMake(50, CGRectGetMaxY(delegateButton.frame) + 30, 200, 30);
[view addSubview:blockButton];
_blockLabel = [[UILabel alloc] init];
[_blockLabel setBackgroundColor:[UIColor lightGrayColor]];
[_blockLabel setTextColor:[UIColor whiteColor]];
[_blockLabel setFont:[UIFont systemFontOfSize:15]];
_blockLabel.textAlignment = NSTextAlignmentCenter;
_blockLabel.frame = CGRectMake(CGRectGetMaxX(blockButton.frame) + 5, CGRectGetMinY(blockButton.frame), 150, 30);
[view addSubview:_blockLabel];
//notification button
UIButton *notificationButton = [[UIButton alloc] init];
[notificationButton setBackgroundColor:[UIColor lightGrayColor]];
[notificationButton setTitle:@"next VC (notification)" forState:UIControlStateNormal];
[notificationButton addTarget:self action:@selector(notificationButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
notificationButton.frame = CGRectMake(50, CGRectGetMaxY(blockButton.frame) + 30, 200, 30);
[view addSubview:notificationButton];
_notificationLabel = [[UILabel alloc] init];
[_notificationLabel setBackgroundColor:[UIColor lightGrayColor]];
[_notificationLabel setTextColor:[UIColor whiteColor]];
[_notificationLabel setFont:[UIFont systemFontOfSize:15]];
_notificationLabel.textAlignment = NSTextAlignmentCenter;
_notificationLabel.frame = CGRectMake(CGRectGetMaxX(notificationButton.frame) + 5, CGRectGetMinY(notificationButton.frame), 150, 30);
[view addSubview:_notificationLabel];
//mediator button:
UIButton *mediatorButton = [[UIButton alloc] init];
[mediatorButton setBackgroundColor:[UIColor lightGrayColor]];
[mediatorButton setTitle:@"next VC (mediator)" forState:UIControlStateNormal];
[mediatorButton addTarget:self action:@selector(mediatorButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
mediatorButton.frame = CGRectMake(50, CGRectGetMaxY(notificationButton.frame) + 30, 200, 30);
[view addSubview:mediatorButton];
_mediatorLabel = [[UILabel alloc] init];
[_mediatorLabel setBackgroundColor:[UIColor lightGrayColor]];
[_mediatorLabel setTextColor:[UIColor whiteColor]];
[_mediatorLabel setFont:[UIFont systemFontOfSize:15]];
_mediatorLabel.textAlignment = NSTextAlignmentCenter;
_mediatorLabel.frame = CGRectMake(CGRectGetMaxX(mediatorButton.frame) + 5, CGRectGetMinY(mediatorButton.frame), 150, 30);
[view addSubview:_mediatorLabel];
}
#pragma mark - button
- (void)propertyButtonClicked:(id)sender
{
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] init];
viewControllerB.property1 = @"via Property value";
[self.navigationController pushViewController:viewControllerB animated:YES];
}
- (void)initializerButtonClicked:(id)sender
{
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] initWithProperty1:@"via Initializer value"];
[self.navigationController pushViewController:viewControllerB animated:YES];
}
- (void)delegateButtonClicked:(id)sender
{
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] init];
viewControllerB.delegate = self;
[self.navigationController pushViewController:viewControllerB animated:YES];
}
- (void)mediatorButtonClicked:(id)sender {
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] initWithMediator];
[self.navigationController pushViewController:viewControllerB animated:YES];
}
#pragma mark - block - initializer 方法
//- (void)blockButtonClicked:(id)sender {
// TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] initWithDataBlock:^(NSString *data) {
// _blockLabel.text = data;
// }];
// [self.navigationController pushViewController:viewControllerB animated:YES];
//}
#pragma mark - block - 定义 @porperty 属性方法
- (void)blockButtonClicked:(id)sender {
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] init];
viewControllerB.dataBlock = ^(NSString *data) {
_blockLabel.text = data;
};
[self.navigationController pushViewController:viewControllerB animated:YES];
}
#pragma mark - delegate
- (void)testViewControllerB:(TestViewControllerB *)testViewControllerB sendDataBack:(NSString *)data {
_delegateLabel.text = data;
}
#pragma mark - 点击通知按钮进入 控制器B 页面的方法
- (void)notificationButtonClicked:(id)sender
{
TestViewControllerB *viewControllerB = [[TestViewControllerB alloc] initWithNotification];
//添加 self(viewControllerA) 为通知(TestViewControllerBNotification)这个通知的观察者:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notificationReceived:) name:TestViewControllerBNotification object:nil];
[self.navigationController pushViewController:viewControllerB animated:YES];
}
#pragma mark - A界面接收到通知后的方法
/**
接收到通知中心发给A控制器的通知之后 , A界面要做的事情!!!
在此之前 , 界面B 已经 POST 通知到了 NSNotificationCenter 并且给通知中心带去了一个userInfo的参数值里面放的是字典:@{@"data" : @"notification data"} .
下面这个方法的 形参:notification 就是装着这个字典的从B页面传给通知中心 , 通知中心又传给A页面的通知 , 这里面就装着字典@{@"data" : @"notification data"}
通知里的userInfo就是我在post这个通知的时候最后带的userInfo参数;
*/
- (void)notificationReceived:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
if ([userInfo isKindOfClass:[NSDictionary class]])
{
//显示在通知的label上:
_notificationLabel.text = userInfo[@"data"];
}
}
#pragma mark - viewDidAppear:
//在图像再次显示的时候刷新UI:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (_mediatorLabel) {
//一旦控制器给B赋值完成 , 返回到A的时候我就拿到AppDelegate的shareString这个字符串 , 然后显示它:
_mediatorLabel.text = ((AppDelegate *)[UIApplication sharedApplication].delegate).sharedString;
}
}
@end
TestViewControllerB.h
#import <UIKit/UIKit.h>
@class TestViewControllerB;
FOUNDATION_EXTERN NSString *const TestViewControllerBNotification;
typedef void(^DataBlock) (NSString * data);
@protocol TestViewControllerBDelegate <NSObject>
- (void)testViewControllerB:(TestViewControllerB *)testViewControllerB sendDataBack:(NSString *)data;
@end
@interface TestViewControllerB : UIViewController
-(instancetype)initWithProperty1:(NSString *)property1Value;
-(instancetype)initWithDataBlock:(DataBlock)dataBlock;//block也可以定义出一个initializer方法出来;
@property (nonatomic, copy) DataBlock dataBlock;//block也可以定义一个变量出来;
-(instancetype)initWithNotification;
@property (nonatomic, retain) NSString *property1;
@property (nonatomic, weak) id<TestViewControllerBDelegate> delegate;
- (instancetype)initWithMediator;//中间媒介 , 让 VCA 与 VCB 相互传值;
@end
TestViewControllerB.m
#import "TestViewControllerB.h"
#import "AppDelegate.h"
//定义通知名称:
NSString *const TestViewControllerBNotification = @"TestViewControllerBNotification";
@interface TestViewControllerB () {
DataBlock _dataBlock;
BOOL _useNotification;
BOOL _userMediator;
}
@end
@implementation TestViewControllerB
#pragma mark - init
- (instancetype)init
{
self = [super init];
if (self)
{
[self.navigationItem setTitle:@"ViewController B"];
self.edgesForExtendedLayout = UIRectEdgeNone;
}
return self;
}
#pragma mark - 正向传值initializer方法
- (instancetype)initWithProperty1:(NSString *)property1Value
{
self = [self init];
if (self)
{
self.property1 = property1Value;
}
return self;
}
#pragma mark - 反向传值 block 的 initializer 方法
- (instancetype)initWithDataBlock:(DataBlock)dataBlock
{
self = [self init];
if (self) {
_dataBlock = dataBlock;
}
return self;
}
- (instancetype)initWithNotification
{
self = [self init];
if (self) {
_useNotification = YES;
}
return self;
}
- (instancetype)initWithMediator {
self = [self init];
if (self) {
_userMediator = YES;
}
return self;
}
- (void)loadView
{
UIView *view = [[UIView alloc] init];
view.backgroundColor = [UIColor whiteColor];
self.view = view;
//label:正向传值的 label;
UILabel *label = [[UILabel alloc] init];
[label setBackgroundColor:[UIColor lightGrayColor]];
[label setTextColor:[UIColor whiteColor]];
[label setFont:[UIFont systemFontOfSize:15]];
[label setTextAlignment:NSTextAlignmentCenter];
[label setFrame:CGRectMake(50, 50, 200, 30)];
[view addSubview:label];
label.text = self.property1;
#pragma mark - 代理 UI
if (_delegate)
{
UIButton *notifyDelegateButton = [[UIButton alloc] init];
[notifyDelegateButton setBackgroundColor:[UIColor lightGrayColor]];
[notifyDelegateButton setTitle:@"notify delegate" forState:UIControlStateNormal];
[notifyDelegateButton addTarget:self action:@selector(notifyDelegateButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
notifyDelegateButton.frame = CGRectMake(50, 50, 200, 30);
[view addSubview:notifyDelegateButton];
}
#pragma mark - Block UI
else if (_dataBlock)
{
UIButton *blockButton = [[UIButton alloc] init];
[blockButton setBackgroundColor:[UIColor lightGrayColor]];
[blockButton setTitle:@"notify block" forState:UIControlStateNormal];
[blockButton addTarget:self action:@selector(blockButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
blockButton.frame = CGRectMake(50, 50, 200, 30);
[view addSubview:blockButton];
}
#pragma mark - 通知 UI
else if (_useNotification)
{
UIButton *notificationButton = [[UIButton alloc] init];
[notificationButton setBackgroundColor:[UIColor lightGrayColor]];
[notificationButton setTitle:@"notify notification" forState:UIControlStateNormal];
[notificationButton addTarget:self action:@selector(notificationButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
notificationButton.frame = CGRectMake(50, 50, 200, 30);
[view addSubview:notificationButton];
}
#pragma mark - Mediator UI
else if (_userMediator) {
UIButton *mediatorButton = [[UIButton alloc] init];
[mediatorButton setBackgroundColor:[UIColor lightGrayColor]];
[mediatorButton setTitle:@"notify mediator" forState:UIControlStateNormal];
[mediatorButton addTarget:self action:@selector(mediatorButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
mediatorButton.frame = CGRectMake(50, 50, 200, 30);
[view addSubview:mediatorButton];
}
}
#pragma mark - 点击代理按钮
- (void)notifyDelegateButtonClicked:(id)sender {
if ([_delegate respondsToSelector:@selector(testViewControllerB:sendDataBack:)])
{
[_delegate testViewControllerB:self sendDataBack:@"notify delegate"];
}
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - 点击 block 按钮
- (void)blockButtonClicked:(id)sender {
if (_dataBlock) {
_dataBlock(@"notify Block");
}
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - 点击 通知 按钮
- (void)notificationButtonClicked:(id)sender {
//所需要传递的值放在 userInfo 里:
[[NSNotificationCenter defaultCenter] postNotificationName:TestViewControllerBNotification object:nil userInfo:@{@"data" : @"notification data"}];
[self.navigationController popViewControllerAnimated:YES];
}
#pragma mark - 点击 Mediator 按钮
//更改AppDelegate里的sharedString:
- (void)mediatorButtonClicked:(id)sender {
((AppDelegate *)[UIApplication sharedApplication].delegate).sharedString = @"shared mediator";
[self.navigationController popViewControllerAnimated:YES];
}
@end