代码之家  ›  专栏  ›  技术社区  ›  P i

iOS,KVO:Observer无法跟踪对myObject.myCALayer.center的更改

  •  1
  • P i  · 技术社区  · 14 年前

    我看到了。这个视图中间有一个轮子。它还支持IAD和自动旋转。因此,每当广告弹出顶部,或设备旋转,轮子自动重新定位到开放空间的中心。

    现在我有一个类来检测用户是否在旋转轮子。它源于uiadvancedprocesse,但要使它正确工作,它需要知道车轮的中心。不断变化。如何修复?

    我想“观察”myObject.myCALayer.center,每次它改变时,都会将新值发送到我的touchinput processing类中。

    所以我做到了:

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

    但是,没有任何记录。我做错什么了?显然轮子的加莱尔在屏幕上重新定位。但是观察者没有观察到这种变化。如何修复?

    更新: 显然,KVO在CALayer属性上存在一些问题。

    我尝试过将CALayer子类化,如下所示:

    @实现监视层

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

    但仍然没有快乐

    2 回复  |  直到 14 年前
        1
  •  4
  •   Dalmazio    13 年前

    有些CALayer属性不符合KVO。例如,CALayer的frame属性似乎是这些属性之一。我已经成功地观察到了bounds属性(CGRect)的更改,它是KVO兼容的(至少在10.6中)。

    我还测试了position属性,它在10.6上符合KVO。但我不确定10.5和iOS。

    CALayer的KVC/KVO兼容属性在10.5和10.6之间似乎存在差异。具体来说,CALayer子类的自定义属性在10.5中似乎不符合KVO,但在10.6中符合KVO。CALayer属性在10.5、10.6和iOS之间可能存在其他KVO遵从性差异。

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

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

        2
  •  -2
  •   Matthew    13 年前

    我相信你只能观察物体。您试图观察的属性是结构。