How can you change the appearance of the UIRefreshControl to the "raindrop" style?
I looked up the docs and it doesn't seem to have any appearance related options, although it inherits UIView/UIControl.
Also it's not centered in the tableview. I tried to align it by assigning a frame with x=0, but that didn't change it to left align.
Here is what it looks like
And this is my code:
// in class description
var refreshControl: UIRefreshControl!
// in viewDidLoad()
refreshControl = UIRefreshControl()
//refreshControl.frame(CGRectMake(0, 0, 100, 100))
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubView(refreshControl)
func refresh(sender: AnyObject){
println("refreshing")
refreshControl.endRefreshing()
}
You cannot change it to the "raindrop" style. This was appearance of refresh control when Apple introduced it in UIKit (back in iOS 6) but then they switched to the current one. In fact there is almost no customization you can do with the built-in UIRefreshControl - just some basic text styling and color.
If you need more flexible control you either need to lookup 3rd party refresh controls or write something yourself.
Related
Hi in my app I have a stretchy header and I am adding my refresh control like this tableView.addSubview(refreshControll)
But when using it, it is in middle or bottom of my view and not pinned to the top how do I fix this?
Since iOS 10 or iOS 11 UITableView and UICollectionView have gotten their own refresh control option.
var refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(reloadData), for: UIControl.Event.valueChanged)
tableView.refreshControl = refreshControl
You can also look at the Apple documentation about UITableViewController.
From iOS 10 you have two options to add a refresh control to a UIScrollView:
You can add it to the tableView like another refresh control :
tableView.addSubview(refreshControl)
This will show the refreshControl on top of the UITableView, more precisely like if it was added to the tableHeaderView.
The other option, is to use the already included refreshControl in the UIScrollView classes:
tableView.refreshControl = UIRefreshControl()
With this option the UIViewController takes control of where to put the refreshControl, since iOS 10 will move it to the top of the view just above the navigation bar. Check Mail app on the iPhone to see and example.
refreshControl.addTarget(self, action: #selector(refresh( sender:)), for: .valueChanged)
tableView.insertSubview(refreshControl, at: 0)
func refresh(sender: UIRefreshControl) {
sender.beginRefreshing()
// refresh tableview datasource
refresh()
}
To keep a complete design control over my project I am using a static View Controller for my main application window where I superpose labels and buttons over my images.
The issue is obviously that I now need to add a refresh control to the view and since I am not using a Table View I don't have the Enable Refresh option.
Is there any simple trick to implement a pull-to-refresh control or am I forced to reproduce my design to Table View Cells?
I found a solution using a scroll view, here is what I did:
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(doSomething), for: .valueChanged)
scrollView.refreshControl = refreshControl
}
#objc func doSomething(refreshControl: UIRefreshControl) {
print("Hello World!")
refreshControl.endRefreshing()
}
I needed to extand the scroll view height to cover the pull extension at the top and at the bottom. I also added a background image to cover the white area that the pull created.
Now I need to write the code to update the data.
I have trouble hiding refreshControl once a user leaves the ViewController while refreshControl is still visible. I have tried setting it removing it from superView (tableView), replacing it with new one, etc... The issue still remains with tableView when user returns to the screen, top content insets remain from refreshControl before and it leaves a white space on top of tableView and if I do not replace/hide refreshControl, it will be visible at this point.
Any suggestions?
Image: Transition between screens, refreshControl does not hide on viewDidDisappear
Try this one :-
refreshControl.tintColor = .clear
Initialize the refresh control:
lazy var refreshControl: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action:
#selector(ViewController.handleRefresh(_:)),
for: UIControlEvents.valueChanged)
refreshControl.tintColor = UIColor.red
return refreshControl
}()
Handle the refresh and end the refreshing:
func handleRefresh(_ refreshControl: UIRefreshControl) {
self.tableView.reloadData()
refreshControl.endRefreshing()
}
Add the refresh control:
self.tableView.addSubview(self.refreshControl)
When you present the new screen just use .endRefreshing() on your refreshControl.
I have contacted a friend that gave a really nice answer. This was the code that helped me smoothly remove refreshControl in case it was stuck in frozen state on screen:
func forceHideRefreshControl(tableView: UITableView) {
if tableView.contentOffset.y < 0 { // Move tableView to top
tableView.setContentOffset(CGPoint.zero, animated: true)
}
}
Though if view controller hasn't finished loading, it won't have refreshControl visible. For that you'd need to call beginRefreshing() on it again, but I would do it with delay to avoid any animation problems. In any case, I think this was the best solution that actually removed the white spacing on top. I do not know why endRefreshing() did not work, but at least I found another way. Hope this helps anyone! :)
NOTE: However, this solution is tested on stuck/frozen refreshControl only. I do not know what effect it will have if you do not have this problem, but still use this solution for hiding refreshControl.
I have attached headerView to UITableView. And I also want to use pull to refresh with tableview.
I have attached headerview to tableview with this code:
tblView.tableHeaderView = headerView
and used redresh controll as:
var refreshControl: UIRefreshControl!
refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: #selector(self.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
let tableController = UITableViewController()
self.addChildViewController(tableController)
tableController.tableView = self.tblView
tableController.refreshControl = self.refreshControl
Now issue is when I pull down tableview refreshcontrol showing but my header view position also changing with bounce effect. I don't want to change header position when I pulled down I want to display refreshcontrol under header view.
my header view and refreshcontrol is shown in screenshots. I want header view's position static joined with navigation bar but when user scroll up headerview will also have to scroll.
1)adding header view inside uiviewcontroller not to headerview for tableview,
2)you can change the headerframe accord scrollView of the tableView contentoffset,It is a little complex
3) github.com/CoderJackyHuang/StickyUpDownDemo this demo you can learn to solve your problem
I'm experiencing a kind of flicker with my implementation of UIRefreshControl under iOS 8. Every first time I come to the top of my tableView (meaning when the app has just started) I see the flicker shown in the gif below. This does not happen on any subsequent times I come to the top of the tableView until this view is loaded again, so after I did something in another view of the app or restart it altogether.
This is the code in the viewDidLoad() of my application:
let refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
// Doing this here to prevent the UIRefreshControl sometimes looking messed up when waking the app
self.refreshControl.endRefreshing()
updateData()
refreshControl.backgroundColor = UIColor(hue: 0.58, saturation: 1.0, brightness: 0.43, alpha: 1.0)
refreshControl.tintColor = UIColor.whiteColor()
refreshControl.addTarget(self, action: "updateData", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl)
}
The refreshControl is declared outside of the viewDidLoad() function as I want to call the endRefreshing method from within my updateData() function. This seemed like the obvious way of doing that.
I was able to resolve this by changing the following line
tableView.addSubview(refreshControl)
to
tableView.insertSubview(refreshControl, atIndex: 0)
Thanks to this comment: UIRefreshControl without UITableViewController
Change the background color of the UIRefreshControl's parent view to be the same as the background color of the UIRefreshControl.
Something like:
refreshControl.Superview.BackgroundColor = refreshControl.BackgroundColor