2010-03-16 8 views
19

UIView가 사용자에게 표시 될 때마다 메서드, 즉 UIScrollview가 일부 UIView의 수퍼 뷰일 때마다 메서드를 호출하는 알림, 콜백 또는 다른 방법을 사용할 수 있습니까? 이러한 UIView의 ViewController는 보기가 이제 사용자에게 표시 될 때 알림을 받습니까?UIView가 표시 될 때 어떻게 알림을받을 수 있습니까?

(UIScrollViewDelegate-방법을 통해) 내가 가능한 알고있다, 그러나 체크하지 그래서 우아한 해결책이되는 놓습니다있는 ScrollView를 스크롤하고 파단 중 하나가 표시되는 경우 계산 ...
하지만 찾고 있어요 더 보편적 인 방법으로

+0

내 탐색은 UIScrollView를 가로로 스크롤하는 것을 기반으로합니다. 나는 또한 서브 클래 싱 된 UIWindow를 통해 감청을 가로 채고있다. 따라서 현재 보이는 뷰의 ViewController는 자신을 서브 클래 싱 된 UIWindow에 대한 델리게이트로 등록해야합니다. 그리고 이것이 내가보기가 보일 때 통보 받기를 원하는 이유입니다. –

답변

8

보기가 동작하는 경우보기 컨트롤러 내에 있어야합니다. 뷰 컨트롤러에서 viewDidAppear 메서드는 뷰가 나타날 때마다 호출됩니다. 해당 뷰가 표시 또는

[view.layer visibleRect]; 

하지만,이 밤은 나를 위해 작동하지 않는 경우

- (void)viewDidAppear:(BOOL)animated 
+7

viewDidAppear의 문제는 Navigation Controller를 사용할 때만 호출된다는 것입니다. 내 경우보기가 화면에서 * 스크롤되어 다시 스크롤됩니다. 스크롤이 viewDidAppear을 트리거하지 않는 것 같습니다 .... –

+1

그래서보기가 화면에 스크롤러가 나타나면 무엇을 나타낼 수 있습니까? –

+0

"보기 컨트롤러 내에 있어야합니다." - 뷰 컨트롤러는 전체 화면보기에서만 작동합니다. 때때로 우리는 화면의 일부분 만 다루는 견해를 가지고 있습니다. – Jonny

0

뷰의 레이어 속성은 우리를 말해야한다.

따라서 UiScrollView contentOffset 속성을 사용하여 특정보기가 표시되는지 여부를 계산할 수 있습니다.

+1

그러면 값이 변경 될 때 해고되는 방아쇠를 어떻게 추가합니까? –

+0

나는이 질문에 오래 전부터 대답했다. 심지어 맥락을 잊어 버렸다. UIView를 서브 클래스 화하고 다음 메소드를 사용하십시오. https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/doc/uid/TP40006816-CH3-SW139 –

+0

그게 지금하고있는 일입니다. 나는 외부 수업에서 듣고 싶다. –

1

나는보기를 위해 이것을하는 보편적 인 방법이 없다고 생각합니다. scrollViewDidEndScrolling 및 다른 ScrollViewDelegate 메서드가 붙어있는 것 같습니다. 그러나 나는 당신이 왜 그것이 우아하다고 말합니까, 그들은 아주 간단합니다.

나는이 방법으로 문제를 해결하기 위해 관리했습니다
8

: 윈도우 재산권 있는지 확인,보기에,

// 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; 
} 

다음 :

먼저 다음과 같은 방법으로 UIView에 대한 카테고리를 추가 설정 :이 설정되어있는 경우, 우리가 어떤 변화를 각 수퍼의 "contentOffset"을 준수합니다

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

. 창문이 없으면 관찰을 멈 춥니 다.

-(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 구현 : 당신의 superviews에는있는 UIScrollView가없는 경우 당신은 어떤 다른 재산, 어쩌면 "프레임"에 키 패스를 변경할 수 있습니다 마지막으로

-(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 
    } 
} 
+0

자세한 솔루션을 제공해 주셔서 감사합니다. 나는 그것을 시험해보고 있지만 문제는 관찰자를 제거 할 기회가 있기 전에 superview가 할당 해제되고 있다는 것이다. 나는 심지어 그들의 "superview"키 경로에 대한 변화를 관찰하고 있지만 도움이되지 않습니다. 이것은 분명히 KVO의 최악의 부분입니다. – phatmann

+0

이것은 문제가되지 않습니다. 수퍼 뷰가 할당 해제되면 관찰 뷰 (뷰가 보이는지 알고 싶어하는 뷰)도 서브 뷰이므로 할당 해제되어야합니다. – Thomas

+0

당신 말이 맞아요. 내 문제는 모든 핵심 경로에서'removeObserver'를 호출하지 못했습니다. 즉, KVO 모범 사례는 모든 관찰 된 개체의 소유권을 유지하는 것입니다. 이 경우, 이것은'observeSuperviewsOnOffsetChange'에 의해 생성 된 superviews의리스트를 멤버 변수에 넣고,이 retain 된 superviews리스트를'removeAsSuperviewObserver'에서 사용하는 것을 의미합니다. 또한 약간의 성능 이점이 있습니다. – phatmann

관련 문제