0
votes

I have a UITableView, that on the delegate of the UIViewController that adds a new item, inserts the row. The row gets correctly inserted.

However, the UIRefreshControl on the UITableView will not go away when dragging the UITableView after that.

extension FeedViewController: AddPostDelegate {
    func didAddPost(_ userPost: UserPost) {
        self.postsWrapper?.posts.insert(PostWrapper(type: PostType.user(userPost)), at: 0)
        self.tableView.beginUpdates()
        self.tableView.insertRows(at: [
            IndexPath(row: 1, section: 0)
            ], with: .automatic)
        self.tableView.endUpdates()
        self.refresher.endRefreshing()//Does nothing
    }
}

In viewDidLoad:

refresher = UIRefreshControl()
tableView.addSubview(refresher)
refresher.addTarget(self, action: #selector(didDragScrollView), for: .valueChanged)
refresher.layer.zPosition = -1//otherwise in front of the header cell when refreshing (iOS 9.2)

If I do not go to another view first than come back before attempting to pull for refresh, it always hangs spinning forever.

EDIT: It looks like the UIRefreshControl is no longer calling the target function AFTER I add a post.

Any ideas on why this may be occurring? How to fix that?

2
Remark unrelated to your question. You're adding refresh control as a subview, and perfectly fine if that's what you need. But in case you're not aware, there is a UITableView (UIScrollView) property refreshControl which can be used out of the box. - Au Ris
@AuRis that is only 10.0 or newer, so for supporting users still, for some reason, below that - then you cannot use that. According to my app's users statistics, there are still about 8% of users on iOS 9 - daredevil1234
@KaylaGalway if you are referring to DispatchQueue.main.async, then yes, I tried that - daredevil1234
@daredevil1234 sure, makes sense if you're still supporting iOS 9. Regarding refresh, are you initiating it with a "pull to refresh" action or do you call refresher.beginRefreshing() somewhere? - Au Ris
@AuRis I am actually pulling to refresh. The refresh works correctly before adding a post, but after adding a post it does not. Based on what im debugging, it looks like the RefreshControl no longer calls its' target function after that - daredevil1234

2 Answers

1
votes

Make sure that beginRefreshing() was not called before the user pulled to refresh. If refreshControl.isRefreshing is true then the selector does not get called upon "pull to refresh".

A simple test:

let refreshControl = UIRefreshControl()

override func viewDidLoad() {
    super.viewDidLoad()

    refreshControl.addTarget(self, action: #selector(ViewController.refreshData), for: .valueChanged)
    tableView.refreshControl = refreshControl
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // sets refreshControl.isRefreshing to true
    // before the user initiates it
    refreshControl.beginRefreshing()
}

Then the user pulls to refresh. Because refreshControl.isRefreshing is true the selector will not get called. If you remove refreshControl.beginRefreshing()in viewDidAppear, the selector will get called:

@objc func refreshData() {
    print("refresh initiated")
    refreshControl.endRefreshing()
}
0
votes

Try assigning your UIRefreshControl into the refreshControl property of UITableView like this:

if #available(iOS 10.0, *) {
    tableView.refreshControl = refresher
} else {
    tableView.addSubview(refresher)
}

Note that this requires iOS 10.0 or higher, but we're soon getting iOS 12.0 so I don't think you should support iOS lower than 10.0