Swift. Page based application. Immediately updating of UIViewController after update ModelController - ios

I Created Page Based Application from Apples template. I have a function in RootViewController for updating my ModelController after receiving a data from web server:
func updateMC() {
if let mc = getModelControllerWithLatestData() {
self._modelController = mc
let startingViewController: DataViewController = self.modelController.viewControllerAtIndex(1, storyboard: self.storyboard!)!
let viewControllers = [startingViewController]
// self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: {done in })
self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
self.pageViewController!.dataSource = self.modelController
self.pageViewController!.didMoveToParentViewController(self)
println("updateMC")
}
}
But new Data appearing on the screen after 10-15 seconds after updating _modelController.
How can I fix the issue?
P.S. I posted src of the RootViewController, hope this would be helpful: https://gist.github.com/stillfinder/d3ec7a57c73569411ff5

That happened because a background thread can't modify the UI. Only the UI Thread should modify that add this code, to run the modifiers in the main thread
dispatch_async(dispatch_get_main_queue()) {}
func updateMC() {
if let mc = getModelControllerWithLatestData() {
dispatch_async(dispatch_get_main_queue()) {
self._modelController = mc
let startingViewController: DataViewController = self.modelController.viewControllerAtIndex(1, storyboard: self.storyboard!)!
let viewControllers = [startingViewController]
// self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: false, completion: {done in })
self.pageViewController!.setViewControllers(viewControllers, direction: .Forward, animated: true, completion: nil)
self.pageViewController!.dataSource = self.modelController
self.pageViewController!.didMoveToParentViewController(self)
println("updateMC")
}
}
}

Related

Attempt to present UINavigationController whose view is not in the window hierarchy! (Swift)

I am running into the issue of my viewcontrollers not showing up even though the function calling the viewcontrollers seem to be running. The error I receive in the console is:
Warning: Attempt to present on whose view is not in the window hierarchy!
I have tried the suggestions on the "Attempt to present UIViewController on UIViewController whose view is not in the window hierarchy" thread without any progress. I am running everything programmatically.
func handleNewPage(){
print("this code works")
let uid = Auth.auth().currentUser?.uid
ref = Database.database().reference()
let usersReference = ref.child("patient").child((uid)!)
if usersReference.child("Doctor Code") != nil {
func presentNewPage(){
let firstPage = LandingPage()
let navCon = UINavigationController(rootViewController: firstPage)
present(navCon, animated: true, completion: nil)
}
presentNewPage()
print("PRINT")
} else{
let newPage = PresentViewController() // doctor reg page
let navController = UINavigationController(rootViewController: newPage)
present(navController, animated: true, completion: nil)
}
}
The function is called and the print statements come out valid. Yet, the viewcontrollers will not appear.
You have to create presentNewPage() function outside of your if ???
if usersReference.child("Doctor Code") != nil {
func presentNewPage(){
let firstPage = LandingPage()
let navCon = UINavigationController(rootViewController: firstPage)
present(navCon, animated: true, completion: nil)
}
presentNewPage()
print("PRINT")
} else{
let newPage = PresentViewController() // doctor reg page
let navController = UINavigationController(rootViewController: newPage)
present(navController, animated: true, completion: nil)
}
change it like this
func presentNewPage(){
let firstPage = LandingPage()
let navCon = UINavigationController(rootViewController: firstPage)
present(navCon, animated: true, completion: nil)
}
func handleNewPage(){
print("this code works")
let uid = Auth.auth().currentUser?.uid
ref = Database.database().reference()
let usersReference = ref.child("patient").child((uid)!)
if usersReference.child("Doctor Code") != nil {
presentNewPage()
print("PRINT")
} else{
let newPage = PresentViewController() // doctor reg page
let navController = UINavigationController(rootViewController: newPage)
present(navController, animated: true, completion: nil)
}
}

How to present a UICollectionViewController?

