How to pass data to embed ViewController? - ios

I have a code, which must pass data with segue:
let navController : UINavigationController = segue.destinationViewController as! UINavigationController
let viewController : UIViewController = navController.viewControllers[0] as! CTableViewController
viewController.SelectedTypeOfVariable = "G"
But I have the following error:
UIViewController does not have a member named SelectedTypeOfVariable

This worked for me:
let viewController : CTableViewController = navController.viewControllers[0] as! CTableViewController
viewController.SelectedTypeOfVariable = "G"
I think the reason for this is because you are saying your "viewController" variable is of type UIViewController. If your "viewController" variable is of type UIViewController, then it indeed does not have a member named SelectedTypeOfVariable. Your subclass of UIViewController, "CTableViewController" does though and so you need to make sure your variable is of type "CTableViewController"

You can use like this
let viewController = navController.viewControllers[0] as! CTableViewController

Related

iOS (Swift) - Array of UIViewControllers

I have an array UIButtons that have a unique tag value. When a given button is pressed, I want to load and present a UIViewController that is also stored in an array of equal length.
The UIViewControllers to be presented are subclasses of a subclass of UIViewController:
class AViewController: UIViewController {}
class BViewController: AViewController {}
class CViewController: AViewController {}
class DViewController: AViewController {}
// ... etc.
I've tried storing the array of AViewController subclasses using the following:
private var array: [AViewController] = [BViewController.self, CViewController.self, DViewController.self]
but I get the error Cannot convert value of type '[BViewController].Type' to specified type '[AViewController]' for the first element.
I will then present BViewController (for instance) using the following:
let ViewController = array[button.tag].self
var viewController: AViewController
viewController = ViewController.init()
viewController.transitioningDelegate = self
viewController.modalPresentationStyle = .custom
present(viewController, animated: true)
Please let me know if this is the incorrect thought process for doing something like this please and thanks for any help.
You need instances
private var array: [AViewController] = [BViewController(), CViewController(), DViewController()]
if the vcs are in IB , then you would do
let b = self.storyboard!.instantiateViewController(withIdentifier: "bID") as! BViewController
let c = self.storyboard!.instantiateViewController(withIdentifier: "cID") as! CViewController
let d = self.storyboard!.instantiateViewController(withIdentifier: "dID") as! DViewController
Then
array = [b,c,d]
lazy var VCArray :[UIViewController] = {
return [VCinst(name: "firstVC"),VCinst(name: "secondVC"), VCinst(name: "thirdVC")]
}()
func VCinst(name:String) -> UIViewController {
return UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: name)
}
Alternate answer if you want to store array of view controllers as a constant.
struct AppConstant {
static let yourViewControllers: [AnyClass] = [AViewController.self,
BViewController.self, CViewController.self]
}

Swift: Reuse code passing class to parameter

I would like to reuse code, so I created redirectToTabBarControllerChild
func redirectToTabBarControllerChild(storyboardName: String, tabBarIndex: Int, segueID: String, viewController: UITableViewController) {
let storyboardMain = UIStoryboard(name: storyboardName, bundle: nil)
let tabBarController = storyboardMain.instantiateViewController(withIdentifier: "TabBarController") as! UITabBarController
window?.rootViewController = tabBarController
tabBarController.selectedIndex = tabBarIndex
let navigationViewContrller = tabBarController.childViewControllers[tabBarIndex] as! UINavigationController
let currentViewContrller = navigationViewContrller.childViewControllers.first as! viewController
currentViewContrller.performSegue(withIdentifier: segueID, sender: nil)
window?.makeKeyAndVisible()
}
The last parameter I would like to pass ProfileViewController for example. But I have an error in this line: let currentViewContrller = navigationViewContrller.childViewControllers.first as! viewController
Use of undeclared type viewController
Does anyone know how I could do it?
The navigationController?.childViewControllers is an array of UIViewControllers. You´re getting the first property which means you need to cast it to as! UIViewController which will force cast it and it will not be an optional anymore.
What you want to do is to cast it to a UITableViewController, so do it like this:
if let vc = navigationViewContrller.childViewControllers.first as? UITableViewController {
// Will succeed if the first is of type UITableViewController
// Use vc in here
}
Replace viewController to UITableViewController

