我試圖通過將屬於UIView
的代碼與屬於UIViewController
的代碼分開來重新組織早期項目。回答一個受歡迎的問題(found here)似乎並沒有解決我需要做的事情,讓我用兩個例子來說明我的問題。使用getters和setters將消息從父UIViewController傳遞給UIView類中的方法?
- 實施例1
這裏setBackground:zone
改變視圖的背景顏色,以指示該應用的各種狀態的方法。方法如下所示當前有效,我想將代碼重定位到它所屬的視圖。
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
}
@end
ViewController.m
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
[self setBackground:zone];
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
- 實施例2
在下面的代碼我試着在CustomView
上使用getter和setter來引用zone
的值ViewController
(適當的爲ViewControllers
在原始項目中已經獲得並且設置爲zone
以改變背景顏色)的值初始化背景顏色。
CustomView.h
CustomView.m
#import "CustomView.h"
@implementation CustomView
- (void)setParent:(UIViewController *)theParent {
parent = theParent;
}
- (int)getSelectedZone {
return selectedZone;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:[UIScreen mainScreen].bounds];
if (self) {
NSLog(@"selectedZone in CustomView is seen as %i", [self getSelectedZone]);
int zone = [self getSelectedZone];
[self setBackground:(int) zone];
}
return self;
}
- (void)setBackground:(int)zone {
switch (zone) {
case 1:
self.view.backgroundColor = [UIColor orangeColor];
break;
case 2:
self.view.backgroundColor = [UIColor cyanColor];
break;
case 3:
self.view.backgroundColor = [UIColor greenColor];
break;
default:
break;
}
}
ViewController.h
#import <UIKit/UIKit.h>
#import "CustomView.h"
@interface ViewController : UIViewController {
int selectedZone;
}
- (void)setSelectedZone:(int)zone;
- (int)getSelectedZone;
ViewController.m
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
int zone = 1; // or 2 or 3;
[self setSelectedZone:(int)zone];
NSLog(@"selectedZone in ViewController is now set to %i", [self getSelectedZone]);
self.view = [[UIView alloc] initWithFrame: [UIScreen mainScreen].bounds];
CustomView *cv = [[CustomView alloc]init];
[self.view addSubview:cv];
}
- (void)setSelectedZone:(int)zone {
selectedZone = zone;
}
- (int)getSelectedZone {
return selectedZone;
}
我可以告訴我的代碼以上不起作用,因爲getSelected:zone
在CustomView
不能引用zone
通過setSelected:zone
在ViewController.
設置,但我不明白爲什麼。
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in ViewController is now set to 1
2017-04-05 07:04:26.126 ZoneIndicator[1865:1270743] selectedZone in CustomView is seen as 0
但an article found here甚至讓我懷疑使用getter和setter方法是否是最好的方法 - 尤其是這樣的:
最大的危險在這裏的是,通過詢問數據從一個對象,你 是隻獲取數據。你沒有得到一個對象 - 不是在大的 意義上。即使您從查詢中收到的東西在結構上是對象 (例如,,一個字符串)它不再是一個對象的語義。 它不再與其所有者對象有任何關聯。只是因爲 你得到了一個字符串,其內容是「紅色」,你不能問字符串 這意味着什麼。它是業主的姓氏嗎?汽車的顏色? 轉速錶的當前狀況?一個對象知道這些事情, 數據沒有。
那麼如何將消息從父UIViewController傳遞給UIView類中的方法?
DANH,感謝您的詳細解釋。這是我在項目中缺少的完美簡單解決方案。我必須考慮「不明智地給視圖一個指向它的視圖控制器的指針(並且更加不明智地稱這個指針爲」parent「)。 – Greg
:-)高興地幫助。命名要點是UIView使用「parent」來引用它出現的視圖,而不是管理它的視圖控制器。保持指針不明智的原因更多的是關於設計傳統,強大的所有權和信息流從*視圖控制器*轉到*視圖,而不是其他方式。意見有時確實需要在該鏈上反向溝通,而通常的做法是「委託」。 – danh