2012-06-01 34 views
3

我想了解iOS中的關鍵值觀察,但我認爲我沒有正確地做某件事。 作爲一個想法,我試圖添加一個觀察者到視圖控制器的屬性(與IBOutlet連接的視圖)。這個視圖(tableIndicator)是動畫的,所以我想看看當視圖的框架發生變化時是否可以讓觀察者作出反應。KVO不能用於類屬性

所以我做了以下內容,視圖控制器的viewDidLoad裏面:

[tableInidicator addObserver:self forKeyPath:@"frame" options:0 context:nil]; 

tableIndicator是我的看法/類屬性,我添加默認選項視圖控制器(個體經營)作爲觀察員,0和框架作爲觀察的關鍵值。

然後,我在等待,看看這個功能被觸發爲框架的變化:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 
    NSLog(@"value changed"); 
} 

...但沒有任何反應。

我不一定在尋找解決這個問題的方法,因爲除了我理解它之外,沒有任何其他目的,如果有人能指出我做錯了什麼,我會非常感激。一些很好的例子/教程也會很棒。

我發現的那些(http://iphonedevelopment.blogspot.ro/2009/02/kvo-and-iphone-sdk.html/http://nachbaur.com/blog/back-to-basics-using-kvo)未涵蓋此類情況。他們只是觀察者應用到一個類來觀察它的一個屬性,而不是在一個類內的(自定義)對象的屬性,我認爲這對我來說更有用。

預先感謝您

[編輯] 對於那些誰就會錯過接受的答案我的評論:

更改視圖的中心顯然將不會觸發幀屬性的觀察員。你必須改變框架本身。

+0

據我從你的問題理解是否tableindicator是烏拉圭回合的ViewController,然後去NSNotification,而不是志願 –

+0

我知道如何使用NSNotification。我正在嘗試使用KVO,因此我可以更好地理解這種技術。 – BBog

+2

我知道這是一個很久以前回答的非常古老的問題,但我想爲可能找到它的其他人添加評論。你應該認識到UIKit中一個視圖的「框架」是它是從「邊界」和「中心」中找到的值合成的。如果您想在視圖的位置或大小上執行KVO,通常最好觀察邊界或中心,而不是幀屬性。如果您直接更改框架屬性,它只會觸發KVO通知。 –

回答

1

檢查您的IBOutlet連接是否正確,可能是tableIndicator ivar指向零。 考慮下面這個簡單的代碼,它的工作原理。它只是創建一個窗口,在其上添加一個紅色正方形,然後使用KVO註冊要通知更改幀的對象。最後它會實例化一個按鈕:每次點擊它時,幀的大小都會減小,並且正確觸發通知(您將在調試控制檯中看到該消息)。 所以你必須檢查你的代碼。



#import "AppDelegate.h" 

@implementation AppDelegate 

@synthesize window = _window; 
@synthesize v = _v; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    // Override point for customization after application launch. 
    self.window.backgroundColor = [UIColor whiteColor]; 
    [self.window makeKeyAndVisible]; 

    self.v = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)]; 
    _v.backgroundColor=[UIColor redColor]; 
    [self.window addSubview:_v]; 

    UIButton *b = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    b.frame=CGRectMake(0, 300, 40, 10); 
    [b setTitle:@"A" forState:UIControlStateNormal]; 
    [b addTarget:self action:@selector(changeFrame) forControlEvents:UIControlEventTouchUpInside]; 
    [_window addSubview:b]; 

    [_v addObserver:self forKeyPath:@"frame" options:0 context:NULL]; 

    return YES; 
} 

-(void)changeFrame { 
    CGRect _f = self.v.frame; 
    _f = CGRectInset(_f, 20, 20); 
    _v.frame=_f; 
} 

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { 
    NSLog(@"Observing..."); 
} 
+0

我的視圖控制器和它的視圖正在工作,一切都連接起來。我試圖在完成的項目上實現KVO代碼,所以問題不在那裏。我會看看你的代碼,謝謝! – BBog

+0

我在一個新項目上試過你的代碼,它工作,但不適合我的項目。儘管我確實設法找出了問題,但這是因爲我基本上是在關注視圖的中心而不是其框架。當我強制改變框架時,它起作用了,我被通知了。謝謝 – BBog

2

有一些不完全清楚你的代碼。 tableIndicator是從UIView派生的自定義類嗎?應該在該類中定義方法observeValueForKeyPath,然後調用它。但我不確定這是最好的方法。

一般來說,更健全的方法是將您的控制器(而不是您的視圖)定義爲觀察者。在這種情況下,您可以:

[self addObserver:self forKeyPath:@"view.frame" options:0 context:nil]; 

從控制器內部某處; observeValueForKeyPath也將被定義爲控制器中的方法。

+0

nope,tableIndicator不是一個類,它是一個簡單的UIView,當我滾動一個表時,它移動。你的觀察是非常有價值的,但我真的想知道如何觀察自定義對象的價值。不幸的是,應用你的解決方案似乎沒有工作,這是奇怪的......我甚至嘗試過一個簡單的布爾屬性,我仍然無法得到任何反應。我想我會再讀一些,我肯定在這裏做錯了 – BBog

相關問題