1

是)我有的:

当我移动 aUIView时,我通过执行以下操作来检测它的移动:

[myView.layer addObserver:self forKeyPath:@"position" options:NSKeyValueObservingOptionNew context:nil];

作为我正在移动myView的班级,我必须检测到不同的位置。UIViewselfUIView

问题:

当我放入myView另一个UIView并移动时anotherView

[anotherView addSubview: myView];

方法:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

不再被调用,尽管理论上myView也是移动的。NSNotification每次发生“运动”时,我都尝试使用被解雇,但我发现它很笨拙。这类问题有“优雅”的解决方案吗?


对于UIView我正在使用这种方法的运动:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
4

2 回答 2

2

我在这里上传了一个示例项目,它可以干净地做到这一点:

https://github.com/n9986/ObservingUIViewMovement

我曾经有过类似的要求。这里的问题是,当您将 UIView 添加到另一个 UIView(称为 superView)时,它现在驻留在 superView 的坐标空间中。因此,superView 在其父坐标空间中的移动不会影响其子视图。

我将在这里稍微解释一下代码。

我们有ViewController,MyViewInsideView类来说明您的典型类。我想在 viewController 中观察 InsideView 是否移动了。所以在自定义类中,我添加了一个属性positionInWindow,并在 superView 移动时更新它。

所以在InsideView.m

// Make sure this property exists in .h file to make the class KVC compliant
@synthesize positionInWindow;

// This method is called when the super view changes.
- (void)didMoveToSuperview
{
    // Drop a random log message
    NSLog(@"MAI SUPERVIEW HAS CHANGED!!!");

    // Start observing superview's frame
    [self addObserver:self 
           forKeyPath:@"superview.frame" 
              options: NSKeyValueObservingOptionNew 
              context:nil];
}

- (void)observeValueForKeyPath:(NSString *)keyPath 
                      ofObject:(id)object 
                        change:(NSDictionary *)change 
                       context:(void *)context
{
    // Here we update the positionInWindow because 
    // we know the superView.frame has changed
    CGPoint frameOrigin = self.frame.origin;
    [self setPositionInWindow:[[self window] convertPoint:frameOrigin
                                                 fromView:self]];
}

以及您想要监控此视图的任何地方:

// On an instance of InsideView
[insideView addObserver:self 
             forKeyPath:@"positionInWindow" 
                options:NSKeyValueObservingOptionNew 
                context:nil];

这个解决方案的好处是InsideView不需要知道它是谁superView。即使superView稍后更改,此代码也将起作用。类没有修改MyView。并且任何类都可以独立于该事实来监视它的属性。

于 2012-09-06T10:55:11.783 回答
1

据我所知,UIView 不会“自行”移动,这意味着您可能有一些用于移动的代码

也许尝试在那里设置一些委托或通知,而不是使用 addObserver:

于 2012-09-05T14:53:01.953 回答