效果圖
效果圖
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