Programing

UITableViewController가없는 UIRefreshControl

lottogame 2020. 3. 13. 08:11
반응형

UITableViewController가없는 UIRefreshControl


즉시 궁금하지는 않지만 호기심이 많지만 하위 UIRefreshControl클래스를 사용하지 않고 새로운 iOS 6 클래스 를 활용하는 은밀한 방법이 UITableViewController있습니까?

나는 종종를 사용 UIViewControllerUITableView서브 뷰와 준수 UITableViewDataSource하고 UITableViewDelegate오히려를 사용하는 것보다 UITableViewController철처.


직감하고 DrummerB의 영감에 따라 UIRefreshControl인스턴스를 하위 뷰로 간단히 추가하려고했습니다 UITableView. 그리고 그것은 마술처럼 작동합니다!

UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.myTableView addSubview:refreshControl];

이것은 UIRefreshControl테이블 뷰 위에 위를 추가 하고 UITableViewController:) 을 사용할 필요없이 예상대로 작동합니다.


편집 : 위의 내용은 여전히 ​​작동하지만 몇 가지 지적했듯이 UIRefreshControl 을이 방법으로 추가 할 때 약간의 "말림"이 있습니다. 이에 대한 해결책은 UITableViewController를 인스턴스화 한 다음 UIRefreshControl 및 UITableView를 다음과 같이 설정하는 것입니다.

UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

허용 대답에 의해 발생하는 더듬을 제거하기 위해, 당신은 당신을 할당 할 수 있습니다 UITableViewA를 UITableViewController.

_tableViewController = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
[self addChildViewController:_tableViewController];

_tableViewController.refreshControl = [UIRefreshControl new];
[_tableViewController.refreshControl addTarget:self action:@selector(loadStream) forControlEvents:UIControlEventValueChanged];

_theTableView = _tableViewController.tableView;

편집하다:

더듬 지 않고을 추가 UIRefreshControl하지 UITableViewController않고 테이블 뷰에서 데이터를 새로 고친 후 멋진 애니메이션을 유지하는 방법입니다.

UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.theTableView addSubview:refreshControl];
[self.theTableView sendSubviewToBack:refreshControl];

나중에 새로 고친 데이터를 처리 할 때 ...

- (void)handleRefresh:(UIRefreshControl *)refreshControl {
    [self.theTableView reloadData];
    [self.theTableView layoutIfNeeded];
    [refreshControl endRefreshing];
}

시도하는 것은 사용중인 ViewController 내부의 컨테이너보기를 사용하는 것입니다. 전용 테이블 뷰로 깨끗한 UITableViewController 서브 클래스를 정의하고 ViewController에 배치 할 수 있습니다.


UIRefreshControl은 UIView 하위 클래스이므로 자체적으로 사용할 수 있습니다. 어떻게 렌더링되는지 잘 모르겠습니다. 렌더링은 단순히 프레임에 의존 할 수 있지만 UIScrollView 또는 UITableViewController에 의존 할 수도 있습니다.

어느 쪽이든, 그것은 우아한 솔루션보다 해킹이 될 것입니다. 사용 가능한 타사 복제본 중 하나를 보거나 직접 작성하는 것이 좋습니다.

ODRefreshControl

여기에 이미지 설명을 입력하십시오

슬라임

여기에 이미지 설명을 입력하십시오


-endRefreshNSObject -performSelector:withObject:afterDelay:또는 GCD를 사용하여 tableView가 내용을 다시로드 한 후 새로 고침 컨트롤 메서드에 대한 호출을 1 초 정도 지연하십시오 dispatch_after.

이를 위해 UIRefreshControl에 카테고리를 작성했습니다.

@implementation UIRefreshControl (Delay)

- (void)endRefreshingAfterDelay:(NSTimeInterval)delay {
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self endRefreshing];
    });
}

@end

나는 그것을 테스트했고 이것은 Collection Views에서도 작동합니다. 0.01 초 정도의 지연이 충분하다는 것을 알았습니다.

// My data refresh process here while the refresh control 'isRefreshing'
[self.tableView reloadData];
[self.refreshControl endRefreshingAfterDelay:.01];

iOS 10 스위프트 3.0

간단 해

import UIKit

class ViewControllerA: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet weak var myTableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        myTableView.delegate = self
        myTableView.dataSource = self

        if #available(iOS 10.0, *) {
            let refreshControl = UIRefreshControl()
            let title = NSLocalizedString("PullToRefresh", comment: "Pull to refresh")
            refreshControl.attributedTitle = NSAttributedString(string: title)
            refreshControl.addTarget(self,
                                     action: #selector(refreshOptions(sender:)),
                                     for: .valueChanged)
            myTableView.refreshControl = refreshControl
        }
    }

    @objc private func refreshOptions(sender: UIRefreshControl) {
        // Perform actions to refresh the content
        // ...
        // and then dismiss the control
        sender.endRefreshing()
    }

    // MARK: - Table view data source

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 12
    }


    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)

        cell.textLabel?.text = "Cell \(String(indexPath.row))"
        return cell
    }

}

여기에 이미지 설명을 입력하십시오

iOS 10 UIRefreshControl에 대해 배우려면 여기를 읽으 십시오 .


새로 고치기 제어를 서브 뷰로 추가하면 섹션 헤더 위에 빈 공간이 작성됩니다.