NSClassFromString in Swift 2.1

I guess I read most of the SO questions and Google answers on this, but still cannot get it working. Take this code example:
import UIKit
class Person: NSObject {
var name = "Pieter"
}
let PersonClass: AnyClass? = NSClassFromString("Person")
let person = PersonClass()
print(person.name)
Changing NSClassFromString("Person") into NSClassFromString("MyAppName.Person") does not make a difference. Adding as! NSObject.Type behind the PersonClass declaration neither. Adding #obcj(Person before the class declaration neither.
The real-life goal is to read class names from a database and load the appropriate storyboard / UIViewController accordingly. So I am looking for a way to pass the UIViewController class name as a String and instantiate the UIStoryboard with it.
How to do that?
Edit: here is what I currently try for the real-life scenario after your suggestions:
let storyboard = UIStoryboard(name: "MyStoryboard", bundle: nil)
let MyClassName = "MyApp.MyTableViewController"
let MyClass = NSClassFromString(MyClassName) as! UITableViewController.Type
let controller = storyboard.instantiateInitialViewController() as! MyClass
It gives an error saying "MyClass" is not a type. I cannot remove it or I will get an error that it cannot convert from AnyClass.
Try the code given below
let viewController = storyboard?.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
This code allow you to instantiate the storyboard view controller.
But you can not pass the View Controller class name.
You have to pass the storyboard identifier of the view controller.
Please review the below picture for it.

Downcast from 'UIViewController?' to 'UIViewController' only unwraps optionals; did you mean to use '!'?

I am using below code to set root view controller. But It is giving me error:
let storyboard = UIStoryboard(name:"SignUp", bundle:nil)
let viewController = storyboard.instantiateInitialViewController() as! UIViewController
self.window!.rootViewController = viewController
I am getting error like Downcast from 'UIViewController?' to 'UIViewController' only unwraps optionals; did you mean to use '!'?
I think, It has to do with "as!", but it is introduced in new swift.
Does any one have idea ?
Two ways to do this I suppose
Safer one:
let storyboard = UIStoryboard(name:"SignUp", bundle:nil)
if let viewController = storyboard.instantiateInitialViewController(){
self.window!.rootViewController = viewController
}
edit: removed as? UIViewController
The one suggested by the compiler:
let storyboard = UIStoryboard(name:"SignUp", bundle:nil)
let viewController = storyboard.instantiateInitialViewController()!
self.window!.rootViewController = viewController
Basically the compiler is just letting you know that the as! UIViewController in this code is basically just the same as using one !

How to use a variable in other class that is defined in AppDelegate

I have a variable var window: UIWindow? in AppDelegate.swift file inside class AppDelegate that I want to use in other class xyz.swift file inside class xyz as explained in here Get current view controller from the app delegate (modal is possible) but I am getting error at the first line any help will be appreciated. here is the code from xyz.swift
func CurrentView() -> UIView
{
let navigationController = window?.rootViewController as? UINavigationController // Use of Unresolved identifier 'window'
if let activeController = navigationController!.visibleViewController {
if activeController.isKindOfClass( MyViewController ) {
println("I have found my controller!")
}
}
}
Even if I use let navigationController = AppDelegate.window?.rootViewController as? UINavigationController error is 'AppDelegate.Type' does not have member named 'window'
You may have to do as follows:
var appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let navigationController = appDelegate.window?....
As #Dave Durbin has pointed out you are trying to use a variable defined in one class into another class without the reference of the defining class.
This line of code is in xyz.swift
let navigationController = window?.rootViewController as? UINavigationController // Use of Unresolved identifier 'window'
You don't provide any context for window so it's expected to be in this class or a global variable.
This is closer:
navigationController = AppDelegate.window?.rootViewController as? UINavigationController
and you seem to realise that you need to reference the window variable within your AppDelegate instance however the syntax you are using references a static variable and window is a member variable.
I suggest you read through the swift manual and gain a better understanding of variable scopes and check this:
How do I get a reference to the app delegate in Swift?

Resources