1

내가 KVO에 대해 얻지 못하는 무언가가 있어야합니다. UIScrollView를 스크롤하여 UITableView를 스크롤하려고합니다. 오프셋 번역은 정확하지만 UIScrollView가 스크롤을 마친 후에 UITableView 스크롤이 발생합니다. 여기 KVO가 동시에 작동하지 않아야합니까?

내 관측 코드 :

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context { 

    AILog(@"observeValueForKeyPath:%@ ofObject:%@", keyPath, NSStringFromClass([object class])); 

    static BOOL isObservingContentOffsetChange = NO; 

    if ([keyPath isEqualToString:@"contentOffset"]) { 
     if ([object isEqual:self.scrollView]) { 
      if (isObservingContentOffsetChange) { 
       return; 
      } 
      isObservingContentOffsetChange = YES; 

      CGPoint offset = [[change valueForKey:NSKeyValueChangeNewKey] CGPointValue]; 

      NSDate *offsetDay = [self dayForScrollViewOffset:offset]; 
      if (offsetDay) { 
       AILog(@"offset (%.2f, %.2f)", offset.x, offset.y); 
       AILog(@"offsetDay %@", [df stringFromDate:offsetDay]); 
       NSIndexPath *offsetIndexPath = [self indexPathForDay:offsetDay]; 
       AILog(@"offsetIndexPath (%d, %d)", (int)offsetIndexPath.section, (int)offsetIndexPath.row); 

       if (offsetIndexPath) { 
        CGRect rect = [self.tableView rectForSection:offsetIndexPath.section]; 
        [self.tableView setContentOffset:CGPointMake(0, rect.origin.y) animated:YES]; 
        AILog(@"----------------------------------------------"); 
       } 
      } else { 
       AILog(@"nil offset day"); 
      } 
     } 
     isObservingContentOffsetChange = NO; 
     return; 
    } 
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
} 

그리고 여기이 보여 콘솔 로그가 예상대로 작동된다 :

014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1526.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1520.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1514.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1508.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1503.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1498.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1493.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1488.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Sunday, 19/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (2, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1483.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1479.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1474.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1470.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1466.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1462.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1458.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1454.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1450.50, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> ---------------------------------------------- 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> observeValueForKeyPath:contentOffset ofObject:UIScrollView 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offset (1447.00, 0.00) 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetDay Saturday, 18/10/2014 
2014-10-21 17:44:53 +0000 : BPTimeViewController --> offsetIndexPath (3, 0) 

하지만 jQuery과 스크롤 시작에만 모든 콘텐츠 오프셋을 계산 한 후 UIScrollView가 감속을 끝내면 UIScrollView 대리자 메서드에는 아무 것도 없습니다. 그 이유를 알고 계십니까?

+6

'UIScrollViewDelegate' 메소드를 사용하지 않을 이유가 있습니까? '- scrollViewDidScroll'과 같이, 예를 들면? –

+0

예, 있습니다. 그리고 이것은 요점이 아닙니다. 나는 KVO를 필요로하고 싶다. 그리고 나는이 질문에 또 다른 질문을하지 않았다. 감사. –

+5

은 동기식으로 실행하고 UI를 차단하는 것과 같습니다. – vikingosegundo

답변

4

UITableViewUIScrollView의 하위 클래스입니다. UIScrollView의 스크롤을 애니메이션으로 만들 때 대부분의 다른보기 애니메이션과 달리 CAAnimation을 사용하여 변경 사항을 애니메이션으로 적용하지 않습니다. 대신 타이머를 사용합니다.

문제점을 재현하고 조사 할 수있었습니다. 귀하의 문제는 타이머가 실행 루프의 기본 모드 (kCFRunLoopDefaultMode)에서만 실행되도록 예약되었지만 사용자가 스크롤보기를 끌 때 (그리고 스크롤보기가 끌기 후에 감속 할 때) 실행 루프가 UITrackingRunLoopMode. 따라서 테이블 뷰의 스크롤 타이머는 감속이 끝날 때까지 시작되지 않습니다.

이 문서화하지 (또는 다른 명백한) 다른 실행 루프 모드에서 실행할 수있는 테이블 뷰의 타이머를 얻을 수있는 방법을하지만,이 일 것으로 보인다 :이 아이폰으로 시뮬레이터에 나를 위해 일한

[UIView animateWithDuration:0.2 animations:^{ 
    self.tableView.contentOffset = CGPointMake(0, rect.origin.y); 
}]; 

을 5 (7.0.3) 및 iPhone 6 (8.0).

+1

덧붙여서, 'context' 매개 변수를 사용하여 KVO 메소드를 단순화 할 수 있습니다. [이 답변] (http://stackoverflow.com/a/11917449/77567)을 참조하십시오. –

+0

이와 같이 내용 오프셋을 애니메이션으로 적용하면 셀을 다시 사용할 때 테이블보기에 문제가 발생할 수 있습니다. 이는이 애니메이션 중에 화면의 내용을 "알지 못하기"때문입니다. (셀이 깜박일 수 있습니다.) 왜 애니메이션없이 컨텐츠 오프셋을 설정하지 않습니까? –

+0

대단히 감사합니다. 아주 좋은 설명이고 좋은 해결 방법입니다. 그리고 컨텍스트 제안에 대해서도 감사드립니다. 건배;) –

관련 문제