【问题标题】:Detect movement of UIView inside another UIView检测 UIView 在另一个 UIView 中的移动
【发布时间】:2012-09-05 14:48:03
【问题描述】:

我有什么:

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

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

作为myViewUIView 我正在移动和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;

【问题讨论】:

  • 下面发布的解决方案对您有用吗?

标签: ios xcode uiview key-value-observing


【解决方案1】:

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

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 类没有修改。并且任何类都可以独立于该事实来监视它的属性。

【讨论】:

  • 如果 superview.superview.frame 改变了会发生什么?所以这只会检测到直接超级视图的变化,但是层次结构的其余部分呢?
【解决方案2】:

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

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

【讨论】:

  • 在 touchesMoved 中,你在做类似“myView.frame = ...”的事情吗?这就是你所追求的
  • UIView 的移动很好...我只想知道 (KVO) 当UIView 在另一个UIView 内并且它正在移动...
  • 当它进入另一个视图时谁让它移动?
猜你喜欢
  • 1970-01-01
  • 2011-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 2019-04-14
  • 1970-01-01
相关资源
最近更新 更多