So I have enabled refreshing for the table view in Storyboard and put this code into the viewDidLoad() :
refreshControl?.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: .valueChanged)
and this is the refresh function:
func refresh(sender: AnyObject) {
print("a")
self.tableView.reloadData()
refreshControl?.endRefreshing()
}
The problem is that when I pull to refresh, it does not print "a"(put this for testing) and it does not end refreshing. Why?
Since you're already using Storyboards, try connecting your refresh control through IBActions (valueChanged) and see if it works. Follow this link for a guide
Related
I'm trying to add pull to refresh on my wkwebview app. I'm using UIViewRepresentable for my webview, so I don't have the onViewLoad function and view controllers. Here's my code:
var wbWebViewEl: WKWebView = WKWebView()
struct SwiftUiWebView: UIViewRepresentable {
....
class refreshWebViewClass {
#objc func refreshWebView1(sender: UIRefreshControl) {
print("test debug :D")
wbWebViewEl.reload()
DispatchQueue.main.async {
sender.endRefreshing()
}
}
func makeUIView(context: Context) -> WKWebView {
......
wbWebViewEl.scrollView.bounces = true
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(refreshWebViewClass.refreshWebView1), for: UIControl.Event.valueChanged)
wbWebViewEl.scrollView.addSubview(refreshControl)
wbWebViewEl.scrollView.refreshControl = refreshControl
.....
}
.....
}
At the moment, when you swipe down, it shows the refresh loading spinner, but it doesn't stop spinning. Also the test print I put in the refreshWebView1 function, doesn't show in the logcat. Does anyone know what I'm getting wrong here? If you need to see anymore code let me know :)
Looks like your refreshWebViewClass should be a Coordinator. Then, in your addTarget, the target would be context.coordinator, not self, which doesn't make sense here, since self doesn't actually implement this method.
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?
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()
}
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
I need help fixing this issue! I am adding pull to refresh to my table view. When I pull to refresh I want the articles to refresh. If someone who knows this would help me would be great, and if there is anything else wrong too.
Argument of '#selector' does not refer to an '#objc' method, property, or initializer
The error is here:
refreshControl.addTarget(self, action: #selector(fetchArticles(fromSource: source)), for: .valueChanged)
return refreshControl
}()
Here is the function fetchArticles:
#objc func fetchArticles(fromSource provider: String){
...
}
You have to add another function to refresh articles, because you are passing a parameter:
#objc func refreshArticles() {
self.fetchArticles(fromSource: self.source))
}
And addTarget like this:
refreshControl.addTarget(self, action: #selector(refreshArticles), for: .valueChanged)
Also, Do not miss to add refreshControl to tableView, as such:
tableView.addSubview(refreshControl)
Update Add following line once fetchArticles completes, as such:
refreshControl.endRefreshing()
You are using session.dataTask so this must go inside:
DispatchQueue.main.async {
refreshControl.endRefreshing()
}
I am using Alamofire to get data from a web URL(JSON). I am trying to implement pull to RefreshControl into my project. I have done it but don't know if it is correct or if the data is getting updated when refreshed. My code is:
var refresh = UIRefreshControl()
refresh.addTarget(self, action: #selector(self.refreshData), for: UIControlEvents.valueChanged)
func refreshData() {
Alamofire.request("https://www.example.com/api").responseJSON(completionHandler: {
response in
self.parseData(JSONData: response.data!)
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
self.tableView.reloadData()
self.refresh.endRefreshing()
})
}
Is this correct?
You are doing correctly but you need reload tableView and stop UIRefreshControl on main thread.
DispatchQueue.main.async {
self.tableView.reloadData()
self.refresh.endRefreshing()
}
Note: Instead of setting separatorStyle always on API request you need to set it once with viewDidLoad or with Interface builder.
i'm so beginner developer in ios world, and it's the first time i try to make a little application.
my app used UItableview to show the content i've get it from server, i use this tutorial: https://www.youtube.com/watch?v=JG_AMY_gSDQ
in this tutorial: they used the main view controller and add table view to it, so when i try to add pull to refresh to my view, i can't because i didn't use UITableViewController.
so is there any way to refresh my content without using UITableViewController ?
and thank you so mush for answering.
Yes this is possible. You will need to initialize UIRefreshControl manually then addsubview to your tableView
var refreshControl:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
refreshControl.tintColor = UIColor.redColor()
refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
myTableView.addSubview(refreshControl)
}
func refresh(sender: AnyObject){
// this function will be called whenever you pull your list for refresh
}