Reputation: 5250
I have next controller:
final class CategoryBreakdownViewController: UIViewController {
private let scrollView = UIScrollView(alwaysBounceVertical: true)
var refreshControl = UIRefreshControl()
Where in viewDidLoad
I'm trying to implement pull to refresh without tableView
:
private func setupRefreshControl() {
scrollView.alwaysBounceVertical = true
scrollView.bounces = true
refreshControl.addTarget(self, action: #selector(updateView), for: .valueChanged)
self.scrollView.addSubview(refreshControl)
}
@objc func updateView() {
SyncScheduler.syncImmediately(
success: {
self.refreshControl.endRefreshing()
},
failure: { [weak self] errorMessage in
self?.present(message: errorMessage, style: .error)
self?.refreshControl.endRefreshing()
}
)
}
But in my case this solution doesn't worked, how to solve this problem?
Upvotes: 0
Views: 655
Reputation: 1490
So you are missing two line of code:
self.scrollView.scrollEnabled = true
self.scrollView.alwaysBounceVertical = true
var alwaysBounceVertical: Bool
// default NO. if YES and bounces is YES, even if content is smaller than bounds, allow drag vertically.
Please try this. Thanks
Upvotes: 0
Reputation: 77462
There doesn't appear to be anything wrong with your approach.
Here is a complete example -- it adds a "full view" scrollView, with a 200-pt tall red subview (so we can see the effect).
When you drag down, you should see the UIRefreshControl
"spinner" appear. Drag down far enough, and it will call the updateView()
func. Since we don't have your SyncScheduler
code, I added a 2-second async delay to simulate the process:
final class CategoryBreakdownViewController: UIViewController {
private let scrollView = UIScrollView()
var refreshControl = UIRefreshControl()
override func viewDidLoad() {
super.viewDidLoad()
scrollView.backgroundColor = .systemTeal
scrollView.translatesAutoresizingMaskIntoConstraints = false
let testView = UIView()
testView.backgroundColor = .red
testView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(testView)
view.addSubview(scrollView)
let contentGuide = scrollView.contentLayoutGuide
let frameGuide = scrollView.frameLayoutGuide
NSLayoutConstraint.activate([
scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
testView.topAnchor.constraint(equalTo: contentGuide.topAnchor, constant: 20.0),
testView.leadingAnchor.constraint(equalTo: contentGuide.leadingAnchor, constant: 20.0),
testView.trailingAnchor.constraint(equalTo: contentGuide.trailingAnchor, constant: -20.0),
testView.bottomAnchor.constraint(equalTo: contentGuide.bottomAnchor, constant: -20.0),
testView.widthAnchor.constraint(equalTo: frameGuide.widthAnchor, constant: -40.0),
testView.heightAnchor.constraint(equalToConstant: 200.0),
])
setupRefreshControl()
}
private func setupRefreshControl() {
scrollView.alwaysBounceVertical = true
scrollView.bounces = true
refreshControl.addTarget(self, action: #selector(updateView), for: .valueChanged)
self.scrollView.addSubview(refreshControl)
}
@objc func updateView() {
// simulate a background process that takes 2 seconds
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0, execute: {
self.refreshControl.endRefreshing()
})
// SyncScheduler.syncImmediately(
// success: {
// self.refreshControl.endRefreshing()
// },
// failure: { [weak self] errorMessage in
// self?.present(message: errorMessage, style: .error)
// self?.refreshControl.endRefreshing()
// }
// )
}
}
Upvotes: 1