대신 UITableViewController를 UIViewController에 포함시킨 다음 tableView포함 된 속성과 비올라를 가리 키도록 속성을 변경했습니다 ! 최소한의 코드 변경. :-)

단계 :

  1. 스토리 보드에서 새 UITableViewController를 만들고 원래 UIViewController에 포함하십시오.
  2. @IBOutlet weak var tableView: UITableView!아래와 같이 새로 내장 된 UITableViewController의 것으로 교체하십시오.

class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
    weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tableViewController = self.childViewControllers.first as! UITableViewController
        tableView = tableViewController.tableView
        tableView.dataSource = self
        tableView.delegate = self

        // Now we can (properly) add the refresh control
        let refreshControl = UIRefreshControl()
        refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: .ValueChanged)
        tableViewController.refreshControl = refreshControl
    }

    ...
}

스위프트 2.2.

먼저 UIRefreshControl ()을 만드십시오.

var refreshControl : UIRefreshControl!

viewDidLoad () 메소드에서 다음을 추가하십시오.

refreshControl = UIRefreshControl()
    refreshControl.attributedTitle = NSAttributedString(string: "Refreshing..")
    refreshControl.addTarget(self, action: #selector(YourUIViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
    self.tableView.addSubview(refreshControl)

그리고 새로 고침 기능을

func refresh(refreshControl: UIRefreshControl) {

    // do something ...

    // reload tableView
    self.tableView.reloadData()

    // End refreshing
    refreshControl.endRefreshing()
}

조금 다른 또 다른 해결책이 있습니다.

나는 몇 가지보기 계층 문제로 인해 그것을 사용해야했다. 나는 UITableViewController의 tableview b / c를 사용할 때 고장난보기 계층의 다른 곳으로 뷰를 전달 해야하는 기능을 만들고 있었다. tableView는 UITableViewController의 루트보기 ( self.view)는 일반보기뿐만 아니라 일관성없는 컨트롤러 /보기 계층을 생성하여 충돌을 일으켰습니다.

기본적으로 고유 한 UITableViewController 서브 클래스를 작성하고 loadView를 대체하여 self.view에 다른보기를 지정하고 tableView 특성을 대체하여 별도의 tableview를 리턴하십시오.

예를 들면 다음과 같습니다.

@interface MyTableVC : UITableViewController
@end

@interface MyTableVC ()
@property (nonatomic, strong) UITableView *separateTableView;
@end

@implementation MyTableVC

- (void)loadView {
    self.view = [[UIView alloc] initWithFrame:CGRectZero];
}

- (UITableView *)tableView {
    return self.separateTableView;
}

- (void)setTableView:(UITableView *)tableView {
    self.separateTableView = tableView;
}

@end

Keller의 솔루션과 결합하면 tableView는 이제 VC의 루트 뷰가 아닌 일반 뷰이며 뷰 계층 구조 변경에 대해 더 강력하다는 의미에서 더욱 강력 해집니다. 이런 식으로 사용하는 예 :

MyTableVC *tableViewController = [[MyTableVC alloc] init];
tableViewController.tableView = self.myTableView;

self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;

이것을 위해 또 다른 가능한 사용법이 있습니다.

이 방법으로 서브 클래 싱하면 self.view가 self.tableView와 분리되므로 이제이 UITableViewController를 일반 컨트롤러로 사용하고 UITableView에 서브 뷰를 추가 할 필요없이 self.view에 다른 서브 뷰를 추가 할 수 있습니다. UITableViewController 자식을 갖지 않고 직접 컨트롤러를 UITableViewController의 서브 클래스로 봅니다.

주의해야 할 사항 :

super를 호출하지 않고 tableView 속성을 재정의하므로 필요한 경우주의해야 할 사항이 있습니다. 예를 들어, 위의 예제에서 tableview를 설정하면 tableview가 self.view에 추가되지 않고 원하는 프레임을 설정하지 않습니다. 또한이 구현에는 클래스가 인스턴스화 될 때 제공되는 기본 tableView가 없으며 추가 할 수도 있습니다. 경우에 따라 여기에 포함되지 않으며이 솔루션은 실제로 Keller의 솔루션과 잘 맞습니다.


이 시도,

위의 솔루션은 훌륭하지만 iOS 9.x까지 iOSTableViewController에서만 tableView.refreshControl을 사용할 수 있으며 iOS 10.x부터 UITableView로 제공됩니다.

스위프트 3으로 작성-

let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(FeedViewController.loadNewData), for: UIControlEvents.valueChanged)
// Fix for the RefreshControl Not appearing in background
tableView?.addSubview(refreshControl)
tableView.sendSubview(toBack: refreshControl)

Keller의 첫 번째 제안은 iOS 7에서 뷰 컨트롤러가 다시 나타난 후 테이블의 삽입이 증가하는 이상한 버그를 유발합니다. uitableviewcontroller를 사용하여 두 번째 답변으로 변경하면 문제가 해결되었습니다.


UITableView 하위보기와 함께 UIViewController를 사용하고 UITableViewDataSource 및 UITableViewDelegate를 준수 할 때 다음을 사용할 수 있습니다.

self.refreshControl = [[UIRefreshControl alloc]init];
[self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];

참고 URL : https://stackoverflow.com/questions/12497940/uirefreshcontrol-without-uitableviewcontroller

반응형