检测UIView在另一个UIView中的移动

时间:2012-09-05 14:48:04

标签: ios xcode uiview key-value-observing

我有什么:

当我移动UIView时,我通过执行以下操作来检测其移动:

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

myView UIView我正在移动self一个班级我必须检测UIView所拥有的不同位置。

问题:

当我将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;

2 个答案:

答案 0 :(得分:2)

我已经上传了一个示例项目,干净利落地完成了这项工作:

https://github.com/n9986/ObservingUIViewMovement

有时候我有类似的要求。这里的问题是当你将UIView添加到另一个UIView(称之为superView)时,它现在位于superView的坐标空间中。因此,superView在其父级坐标空间中的移动不会影响它的子级。

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

我们有ViewControllerMyViewInsideView个类来说明您的典型课程。我想在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类没有修改。并且任何类都可以独立于该事实来监视它的属性。

答案 1 :(得分:1)

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

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