he logrado resolver el problema de esta manera:
En primer lugar, añadir una categoría para UIView con el siguiente método:
// 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;
}
Luego, en su opinión, comprobar si la ventana de la propiedad se establece:
-(void)didMoveToWindow
{
if(self.window != nil)
[self observeSuperviewsOnOffsetChange];
else
[self removeAsSuperviewObserver];
}
Si se establece, observaremos el "contentOffset" de cada supervista sobre cualquier cambio. Si la ventana es nula, dejaremos de observar. Puede cambiar el keyPath a cualquier otra propiedad, tal vez "marco" si no hay UIScrollView en sus superviews:
-(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) { }
}
}
Ahora implementar el "observeValueForKeyPath" -method:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"contentOffset"])
{
[self checkIfFrameIsVisible];
}
}
Por último, comprobar si el marco de la vista es visible dentro del marco de la ventana:
-(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
}
}
La navegación de mi aplicación se basa en desplazar un UIScrollView horizontalmente. También estoy interceptando toques a través de una ventana UI subclasificada. El ViewController de la vista actualmente visible por lo tanto necesita registrarse como delegado a la ventana de UI subclasificada. Y esta es la razón por la que deseo recibir una notificación si una vista se vuelve visible. –