UIRefresh Control UI bug with large titles & collection view - swift

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()
}
}

Related

Refresh animation not displaying when reloading tableview | 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() }

How do I call an interstitial ad to load on another UIViewController?

I have a UIViewController with a UIView displayed on it; pressing a button on the UIView loads my interstitial ad. When the UIView is subsequently displayed, I want the interstitial to be displayed with the rootVC as the UIViewController.
However, this code does not seem to work as intended:
1) My View Controller:
class MyViewController: UIViewController {
let button: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("BUTTON", for: .normal)
btn.addTarget(self, action: #selector(showUIView), for: .touchUpInside)
return btn
}()
#objc func showUIView(_ sender: UIButton) {
let popUp = MyUIView()
self.view.addSubview(popUp)
}
2) My UIView:
class MyUIView: UIView {
var interstitial: GADInterstitial!
let button: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("UIVIEW BUTTON", for: .normal)
btn.addTarget(self, action: #selector(prepareInterstitial), for: .touchUpInside)
return btn
}()
#objc func prepareInterstitial(_ sender: UIButton) {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
let request = GADRequest()
interstitial.load(request)
dismissPopUp()
if interstitial.isReady {
interstitial.present(fromRootViewController: MyViewController())
}
}
I get this in the console:
Warning: Attempt to present <GADFullScreenAdViewController: 0x7f8611e22fc0> on <Project.MyViewController: 0x7f8612884800> whose view is not in the window hierarchy!`
which I do not understand because MyViewController is still very much a part of the view hierarchy.
I'd be really grateful if someone could show me how to fix this error, I'm relatively new to coding and not sure what I am doing wrong. Thank you!
The reason why this doesn't work is because you are creating a brand new VC here:
interstitial.present(fromRootViewController: MyViewController())
This MyViewController() is not the VC that is shown on the screen! You just created by calling its initialiser.
You need to somehow get the VC that's shown on the screen. One simple way to do this is to add a rootVC property to your MyUIView:
weak var rootVC: UIViewController?
And then present this instead:
if let rootVC = self.rootVC { // nil check!
interstitial.present(fromRootViewController: rootVC)
}
In showUIView, set self as rootVC:
#objc func showUIView(_ sender: UIButton) {
let popUp = MyUIView()
popUp.rootVC = self
self.view.addSubview(popUp)
}

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)
}

swift present controller with a back button to get back to last screen

I am presenting a UICollectionViewController but it just ends up as a controller with no back buttons to get back to the last controller or the home controller, how would i add a back button? or what other options do i have?
class UserProfileController: UICollectionViewController, UICollectionViewDelegateFlowLayout, UserProfileHeaderDelegate, ProfileHeaderClosedDelegate {
func presentFRC() {
let PE = FriendsRequestsController(collectionViewLayout:
UICollectionViewFlowLayout())
let NPE = UINavigationController(rootViewController: PE)
self.present(NPE, animated: true, completion: nil)
}
}
Add the following code in the view did load of the view controller you are presenting.
override func viewDidLoad() {
super.viewDidLoad()
var backbutton = UIButton(type: .Custom)
backbutton.setImage(UIImage(named: "BackButton.png"), forState: .Normal)
backbutton.setTitle("Back", forState: .Normal)
backbutton.setTitleColor(backbutton.tintColor, forState: .Normal) // You can change the TitleColor
backbutton.addTarget(self, action: "backAction", forControlEvents: .TouchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backbutton)
}
func backAction() -> Void {
self.navigationController?.popViewControllerAnimated(true)
}
You have two options:
Embed your view controllers into UINavigationController and use UINavigationBar and segues for navigation. The easiest way to build such a system would be through storyboard though. But you can do that programmatically as well, but it would be a lot more work.
Add your own back button programmatically the way #ZahurafzalMirza has shown you. Since you are not using UINavigationController, your navigationController will be nil. So the action should look like this
func backAction() -> Void {
self.dismiss(animated: true)
}

Can't Click on UITabelCell after implementing UIRefreshControl

I have recently implemented the RefreshControl on my ViewController which contains UITableDataSource and Delegate. When you click on each cell of the table, it leads to other view controller but after implementing the refresh control, I can no longer click on each cell. Is it because I added the subview(refreshControl) to the view?
Here is the code below,
tableViewController.refreshControl = self.refreshControl
refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
refreshControl.addTarget(self, action: Selector("refresh:"), forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl)
func refresh(sender:AnyObject) {
// Code to refresh table view
self.tableView.reloadData()
self.refreshControl.endRefreshing()
}