2010-11-24 4 views
1

Ich habe eine Ansicht. Diese Ansicht hat ein Rad in der Mitte. Es unterstützt auch iAds und automatische Rotation. Wenn eine Anzeige oben erscheint oder sich das Gerät dreht, positioniert sich das Rad automatisch in der Mitte des Freiraums.iOS, KVO: Beobachter kann die Änderung an myObject.myCALayer.center nicht verfolgen

Jetzt habe ich eine Klasse zu erkennen, ob der Benutzer das Rad dreht. Es stammt von UIAdvancedGesture, aber damit es richtig funktioniert, muss es die Mitte des Rads kennen. Was sich ständig ändert. wie repariert man?

Ich möchte myObject.myCALayer.center beobachten und jedes Mal, wenn es sich ändert, den neuen Wert in meine touchinput-verarbeitende Klasse senden.

so habe ich das getan:

- (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? 
} 

jedoch nichts protokolliert wird. Was mache ich falsch? Offensichtlich positioniert sich der CALayer des Rades auf dem Bildschirm neu. aber der Beobachter beobachtet diese Änderung nicht. Wie repariert man?

UPDATE: anscheinend gibt es ein Problem mit KVO auf CALayer Eigenschaften.

ich versucht habe Subklassen CALayer, wie folgt aus:

@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 

aber noch keine Freude

Antwort

4

Einige der CALayer-Eigenschaften sind nicht KVO-konform. Die Rahmeneigenschaft, beispielsweise für CALayers, scheint eine dieser Eigenschaften zu sein. Ich habe erfolgreich Änderungen an der Eigenschaft bounds (CGRect) beobachtet, die KVO-konform ist (mindestens in 10.6).

Ich habe auch die Position-Eigenschaft getestet und es ist KVO-konform am 10.6. Ich bin nicht sicher über 10.5 und iOS obwohl.

Es scheint Unterschiede zwischen den KVC/KVO-Eigenschaften für CALayers zwischen 10.5 und 10.6 zu geben. Insbesondere scheinen benutzerdefinierte Eigenschaften von CALayer-Unterklassen in 10.5 nicht KVO-kompatibel zu sein, sind aber in 10.6 kompatibel. Zwischen den CALayer-Eigenschaften zwischen 10.5, 10.6 und iOS können möglicherweise andere KVO-Konformitätsunterschiede bestehen.

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

und

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

-2

Ich glaube, nur Objekte beobachten können. Die Eigenschaften, die Sie beobachten möchten, sind Strukturen.

+1

Sie können einige structs beobachten, da sie von KVC/KVO gewickelt und unterstützt. Zum Beispiel habe ich erfolgreich beobachtet, dass Änderungen der Eigenschaften von Begrenzungen (CGRect) und Position (CGPoint) in CALayers geändert wurden. – Dalmazio

Verwandte Themen