[ios] UIRefreshControl-UITableViewController가 UINavigationController 내부에있을 때 beginRefreshing이 작동하지 않음

내 UITableViewController (UINavigationController 내부에 있음)에 UIRefreshControl을 설정했으며 예상대로 작동합니다 (즉, 풀다운으로 올바른 이벤트가 발생 함). 그러나 beginRefreshing다음과 같이 새로 고침 컨트롤 에서 인스턴스 메서드를 프로그래밍 방식으로 호출하면

[self.refreshControl beginRefreshing];

아무 반응이 없습니다. 아래로 애니메이션되고 스피너가 표시되어야합니다. endRefreshing내가 새로 고침 후 그를 호출 할 때 방법은 제대로 작동합니다.

이 동작으로 기본 프로토 타입 프로젝트를 채찍질했으며 UITableViewController가 애플리케이션 델리게이트의 루트 뷰 컨트롤러에 직접 추가 될 때 제대로 작동합니다. 예 :

self.viewController = tableViewController;
self.window.rootViewController = self.viewController;

그러나 tableViewController먼저 UINavigationController에를 추가 한 다음 탐색 컨트롤러를으로 추가 rootViewController하면 beginRefreshing메서드가 더 이상 작동하지 않습니다. 예

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;

내 느낌은 이것이 새로 고침 컨트롤과 잘 어울리지 않는 탐색 컨트롤러 내의 중첩 된 뷰 계층과 관련이 있다는 것입니다-제안 사항이 있습니까?

감사



답변

프로그래밍 방식으로 새로 고침을 시작하면 contentoffset을 변경하여 테이블보기를 직접 스크롤해야하는 것 같습니다.

[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];

그 이유는 사용자가 테이블보기의 중간 / 하단에있을 때 새로 고침 컨트롤로 스크롤하는 것이 바람직하지 않을 수 있기 때문이라고 생각합니다.

@muhasturk의 Swift 2.2 버전

self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)

간단히 말해서,이 휴대 성을 유지하려면이 확장을 추가하십시오.

UIRefreshControl + ProgramaticallyBeginRefresh.swift

extension UIRefreshControl {
    func programaticallyBeginRefreshing(in tableView: UITableView) {
        beginRefreshing()
        let offsetPoint = CGPoint.init(x: 0, y: -frame.size.height)
        tableView.setContentOffset(offsetPoint, animated: true)
    }
}


답변

UITableViewController는 iOS 7 이후 자동으로 AdjustsScrollViewInsets 속성을 갖습니다. 테이블보기에는 이미 contentOffset (일반적으로 0, -64)이있을 수 있습니다.

따라서 프로그래밍 방식으로 새로 고침을 시작한 후 refreshControl을 표시하는 올바른 방법은 기존 contentOffset에 refreshControl의 높이를 추가하는 것입니다.

 [self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];


답변

다음은 위에서 설명한 전략을 사용하는 Swift 확장입니다.

extension UIRefreshControl {
    func beginRefreshingManually() {
        if let scrollView = superview as? UIScrollView {
            scrollView.setContentOffset(CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height), animated: true)
        }
        beginRefreshing()
    }
}


답변

다른 답변 중 어느 것도 나를 위해 일하지 않았습니다. 스피너가 표시되고 회전하도록하지만 새로 고침 동작 자체는 발생하지 않습니다. 이것은 작동합니다 :

id target = self;
SEL selector = @selector(example);
// Assuming at some point prior to triggering the refresh, you call the following line:
[self.refreshControl addTarget:target action:selector forControlEvents:UIControlEventValueChanged];

// This line makes the spinner start spinning
[self.refreshControl beginRefreshing];
// This line makes the spinner visible by pushing the table view/collection view down
[self.tableView setContentOffset:CGPointMake(0, -1.0f * self.refreshControl.frame.size.height) animated:YES];
// This line is what actually triggers the refresh action/selector
[self.refreshControl sendActionsForControlEvents:UIControlEventValueChanged];

이 예제는 테이블보기를 사용하지만 콜렉션보기 일 수도 있습니다.


답변

이미 언급 한 접근 방식 :

[self.refreshControl beginRefreshing];
 [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];

스피너를 볼 수 있습니다. 그러나 그것은 움직이지 않을 것입니다. 내가 변경 한 한 가지는이 두 가지 방법의 순서이며 모든 것이 작동했습니다.

[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl beginRefreshing];


답변

Swift 4 / 4.1의 경우

기존 답변의 혼합이 나를 위해 일합니다.

refreshControl.beginRefreshing()
tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)

도움이 되었기를 바랍니다!


답변

이 질문도 참조

beginRefreshing을 호출하고 contentOffset이 0 일 때 UIRefreshControl이 가시적으로 표시되지 않음

tableView의 contentOffset 속성이 0 일 때만 발생하기 때문에 버그처럼 보입니다.

다음 코드 (UITableViewController 메서드)로 수정했습니다.

- (void)beginRefreshingTableView {

    [self.refreshControl beginRefreshing];

    if (self.tableView.contentOffset.y == 0) {

        [UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){

            self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);

        } completion:^(BOOL finished){

        }];

    }
}