Ich habe es geschaffen, das Problem auf diese Weise zu lösen:
Fügen Sie zunächst eine Kategorie für UIView mit folgenden Methode:
// 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;
}
in Ihrer View Dann prüfen, ob die Fenster-Eigenschaft gesetzt ist:
-(void)didMoveToWindow
{
if(self.window != nil)
[self observeSuperviewsOnOffsetChange];
else
[self removeAsSuperviewObserver];
}
Wenn es gesetzt ist, werden wir die „content~~POS=TRUNC“ jeder Superview auf jede Veränderung beobachten. Wenn das Fenster leer ist, hören wir auf zu beobachten. Sie können die keyPath jede andere Eigenschaft ändern, vielleicht "Rahmen", wenn es keine UIScrollView in Ihrem superviews ist:
-(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) { }
}
}
nun die "observeValueForKeyPath" -Methode implementieren:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if([keyPath isEqualToString:@"contentOffset"])
{
[self checkIfFrameIsVisible];
}
}
Schließlich prüfen, ob der Rahmen ist der Ansicht, innerhalb des Fensters Rahmen sichtbar:
-(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
}
}
Die Navigation meiner App basiert ein UIScrollView horizontal auf scrollen. Ich halte auch Berührungen über ein unterklassiertes UIWindow ab. Der ViewController der aktuell sichtbaren Ansicht muss sich daher selbst als Delegierter für das untergeordnete UIWindow registrieren. Und das ist der Grund, warum ich benachrichtigt werden soll, wenn eine Ansicht sichtbar wird. –