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
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