In my tableView I need to have self.tableView.tableFooterView = UIView() otherwise the table scrolls too far down. The problem is if I add this then my pull to refresh UIRefreshControl no longer works. Is there a way to have both?
There's no reason why you can't have both. Have you added the UIRefreshControl in the right way?
Here's working code from a project of mine:
var pullToRefreshControl : UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
self.setFooterView()
self.addPullToRefreshView()
}
private func setFooterView() {
let footerView = UIView()
let footerLabel = UILabel()
footerLabel.text = "Table Footer"
footerLabel.sizeToFit()
footerView.addSubview(footerLabel)
self.tableView.tableFooterView = footerView
}
private func addPullToRefreshView() {
pullToRefreshControl = UIRefreshControl()
pullToRefreshControl.attributedTitle = NSAttributedString(string: "Pull To Refresh")
pullToRefreshControl.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
self.tableView.addSubview(pullToRefreshControl!)
}
Make a Custom Control refresh control for This
Related
I have a scrollable content in my view. I want to add pull to refresh in it. I try to add but action is not triggered.
I tried many couple of ways & re-search also but none of it worked for me. I have iOS 10 as minimum deployment target.
Try1:
let refreshControl = UIRefreshControl()
self.scl_view.alwaysBounceVertical = true
refreshControl.addTarget(self, action: #selector(pullToRefresh(_:)), for: .valueChanged)
scl_view.addSubview(refreshControl)
Try2:
let refreshControl = UIRefreshControl()
self.scl_view.alwaysBounceVertical = true
refreshControl.addTarget(self, action: #selector(pullToRefresh(_:)), for: .valueChanged)
scl_view.refreshControl = refreshControl
//MARK:- Refresh control
#objc func pullToRefresh(_ refreshControl: UIRefreshControl) {
// Update your conntent here
self.setupData()
//refreshControl.endRefreshing()
}
select your tablviewcontroller
goto inspector
find refreshing select enabled
goto document outline and select refresh control
control drag or right click(hold) drag to your controller file and call function on it to refresh data
it is not available on tableview
var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
// Add Refresh Control to collection View
if #available(iOS 10.0, *) {
collectionView.refreshControl = refreshControl
} else {
collectionView.addSubview(refreshControl)
}
refreshControl.tintColor = UIColor(red:0.25, green:0.72, blue:0.85, alpha:1.0)
// Configure Refresh Control
refreshControl.addTarget(self, action: #selector(fetchData(_:)), for: .valueChanged)
}
#objc private func fetchData(_ sender: Any) {
DispatchQueue.main.async {
//Fuction which you want to call
self.refreshControl.endRefreshing()
}
}
Hi in my application I want to add Pull to refresh controller to scrollview.
I write the following code but it don't getting any response.
When ever I scroll the view on that time add target method is not called.
#IBOutlet var scrool: UIScrollView!
var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
// Add refresh control for the Home page scroll view.
self.refreshControl.tintColor = UIColor.appcolor
self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl.addTarget(self, action: #selector(refresh(sender:)), for: UIControl.Event.valueChanged)
self.scrool.isScrollEnabled = true
self.scrool.alwaysBounceVertical = true
scrool.addSubview(refreshControl)
}
#objc func refresh(sender:AnyObject) {
// Code to refresh table view
self.getHomePageApi()
refreshControl.endRefreshing()
}
Hi I resolved this issue when I write this code in viewwillappear() except viewdidload() function it will working fine.
var refreshControl:RefreshControl!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
refreshControl = RefreshControl()
refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
scrool.refreshControl = refreshControl
}
#objc func refresh()
{
// Code to refresh table view
refreshControl.endRefreshing()
self.getHomePageApi()
}
I have a UICollectionView with the regular pull to refresh implementation, but somehow the spinner and the "pull to refresh" text appear above the collection view items;
How can I make it behind the items?
This is how I add the UIRefreshControll to the UICollectionView
let refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Pull down to refresh")
refreshControl.addTarget(self, action: #selector(pullToRefresh), for: UIControlEvents.valueChanged)
collectionView?.refreshControl = refreshControl
The way I figure this out is to change the refreshControll zPosition to be behind every view with the following:
refreshControl.layer.zPosition = -1
Hope this helps anyone further.
Try this :
#IBOutlet weak var collectionView: UICollectionView!
var refresher:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
let refresher = UIRefreshControl()
self.collectionView!.alwaysBounceVertical = true
self.refresher.tintColor = UIColor.red
self.refresher.addTarget(self, action: #selector(loadData), for: .valueChanged)
self.collectionView!.addSubview(refresher)
}
func loadData() {
//code to execute during refresher
.
.
.
stopRefresher() //Call this to stop refresher
}
func stopRefresher() {
self.refresher.endRefreshing()
}
I'm not able to display an activity indicator on top a static table view though I wrote the below code in viewDidLoad.
let activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
tableView.backgroundView = activityIndicatorView
tableView.separatorStyle = UITableViewCellSeparatorStyle.none
self.activityIndicatorView = activityIndicatorView
self.activityIndicatorView.isHidden = false
self.tableView.addSubview(activityIndicatorView)
self.activityIndicatorView.startAnimating()
Instead of adding UIActivityIndicatorView in tableView, add it to inside your main view and call the bringSubview(toFront:) on the main view to to bring the indicatorView to front and you have't set the origin position for your indicatorView set that also.
self.activityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
tableView.separatorStyle = UITableViewCellSeparatorStyle.none
self.activityIndicatorView.isHidden = false
//Add inside your view
self.view.addSubview(activityIndicatorView)
//Set activityIndicatorView origin in the screen
self.activityIndicatorView.center = self.view.center
//Try to bring activityIndicatorView to front
self.view.bringSubview(toFront: activityIndicatorView)
self.activityIndicatorView.startAnimating()
You cant add subview to tableview, Try adding it on Navigation controllers view instead.
like :
self.view.superviewaddSubview(activityIndicatorView);
If you use pull to refresh then implement this code:
var refreshControl: UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl)
}
func refresh(sender:AnyObject) {
tableView.reloadData()
refreshControl.endRefreshing()
}
I used the following code at a UICollectionViewController
override func viewDidLoad() {
self.collectionView!.alwaysBounceVertical = true
let refresher = UIRefreshControl()
refresher.addTarget(self, action: "refreshStream", forControlEvents: .ValueChanged)
refreshControl = refresher
collectionView!.addSubview(refreshControl!)
}
func refreshStream() {
print("refresh")
self.collectionView?.reloadData()
refreshControl?.endRefreshing()
}
Now I need it to work with a UICollectionView inside a UIViewController and I googled for an hour now but can't get it working.
I appreciate any help.
New swift code changed in calling action method you could do rewrite like this
#IBOutlet weak var collectionView: UICollectionView!
var refresher:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
self.refresher = UIRefreshControl()
self.collectionView!.alwaysBounceVertical = true
self.refresher.tintColor = UIColor.red
self.refresher.addTarget(self, action: #selector(loadData), for: .valueChanged)
self.collectionView!.addSubview(refresher)
}
#objc func loadData() {
self.collectionView!.refreshControl.beginRefreshing()
//code to execute during refresher
.
.
.
stopRefresher() //Call this to stop refresher
}
func stopRefresher() {
self.collectionView!.refreshControl.endRefreshing()
}
Swift 5 solution
As #fishspy already mentioned, that's the way to put your collection view inside a view controller, but I'm gonna share also how to connect your refresh control to the collection view in a cleaner way.
Since iOS 10 there's a dedicated property for the refresh control. Apart of that, I'd also recommend to directly initialise your refresh control as a property, declaring it private and doing the following things:
#IBOutlet private weak var collectionView: UICollectionView!
private let refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
refreshControl.addTarget(self, action: #selector(didPullToRefresh(_:)), for: .valueChanged)
collectionView.alwaysBounceVertical = true
collectionView.refreshControl = refreshControl // iOS 10+
}
#objc
private func didPullToRefresh(_ sender: Any) {
// Do you your api calls in here, and then asynchronously remember to stop the
// refreshing when you've got a result (either positive or negative)
refreshControl.endRefreshing()
}
var refreshControl:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
self.refreshControl.addTarget(self, action: #selector(PricingPlansCollectionViewController.reload), for: .valueChanged)
collectionView!.addSubview(refreshControl)
}
func refresh(sender:AnyObject)
{
//DO
}
From the storyboard, you need to link the collection view to the appropriate controller file, using Ctrl + Drag from the collection view object. It needs to be linked via an #IBOutlet.
Also, you should Ctrl + Drag from the collection view to the view controller object on the storyboard and select Data Source and Delegate so that the collection view is correctly linked.
Let me know if this helps or if I have misunderstood your situation.
For me, i had:
func setupCollectionView(){
self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Refreshing content...")
self.refreshControl.addTarget(self, action: #selector(self.reload), for: .valueChanged)
collectionView!.addSubview(refreshControl)
}
It still wasn't working (I believe i had constraints preventing it somehow), so i added:
collectionView.alwaysBounceVertical = true
then all was good. Just in case someone else is facing the same issue.
For a better understanding, the full implementation
#IBOutlet private weak var collectionView: UICollectionView!
let refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionView()
}
func setupCollectionView(){
collectionView.delegate = self
collectionView.dataSource = self
collectionView.alwaysBounceVertical = true
self.refreshControl = UIRefreshControl()
self.refreshControl.attributedTitle = NSAttributedString(string: "Refreshing content...")
self.refreshControl.addTarget(self, action: #selector(self.refresh), for: .valueChanged)
collectionView!.addSubview(refreshControl)
}
#objc func refresh(_ sender:AnyObject) {
//do refreshing stuff
}
private let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(youFunction), for: .valueChanged)
refreshControl.attributedTitle = NSAttributedString(string: "Fetching Data ...", attributes: nil)
DispatchQueue.main.async {
self.refreshControl.endRefreshing()
yourCollectionViewOrTableView.reloadData()
}