iOS Swift3 Check Nil Value for Viewcontroller Object

iOS Swift3 check nil value for ViewController Object

Use this code. this is helpful for you.

let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for VC in viewControllers {
if (VC.isKind(of: HomeViewController.self)) {
bScreen = true
self.navigationController?.popToViewController(VC, animated: true)
break;
}
}

if bScreen == false
{
let homeVC = HomeViewController()
self.navigationController?.pushViewController(homeVC, animated: false)
}

iOS Swift3 check nil value for ViewController Object

Use this code. this is helpful for you.

let viewControllers: [UIViewController] = self.navigationController!.viewControllers
for VC in viewControllers {
if (VC.isKind(of: HomeViewController.self)) {
bScreen = true
self.navigationController?.popToViewController(VC, animated: true)
break;
}
}

if bScreen == false
{
let homeVC = HomeViewController()
self.navigationController?.pushViewController(homeVC, animated: false)
}

Variables show up as nil - swift 4 IOS

First thing is never use forcefully unwrap until you are sure about value. In your case VNCoreModelRequest can fail and your both variable will be un assigned so it will defiantly crash your app.
One more thing make sure you use proper naming convention to your label.

Your issue is you are not setting label value from result you are getting.

To fix this

 var stringy:String? {
didSet {
DispatchQueue.main.async {
self.Labele.text = self.stringy
}
}
}

OR

        self.stringy = firstObservastion.identifier
self.stringie = firstObservastion.confidence
DispatchQueue.main.async {
self.Labele.text = "Guess: \(stringy) + Certainty: \(stringie)"
}

Unexpectedly found nil while unwrapping an Optional value, when trying to change a label's text, triggered by a notification

The optional part is your label property. It is marked as force unwrap with having "!" at the end @IBOutlet weak var theLabel: UILabel!. This is a default when connecting outlets and to generally avoid such issue I suggest you to practice @IBOutlet private weak var <#name#>: <#type#>?.

As already mentioned in comment by @Larme you are creating an instance of your view controller through empty constructor which will not load the controller from your storyboard or xib by default (you might have overridden it though). Still even if overridden the view is probably not yet loaded at that point and your label is still nil.

From the code you posted it seems you want to push some data to a view controller which should exist unless your app is opened by triggering a notification. There are many ways to handle this but one you might consider is to have a static method changeLabel which can be called without creating an instance of view controller. The method should check if a view controller is loaded and call your method on it if it does. If it is not yet loaded then it should be called in view did load once it does load (assuming it loads during a default UI pipeline).

To achieve such a system you may do the following:

Add a private static variable of your view controller within itself like private var currentInstance: ViewController?. On view did load call ViewController.currentInstance = self. Also add static variable for data you need (like your url) static var myURL: Any?. Then:

static func setURL(url: Any?) {
if currentInstance != nil {
currentInstance.changeLabel() // Will be called immediately
} else {
myURL = url
}
}

And view did load:

override func viewDidLoad(animated: Bool) {
...
if let url = ViewController.myUrl {
ViewController.myUrl = nil
changeLabel()
}
...
}

This way all you need to do in your app delegate is call ViewController.setURL(userInfo["url"]).

I hope you get a basic idea...

Referring to my view controller in another class (scene.swift) - all variables turn to null? Swift 3

Try This. (Check updated Edited answer: Highly recommended)

ARViewController: Create an instance outside the class

weak var arViewControllerInstance = ARViewController()

Make sure initialization inside ARViewController class:

 override func viewDidLoad() {
super.viewDidLoad()
arViewControllerInstance = self
}

Now you can call in Scene.Swift using:

arViewControllerInstance?.doPost(bookingTime: "08:00:00")

Edited: Highly recommended

Above Method Simple but highly not recommended for best practice. Have a look below implementation using delegate protocol.

Create a protocol

protocol ScenceArViewControllerDelegate {
func doPost(bookingTime: String)
}

Add Above delegate in ARViewController class as below.

class ARViewController: UIViewController, ScenceArViewControllerDelegate{
func doPost(bookingTime: String){
//Funcion body goes here
}
}

Create a delegate variable inside the Scene class as below (Scene.swift)

class Scene: SKScene{
weak var delegateARVC: ScenceArViewControllerDelegate?
}

Once you implement above all. Now you have declared the delegateARVC variable from ARViewController as below code. (Note: You can use dependency injection for set value but below just sets object)

class ARViewController: UIViewController, ScenceArViewControllerDelegate{

var scene: Scene?

override func viewDidLoad() {
super.viewDidLoad()
scene = Scene()
scene.delegateARVC = self
}

func doPost(bookingTime: String){
//Funcion body goes here
}
}

Now all good. Now your Scene class knows it has a relationship reference with ARViewController by the method called doPost using ScenceArViewControllerDelegate.

You can call AARViewController 's doPost method as below from Scene class.

guard let delegateARCAvailable = delegateARVC else { return }
delegateARCAvailable.doPost(bookingTime: "08:00:00")

You can apply as you want. Thanks.

delegate remains nil

The method you are using is incorrect. You should use the new one:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
....
}

Notice the override keyword? if you don't see this when you are writing the viewController methods, It means that you are NOT calling the original method and misspelled the function signature.

NOTE: if you are targeting older iOS and using older Xcode, the method name may be different, you should write the name of the method and let the AutoComplete help you with the correct one.



Related Topics



Leave a reply



Submit