2010-11-24 30 views
1

J'ai une vue. cette vue a une roue au milieu. il prend également en charge les iAds et la rotation automatique. Ainsi, lorsqu'une annonce apparaît en haut ou que l'appareil tourne, la roue se repositionne automatiquement au centre de l'espace ouvert.iOS, KVO: Observer ne parvient pas à suivre la modification de myObject.myCALayer.center

Maintenant, j'ai une classe pour détecter si l'utilisateur fait tourner la roue. Il est dérivé de UIAdvancedGesture, mais pour qu'il fonctionne correctement, il doit connaître le centre de la roue. Qui ne cesse de changer. comment réparer? Je voudrais 'observer' myObject.myCALayer.center, et chaque fois qu'il change, envoyez la nouvelle valeur dans ma classe de traitement de touchinput.

donc je l'ai fait ceci:

- (id) initWithFrame: (CGRect) theFrame 
       target: (id) p_target 
    actionPlayChord: (SEL) p_actionPlayChord 
     actionSettings: (SEL) p_actionSettingsClick 
{ 
    target = p_target; 
    actionPlayChord = p_actionPlayChord; 

    self = [super initWithFrame: theFrame]; 

    if (! self) 
     return nil; 

    CGPoint centre = CGPointMake(theFrame.size.width/2.0, theFrame.size.height/2.0); 

    WheelTouchHandler * wheelTouchHandler = [WheelTouchHandler alloc]; 
    [wheelTouchHandler initWithTarget: self 
         activateAction: @selector(engaged:) 
         moveCWAction: @selector(movedCW:) 
         moveACWAction: @selector(movedACW:) 
    ] ; 

    [self addGestureRecognizer: wheelTouchHandler]; 

    [self setMultipleTouchEnabled: NO]; 


    self.wheel = [Wheel alloc]; 

    NSUserDefaults * prefs = [NSUserDefaults standardUserDefaults]; 
    NSString *symbol = [prefs stringForKey: @"sharpsOrFlats"]; 

    [self.wheel init_rMax: WHEEL_R_MAX 
        rMin: WHEEL_R_MIN 
        rGap01: WHEEL_R_RATIO_GAP_TO_DISC 
        rRatio: WHEEL_R_RATIO_OUTER_TO_INNER 
       sharpsFlats: symbol 
       bitmapSize: theFrame.size 
    ] ; 

    [self.layer addSublayer: [self.wheel wheelLayer] ]; 

    [self.wheel.wheelLayer setPosition: centre ]; 


    [self.layer addSublayer: [self.wheel labelLayer] ]; 
    [self.wheel.labelLayer setPosition: centre ]; 

    // "center" fails too... 
    [self.wheel.wheelLayer addObserver:self forKeyPath:@"position" options:0 context:nil]; 


    return self; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
{ 
    NSLog(@"Changed!"); <-- this line does not get hit - why? 
} 

Cependant, rien ne se connecté. Qu'est-ce que je fais mal? Évidemment, CALayer de la roue se repositionne à l'écran. mais l'observateur ne parvient pas à observer ce changement. Comment réparer?

MISE À JOUR: apparemment il y a un problème avec KVO sur les propriétés CALayer.

J'ai essayé CALayer le sous-classement, comme ceci:

@implementation WatchedLayer

+(BOOL) automaticallyNotifiesObserversForKey: (NSString *) key 
{ 

    //, if key is @"position" return YES, otherwise return [super automatically...] 

    if ([key isEqual: @"position"]) 
     return YES; // doesn't get hit 

    if ([key isEqual: @"center"]) 
     return YES; // <-- gets hit 

    return [super automaticallyNotifiesObserversForKey: key]; 
} 

- (void) setValue: (id) value 
      forKey: (NSString *) key 
{ 
    // method doesn't get hit 


    if ([key isEqual: @"position"]) 
    { 
     NSLog(@"POSHIT"); 
    } 

    [super setValue: value 
      forKey: key]; 
} 

@end 

mais toujours pas de joie

Répondre

4

Certaines propriétés CALayer ne sont pas conformes à la norme KVO. La propriété frame, par exemple, pour CALayer semble être l'une de ces propriétés. J'ai observé avec succès les modifications apportées à la propriété bounds (CGRect) qui est conforme à la norme KVO (au moins dans 10.6).

J'ai également testé la propriété de position et il est conforme à la norme KVO 10.6. Je ne suis pas sûr de 10,5 et iOS cependant.

Il semble qu'il y ait des différences dans les propriétés compatibles KVC/KVO pour CALayer entre 10.5 et 10.6. Plus précisément, les propriétés personnalisées des sous-classes CALayer ne semblent pas être conformes à la norme KVO en 10.5, mais sont conformes en 10.6. Il peut y avoir d'autres différences de conformité KVO entre les propriétés CALayer entre 10.5, 10.6 et iOS.

http://lists.apple.com/archives/cocoa-dev/2008/Dec/msg01141.html

et

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html%23//apple_ref/doc/uid/TP40006082-SW1

-2

Je crois que vous pouvez seulement observer des objets. Les propriétés que vous essayez d'observer sont des structures.

+1

Vous pouvez observer quelques struct car ils sont enveloppés et pris en charge par KVC/KVO. Par exemple, j'ai observé avec succès les modifications de propriété bounds (CGRect) et position (CGPoint) sur CALayer. – Dalmazio