2012-06-01 3 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 по позиции или размеру представления, вам обычно лучше соблюдать границы или центр, а не свойство кадра. Свойство frame будет только запускать уведомления KVO, если вы измените его напрямую. –

ответ

1

Убедитесь, что ваш IBOutlet подключен правильно, возможно, идентификатор tableIndicator указывает на нуль. Рассмотрите этот простой код ниже, он работает. Он просто создает окно, добавляет к нему красный квадрат, а затем регистрирует с помощью 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

Смежные вопросы