I get an error:
fatal error: unexpectedly found nil while unwrapping an Optional value
The didTapUserScreenButton() works fine though, the didTapChatControllerButton() gives the error. I'm thinking it might get the error because the didTapChatControllerButton() goes to a UiCollectionViewController? and the other works fine as it's going to a UITableViewController?.
func didTapChatControllerButton() {
let chat_log_controller = ChatLogController
let navController = UINavigationController(rootViewController: chat_log_controller!)
present(navController, animated: true, completion: nil)
}
func didTapUserScreenButton() {
let user_screen_vc = usersScreenVC()
let navController = UINavigationController(rootViewController: user_screen_vc)
present(navController, animated: true, completion: nil)
You missed the (currently empty) initialization argument holder brackets. Try with tris:
let chat_log_controller = ChatLogController()
let navController = UINavigationController(rootViewController: chat_log_controller)
present(navController, animated: true, completion: nil)

How can I switch view controllers with code in iOS?

let SecondViewController =
self.storyboard?.instantiateViewController(withIdentifier:
"SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(SecondViewController,
animated: true)
For some reason this doesn't work. Any ideas?
Replace
self.navigationController?.pushViewController(SecondViewController,
animated: true)
with
self.navigationController?.present(SecondViewController, animated: true, completion: nil)
Edit: To avoid the optionals you should also do one of the following:
guard let navController = self.navigationController else { return }
navController.present(SecondViewController, animated: true, completion: nil)
or
if let nacVontroller = self.navigationController {
navController.present(SecondViewController, animated: true, completion: nil)
}
Edit2: You should also avoid force unwrapping your SecondViewController using one of the above methods as well. Although that is not your current issue.

Cannot convert value of type'[AnyObject]'to expected argument type '[UIViewController]?'

private func createPageViewController() {
let pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("PageViewController") as! UIPageViewController
pageViewController.dataSource = self
pageViewController.delegate = self
if contentImages.count > 0 {
let firstVC = self.getItemController(0)!
let startingVCs: NSArray = [firstVC]
pageViewController.setViewControllers(startingVCs as [AnyObject] as [AnyObject], direction: .Forward, animated: false, completion: nil)
}
change this
pageViewController.setViewControllers(startingVCs as [AnyObject] as [AnyObject], direction: .Forward, animated: false, completion: nil)
into
The viewControllers parameter is now a [UIViewController]. So your viewControllers array that you pass in must be [UIViewController].
pageViewController.setViewControllers(startingVCs as [UIViewController], direction: .Forward, animated: false, completion: nil)

Cannot invoke" 'setViewController' with an argument list of type [AnyObject]

"Cannot invoke" 'setViewController' with an argument list of type '([AnyObject], direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: nil)'"
I got this error in Xcode 7 beta 3 at this line of code:
self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
This is the rest of the code:
pageImages = NSArray(objects:"screenshot01","screenshot02","screenshot03")
self.pageViewController = self.storyboard?.instantiateViewControllerWithIdentifier("MyPageViewController") as! UIPageViewController
self.pageViewController.dataSource = self
var initialContenViewController = self.pageTutorialAtIndex(0) as TutorialPageContentHolderViewController
var viewControllers = NSArray(object: initialContenViewController)
self.pageViewController.setViewControllers(viewControllers as [AnyObject], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
self.pageViewController.view.frame = CGRectMake(0, 100, self.view.frame.size.width, self.view.frame.size.height-100)
self.addChildViewController(self.pageViewController)
self.view.addSubview(self.pageViewController.view)
self.pageViewController.didMoveToParentViewController(self)
I don't get the error if I run the same code in Xcode 6 and I can't figure out why.
The signature looks like:
func setViewControllers(_ viewControllers: [UIViewController]?,
direction direction: UIPageViewControllerNavigationDirection,
animated animated: Bool,
completion completion: ((Bool) -> Void)?)
So why are you casting to [AnyObject]?
Try
self.pageViewController.setViewControllers(viewControllers as [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)
Depending on the type of viewControllers you might also need to use as!
In xcode7.0, you may change it to
self.pageViewController.setViewControllers(viewControllers as? [UIViewController], direction: UIPageViewControllerNavigationDirection.Forward, animated: true, completion: nil)

Resources