Refresh animation not displaying when reloading tableview | Swift - swift

I cannot seem to figure out why the loading animation stop appearing after I leave and come back to the UITableViewController the following is what I am seeing once I come back - the pull-down gesture still executes the reload code and refreshes the UITableView, just the animation is not showing.
What I am seeing:
What I am doing:
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl?.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.backgroundColor = .tertiarySystemGroupedBackground
edgesForExtendedLayout = [.top]
extendedLayoutIncludesOpaqueBars = true
}
#objc func refresh(sender:AnyObject)
{
self.fetchJSON()
self.refreshControl?.endRefreshing()
}
Setup in Storyboards:
Is there something I am doing incorrect that would prevent the loader from appearing? To clarify it is showing on initial load, but then fails to appear when return

Try closing your refresh control from the main thread.
DispatchQueue.main.async { self.refreshControl.endRefreshing() }

Related

How to automatically refresh table view in view controller upon entering screen?

I'm able to make use of refreshControl and pull down to manually update the screen, but how can i update it automatically every time i enter the screen without having to pull down.
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
configureRefreshControl()
tableView.refreshControl = refreshControl
}
func configureRefreshControl() {
self.refreshControl.addTarget(self, action: #selector(handleRefreshControl), for: .valueChanged)
self.refreshControl.tintColor = UIColor.white
}
#objc func handleRefreshControl() {
updateCommentsOverview()
}
You can call tableView.reloadData() or updateCommentsOverview() either on viewDidLoad. Which will update once Per screen launch. Or call it on viewWillAppear. Which will cause an update every-time you “see” the screen, meaning even when you come back from the background.
I can only guess you mean to use viewWillAppear.
See - https://developer.apple.com/documentation/uikit/uiviewcontroller/1621510-viewwillappear for more info

refresh controller freeze after changing tap tab bar quickly

I use refresh controller. It works well when I tap the tab bar item after the refresh animation completely end. But if I tap the bar item very quickly before the animation done, it will be freeze. I try to use refreshControl.endRefreshing() in viewDidApper. I try to use refreshControl.endRefreshing() in viewWillDisappear, too. This bug still happen. Below are my code and the snapshot.
snapshot: https://imgur.com/a/UNvQbA8
demo video: https://youtu.be/cZMurwiwfjI
let refreshControl: UIRefreshControl = UIRefreshControl()
#IBOutlet weak var myScrollView: UIScrollView!
#IBOutlet weak var noDataView: UIView!
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UINib.init(nibName: "MessageListCell", bundle: nil), forCellReuseIdentifier: "MessageListCell")
tableView.delegate = self
tableView.dataSource = self
refreshControl.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)
self.tableView.isHidden = true
self.myScrollView.isHidden = false
}
I put refreshControl.endRefreshing() here. It seems no work.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.refreshControl.endRefreshing()
if !oneReload {
getList()
oneReload = true
}
}
I also try to put refreshControl.endRefreshing() before adding the subview. It still no worked.
private func getList(){
if self.viewData.count > 0{
self.tableView.addSubview(self.refreshControl)
self.tableView.isHidden = false
self.myScrollView.isHidden = true
self.tableView.reloadData()
}else{
self.myScrollView.addSubview(self.refreshControl)
self.myScrollView.isHidden = false
self.tableView.isHidden = true
}
}
#objc func refresh(){
refreshControl.endRefreshing()
self.getList()
}
I think this will happen because the view controller been freeze before changing the tabbar selected view. Next time I back to the view.It show with the freeze animation. Can I solve this issue? Please help. Thank you.
Try to put your refresh method on the main thread.
#objc func refresh(){
DispatchQueue.async.main {
refreshControl.endRefreshing()
self.getList()
}
}

Swift UIRefreshControl to UICollectionView inside UIScrollView

I have UICollectioview inside UIScrollView and I want to add UIRefreshControl, but it don't work
private let refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
self.refreshControl.addTarget(self, action: #selector(didPullToRefresh(_:)), for: .valueChanged)
self.folderCollectionView.alwaysBounceVertical = true
self.folderCollectionView.bounces = true
self.refreshControl.tintColor = UIColor.black
self.folderCollectionView.refreshControl = refreshControl
}
#objc
private func didPullToRefresh(_ sender: Any) {
print("123")
getFolder(update: true)
refreshControl.endRefreshing()
}
In getFolder I get data and reload collection
When I run collection don't have pull to update and don't work
What have I done wrong
Add UIRefreshControl to the UICollectionView using this way, see the following code, I hope it helps you.
// Add Refresh Control to Collection View
if #available(iOS 10.0, *) {
folderCollectionView.refreshControl = refreshControl
} else {
folderCollectionView.addSubview(refreshControl)
}

UIRefresh Control UI bug with large titles & collection view

I am using a UICollectionViewController embedded within a UITabBarController & UINavigationController and when I switch between tabs multiple times I am occasionally experiencing a bug where the refresh control appears above the title when I do not want it to.
Refresh Control UI Bug
Debug View Hierachy
var refreshControl: UIRefreshControl = {
let refreshControl = UIRefreshControl()
refreshControl.tintColor = UIColor.primaryRed
return refreshControl
}()
refreshControl.addTarget(self, action: #selector(refreshData), for: .valueChanged)
collectionView?.refreshControl = refreshControl
#objc private func refreshData() {
refreshControl.beginRefreshing()
datasource.fetchEvents {
self.refreshControl.endRefreshing()
self.collectionView?.reloadData()
}
}

How to implement edit/delete behaviour on an embedded tableView?

So I have an embedded tableview and I want to implement edit/delete behaviour:
In my HomePageViewController I have:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = editButtonItem
}
However, all that happens is when I click on the edit button, it says done, and the embedded tableview does nothing at all. When I put the above code in the tableview nothing happens.
How do I get the navigation controller/parent view controller to recognise the embedded table view?
It looks like you're using an embed segue to embed a UITableViewController. In your parent view controller, you can do 1 of 2 things easily to achieve you goal.
Method 1: Use the child view controller's edit button
override func viewDidLoad() {
super.viewDidLoad()
// Find and (optionally assign it to a variable for later convenience) the embedded controller, IBOutlets aren't available for VCs embedded within a storyboard
let childControllers = childViewControllers.filter { return $0 is EventTableViewController }
let embeddedController = childControllers[0] as! EventTableViewController
navigationItem.leftBarButtonItem = embeddedController.editButtonItem
}
Method 2: Forward edit events to child view controllers
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = editButtonItem
}
override func setEditing(_ editing: Bool, animated: Bool) {
super.setEditing(editing, animated: animated)
// Forward editing state to children
childViewControllers.forEach { $0.setEditing(editing, animated: animated) }
}
Note: editButtonItem was exposed in iOS 10 (but was implemented much earlier). For deployment targets less than iOS 10, you can use a custom edit button combined with method 2.
In this situation, you can't use the automatic behavior of the edit button. It's up to you to implement it yourself. You need to toggle both the isEditing of the table view and the appearance of the button. Here's an example from one of my own apps:
func doEdit(_ sender: Any?) {
var which : UIBarButtonSystemItem
if !self.tableView.isEditing {
self.tableView.setEditing(true, animated:true)
which = .done
} else {
self.tableView.setEditing(false, animated:true)
which = .edit
}
let b = UIBarButtonItem(barButtonSystemItem: which,
target: self, action: #selector(doEdit))
self.navigationItem.rightBarButtonItem = b
}