首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >当UIView变得可见时,如何收到通知?

当UIView变得可见时,如何收到通知?
EN

Stack Overflow用户
提问于 2010-03-16 18:12:37
回答 4查看 16.6K关注 0票数 24

有没有办法在UIView对用户可见时获得通知、回调或其他方法来调用方法,例如,当UIScrollview是某个UIViews的superview时,当该ViewController的视图现在对用户可见时,应该通知此类UIView的superview?

我知道检查ScrollView滚动到哪个位置(通过UIScrollViewDelegate-methods)并计算其中一个子视图是否可见的可能解决方案,但不是很优雅的解决方案……

但我正在寻找一种更通用的方式来做这件事。

EN

回答 4

Stack Overflow用户

发布于 2013-06-19 21:38:37

我设法用这种方式解决了这个问题:

首先,为UIView添加一个类别,方法如下:

// retrieve an array containing all super views

-(NSArray *)getAllSuperviews
{
    NSMutableArray *superviews = [[NSMutableArray alloc] init];

    if(self.superview == nil) return nil;

    [superviews addObject:self.superview];
    [superviews addObjectsFromArray:[self.superview getAllSuperviews]];

    return superviews;
}

然后,在视图中,检查是否设置了window-property:

-(void)didMoveToWindow
{
    if(self.window != nil)
        [self observeSuperviewsOnOffsetChange];
    else
        [self removeAsSuperviewObserver];
}

如果设置了它,我们将观察到每个superview的"contentOffset“。如果窗口为零,我们将停止观察。您可以将keyPath更改为任何其他属性,如果您的超级视图中没有UIScrollView,则可以更改为"frame“:

-(void)observeSuperviewsOnOffsetChange
{
    NSArray *superviews = [self getAllSuperviews];
    for (UIView *superview in superviews)
    {
        if([superview respondsToSelector:@selector(contentOffset)])
            [superview addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
    }
}

-(void)removeAsSuperviewObserver
{
    NSArray *superviews = [self getAllSuperviews];
    for (UIView *superview in superviews)
    {
        @try
        {
            [superview removeObserver:self forKeyPath:@"contentOffset"];
        }
        @catch(id exception) { }
    }
}

现在实现"observeValueForKeyPath"-method:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if([keyPath isEqualToString:@"contentOffset"])
    {
        [self checkIfFrameIsVisible];
    }
}

最后,检查视图的框架在窗口框架内是否可见:

-(void)checkIfFrameIsVisible
{
    CGRect myFrameToWindow = [self.window convertRect:self.frame fromView:self];
    if(myFrameToWindow.size.width == 0 || myFrameToWindow.size.height == 0) return;
    if(CGRectContainsRect(self.window.frame, myFrameToWindow))
    {
        // We are visible, do stuff now
    }
}
票数 9
EN

Stack Overflow用户

发布于 2010-03-16 21:49:38

如果你的视图表现出行为,它应该在视图控制器中。在视图控制器上,每次出现视图时都会调用viewDidAppear方法。

- (void)viewDidAppear:(BOOL)animated
票数 7
EN

Stack Overflow用户

发布于 2010-07-22 15:23:30

我不认为有一种通用的方法来实现视图。听起来像是您被scrollViewDidEndScrolling和其他ScrollViewDelegate方法卡住了。但我不明白你为什么说它很优雅,它们很简单。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2453457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档