UIRefreshControl - beginRefreshing not working when UITableViewController is inside UINavigationController
It seems that if you start refreshing programmatically, you have to scroll the table view yourself, say, by changing contentoffset
[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
I would guess the reason for this is that it could be undesirable to scroll to the refresh control when user is in the middle/bottom of the table view?
Swift 2.2 version by @muhasturk
self.tableView.setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.size.height), animated: true)
In a nutshell, to keep this portable add this extension
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)
}
}
UIRefreshControl not showing spiny when calling beginRefreshing and contentOffset is 0
It looks like a bug to me, because it only occures when the contentOffset
property of the tableView
is 0
I fixed that with the following code (method for the 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){
}];
}
}
UIRefreshControl does not work
Move tableView.reloadData()
to a place where you can be sure the search()
function has completed and returned results. If that is an async function then add a completion handler so that you know when to call reloadData()
. Then you could call the function like so:
search {
dispatch_async(dispatch_get_main_queue()) {
tableView.reloadData()
}
}
Or, when you're on Swift 3
DispatchQueue.main.async {...}
UIRefreshControl renders behind UINavigation w/ Large Titles
It looks like you are setting the refresh control after the large navigation has been configured.
Try changing the order to something like this -
override func viewDidLoad() {
super.viewDidLoad()
load()
configureTableView()
configureUI()
}
.......
func configureTableView() {
tableView.backgroundColor = .usingHex("fafafa")
tableView.tableFooterView = .init()
tableView.contentInsetAdjustmentBehavior = .always
tableView.refreshControl = .init()
}
func configureUI() {
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.title = "Latest content"
}
Related Topics
iOS Static VS Dynamic Frameworks Clarifications
Set Dimensions for Uiimagepickercontroller "Move and Scale" Cropbox
iOS Nsdate() Returns Incorrect Time
Can't Assign Multiple Buttons to Uinavigationitem When Using Storyboard with iOS 5
Autolayout + Rtl + Uilabel Text Alignment
Storing Asynchronous Cloud Firestore Query Results in Swift
How to Use Uiscrollview in Interface Builder
Class Has No Initializers Swift
How to Change the Font of the Back Button for My Navigation Bar
Prevent Deploying (Disable) Watchkit App with iOS iPhone App in Xcode
Remove Text from Back Button Keeping the Icon
How to Password Protect Writing to Nfc Ntag216 Tag on iOS 13 Using Nfc Core
Implementing Hmac and Sha1 Encryption in Swift
Add Child View Controller to Current View Controller
How to Put the Image on the Right Side of the Text in a Uibutton