arn*_*ne_ 22 cocoa-touch uiscrollview uiview
有没有办法获得通知,回调或其他方法来调用方法,只要UIView变得对用户可见,即当UIScrollview是某些UIViews的超级视图时,这样的UIView的ViewController将得到通知它的视图现在对用户可见了吗?
我知道可能的,但不是那么优雅的解决方案,检查ScrollView滚动的位置(通过UIScrollViewDelegate方法)并计算其中一个子视图是否可见...
但我正在寻找更通用的方式这样做.
我已成功解决了这个问题:
首先,使用以下方法为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;
}
Run Code Online (Sandbox Code Playgroud)
然后,在您的视图中,检查是否设置了window-property:
-(void)didMoveToWindow
{
if(self.window != nil)
[self observeSuperviewsOnOffsetChange];
else
[self removeAsSuperviewObserver];
}
Run Code Online (Sandbox Code Playgroud)
如果已设置,我们将在任何更改时观察每个超级视图的"contentOffset".如果窗口为零,我们将停止观察.您可以将keyPath更改为任何其他属性,如果您的超级视图中没有UIScrollView,则可以"框架":
-(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) { }
}
}
Run Code Online (Sandbox Code Playgroud)
现在实现"observeValueForKeyPath" - 方法:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"contentOffset"])
{
[self checkIfFrameIsVisible];
}
}
Run Code Online (Sandbox Code Playgroud)
最后,检查视图的框架是否在窗口框架内可见:
-(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
}
}
Run Code Online (Sandbox Code Playgroud)
如果您的视图表现出行为,则应该在视图控制器中.在视图控制器上,每次出现视图时都会调用viewDidAppear方法.
- (void)viewDidAppear:(BOOL)animated
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14824 次 |
最近记录: |