UiView with TableView and CollectionView not refreshing randomly - swift

I have a UIView that contains a CollectionView and a TableView, both shows data from a service, but sometimes randomly when I enter on this UIView the data is not showing, I am using self.collectionView.reloadData() and self.servicesTableView.reloadData() but it don't shows the information all the times.

A sample of your code would help a lot to figure it out what is happening. But if you do something like this it should work:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
*Do your request*
After that:
self.yourtableview.reloadData()
self.yourcollectionView.reloadData()
}

Related

Swift: Make UIViewController print off the subclass type upon hitting the viewWillAppear or viewWillDisappear functions?

The title basically asks my question for me. I have a number of view controllers which I'm loading in or dismissing as a user goes through the app. I'm having some asynchrony issues with the dismiss calls being called potentially too much. It's been a bit of a doozy going through the code base and finding what is being called where. I'd like to just print off whenever a new UIViewController hits the points in it's lifecycle functions viewWillAppear() or viewWillDisappear(). Is there a way for me to extent the UIViewController in such a way that all of its subclasses will naturally do this? Or would I have to go through each subclass to add in that code?
Thank you!
You could create a new UIViewController base class with the following:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("\(type(of: self)) will appear")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
print("\(type(of: self)) will disappear")
}
You'll have to inherit from this class on any view controller whos events you want to log

viewDidDisappear not showing ad

Im using startApp to display ads but when the view disappears it doesn't show the ad. I have startAppAd = STAStartAppAd() in viewDidLoad() I'm not quite sure what is going wrong.
override func viewDidAppear(_ animated: Bool) {
startAppAd?.load()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
startAppAd?.show()
}
viewDidDisappear is called when the vc is about to dimiss or popped , so any property is in it's way to deallocate if that vc is not strongly linked , so move the show method also inside viewDidAppear or in the ad load finish callback if any

How to Stop a VCs functions from operating when VC is not in view? [Swift 3.0 Xcode]

I have a view controller which contains functions wish I need to disable once I leave the view controller. The functions wont start until I navigate to the VC, which is what I want, but I also what these functions to stop once I leave and navigate to other view controllers. Does anyone know any tricks to this?
there are multiple ways you can do this.
One like others have commented is invalidate timers or location stuff in either one of these methods.
let someTimer = Timer()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
someTimer.invalidate()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
someTimer.invalidate()
}

Call reloadData() after a dismissViewController

I have a collectionView controller with a collectionView populated by a database. In this controller I have reloadData() in 'viewDidAppear' and 'viewWillAppear' functions.
The collectionView controller has a modal segue to a gameViewController. After the 'game' is finished in the gameViewController, the database is updated (this works) and the modal is dismissed back to the collectionView controller.
func gameOver() {
self.dismissViewControllerAnimated(true, completion: nil)
}
However despite 'viewDidAppear' and 'viewWillAppear' being called (I confirm this with a println()) when the gameViewController is dismissed, the collectionView data does not reload. So the updated database data isn't shown in the collectionView.
The collectionView data does reload if I dismiss the collectionView controller, and then reopen it.
How do I ensure the collectionView controller - reloadData() - is called after dismissing the gameViewController?
Code:
class GameViewController: UIViewController {
var collectionView: LevelsCollectionViewController!
override func viewDidLoad() {
super.viewDidLoad()
// code not related to question - creates game scene
}
override func viewDidDisappear(animated: Bool) {
collectionView.reloadData()
}
func gameOver() {
self.dismissViewControllerAnimated(true, completion: nil)
}
class LevelsCollectionViewController: UICollectionViewController {
// code setting up cells
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
println("viewWillAppear")
self.collectionView!.reloadData()
self.collectionView!.setNeedsDisplay()
}
override func viewDidAppear(animated: Bool) {
super.viewWillAppear(animated)
println("viewDidAppear")
self.collectionView!.reloadData()
self.collectionView!.setNeedsDisplay()
}
}
UPDATE:
The println() viewWillAppear & viewDidAppear are printed in the console after the dismissViewController, but the collectonView data isn't reloaded.
The database that the collectionView is taken from is updated (done is another function called before gameOver().
I tried the method suggested below of having a reference to UIViewController and calling reloadData on that from viewDidDisappear, but nothing happens.
Actually that's what the completion argument is for
func gameOver() {
self.dismissViewControllerAnimated(true) { () -> Void in
self.collectionView.reloadData()
}
}
Check to make sure that your data source is being updated (a few println's in your viewDidAppear() will help) - in addition, try storing a reference to the collectionView controller and calling reloadData() on it in the viewWillDisappear() method of your gameViewController.
Some days I want to kick my own backside!
I 'stupidly' forgot to reload the temp array (levelProgress) that was holding the information taken from the database (held on array in appDelegate) in the collectionViewController.
Thus while the database and the array in appDelegate were being updated, the reloadData() was still working off the tempArray in the collectionViewController. Resetting this tempArray on viewDidAppear(), then reloadData() did the trick.
override func viewDidAppear(animated: Bool) {
super.viewWillAppear(animated)
levelProgress = appDelegate.levelProgress
self.collectionView!.reloadData()
self.collectionView!.setNeedsDisplay()
}
Think I'm going code blind

How to open the keyboard automatically on UITextField?

I have a very simple table and when tocuh a cell it opens a new view with one UITextfield. All I want is that the keyboard will automatically opens, without the user have to touch the UITextfield.
Its all done in Interface Builder, so I am not sure how I do this. I guess I need to set the focus at some point ?
Thanks
To cause the keyboard to show up immediately you'll need to set the text field as the first responder using the following line:
[textField becomeFirstResponder];
You may want to place this in the viewDidAppear: method.
Swift 3 & 4:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
textField.becomeFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
textField.becomeFirstResponder()
}
Prefer adding the first responder on the main thread -
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.textField.becomeFirstResponder()
}
This will come in handy when the view controller view is added as a subview.