objective-c - 沒有UITableViewController的UIRefreshControl





ios ios6 (11)


這是另一個有點不同的解決方案。

我必須使用它,因為我有一些視圖層次結構問題:我創建了一些功能,需要將視圖傳遞到視圖層次結構中的不同位置,這在使用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;

還有另一種可能的用途:

由於subclassing這種方式將self.view與self.tableView分開,所以現在可以將此UITableViewController用作更多的常規控制器,並將其他子視圖添加到self.view中,而無需向UITableView中添加子視圖,因此可以考慮製作它們直接查看控制器是UITableViewController的子類,而不是具有UITableViewController子元素。

有些事情要注意:

由於我們在不調用super的情況下覆蓋tableView屬性,因此可能需要注意某些事項並在必要時處理。 例如,在我上面的示例中設置tableview不會將tableview添加到self.view,而不會設置您可能想要執行的框架。 另外,在這個實現中,當類被實例化時,沒有給你默認的tableView,這也是你可能考慮添加的東西。 我不在這裡列出,因為這是個案,這個解決方案實際上非常符合凱勒的解決方案。

只是好奇,因為它似乎不可能,但有沒有偷偷摸摸的方式來利用新的iOS 6 UIRefreshControl類而不使用UITableViewController子類?

我經常使用帶有UITableView子視圖的UIViewController ,並且符合UITableViewDataSourceUITableViewDelegate而不是直接使用UITableViewController




對於Swift 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()
}



嘗試這個,

以上解決方案都很好,但tableView.refreshControl只適用於UITableViewController,直到iOS 9.x,並從iOS 10.x開始進入UITableView。

寫在Swift 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)



在tableView重新加載其內容之後,嘗試延遲對refreshControl -endRefresh方法的調用,方法是使用NSObject的-performSelector:withObject:afterDelay:或GCD的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

我測試了它,這也適用於集合視圖。 我注意到一個小至0.01秒的延遲就足夠了:

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



你會嘗試使用你正在使用的ViewController中的容器視圖。 你可以用專用的tableview定義乾淨的UITableViewController子類,並將其放置在ViewController中。




那麼UIRefreshControl是一個UIView子類,所以你可以自己使用它。 我不確定它是如何呈現自己的。 渲染可以簡單地依賴於框架,但它也可以依賴於UIScrollView或UITableViewController。

無論哪種方式,這將是一個比一個優雅的解決方案更多的黑客。 我建議你查看一個可用的第三方克隆或寫你自己的。

ODRefreshControl

SlimeRefresh




事實證明,當你使用帶有UITableView子視圖的UIViewController並且符合UITableViewDataSource和UITableViewDelegate時,你可以使用以下方法:

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



IOS 10 Swift 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閱讀here




將刷新控件添加為子視圖會在節標題上方創建一個空白空間。

相反,我將UITableViewController嵌入到我的UIViewController中,然後將我的tableView屬性更改為指向嵌入的和中提琴! 最小代碼更改。 :-)

腳步:

  1. 在Storyboard中創建一個新的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
    }

    ...
}



Keller的第一個建議會導致iOS 7中的一個奇怪的錯誤,其中在視圖控制器重新出現之後表格的插入增加。 更改為第二個答案,使用uitableviewcontroller,為我解決了一些問題。




斯威夫特3:

    let myFileName = "somefilename"
    let myURL = Bundle.main.url(forResource: myFileName, withExtension: "png") 




objective-c ios uitableview ios6 uirefreshcontrol