Friday, August 19, 2022
HomeiOS Developmentios - How do I current my authentic TopMostViewController from a brand...

ios – How do I current my authentic TopMostViewController from a brand new ViewController (new .swift file) that is not within the window hierarchy?

[ad_1]

Xcode 13.3.1 – Swift 5

So I am very new to this. I’ve no background in coding. I am an automotive restore technician (fancy time period for mechanic).
That is my first try.
I constructed a easy calculator with a UITabBarController.
Each single factor I needed the app to do, I googled and realized do it.
The calculator masses up superb and all the pieces appears to work.
I even added a GADBannerView with Admob and the check advert works on each tabs.

So then I discovered a video by iOS Academy and thought wow an animated launch display sounds cool.

import UIKit

class LaunchViewController: UIViewController {

non-public let imageView: UIImageView = {
    let imageView = UIImageView(body: CGRect(x: 0, y: 0, width: 270, peak: 270))
    imageView.picture = UIImage(named: "launch")
    return imageView
}()

override func viewDidLoad() {
    tremendous.viewDidLoad()
    view.addSubview(imageView)
    view.backgroundColor = .black
}
override func viewDidLayoutSubviews() {
    tremendous.viewDidLayoutSubviews()
    imageView.heart = view.heart
    
    DispatchQueue.essential.asyncAfter(deadline: .now()+0.5, execute: {
        self.animate()
    })
}

non-public func animate() {
    UIView.animate(withDuration: 1, animations: {
        let dimension = self.view.body.width * 9
        let diffX = dimension - self.view.body.dimension.width
        let diffY = self.view.body.dimension.peak - dimension
        self.imageView.body = CGRect(
            x: -(diffX/2),
            y: diffY/2,
            width: dimension,
            peak: dimension
        )
    })
    UIView.animate(withDuration: 1.5, animations: {
        self.imageView.alpha = 0
    }, completion: {completed in
        if completed {
            DispatchQueue.essential.asyncAfter(deadline: .now()+0.5, execute: {
                let viewController = ViewController()
                viewController.modalTransitionStyle = .crossDissolve
                viewController.modalPresentationStyle = .fullScreen
                self.current(viewController, animated: true)
            })
        }
    })
}

}

I adopted the code from the video to a T, besides my NEW .swift file would not comprise the primary app calculator code. The launch display VC is not my rootVC or possibly not my topmostVC? It was undoubtedly created after constructing the calculator. So I assumed, hey I will simply use the brand new VC because the preliminary view.

The above did not work. App crashed after animation and flagged the next in my rootVC:

@IBOutlet weak var bannerView: GADBannerView! "Thread 1: Deadly error: Unexpectedly discovered nil whereas implicitly unwrapping an Non-compulsory worth."

Bizarre, implicitly unwrapping the non-obligatory (do not even know what that actually means haha) labored simply superb earlier than attempting so as to add a launch display animation earlier than presenting rootVC.
Okay I will simply use ? as a substitute of !

@IBOutlet weak var bannerView: GADBannerView?
//and so on and so on
override func viewDidLoad() {
    tremendous.viewDidLoad()
    let faucet = UITapGestureRecognizer(goal: self.view, motion: #selector(UIView.endEditing))
            view.addGestureRecognizer(faucet)
    
    
    bannerView?.adUnitID = "ca-app-pub-3940256099942544/2934735716" //TestAdUnitID
    bannerView?.rootViewController = self
    bannerView?.load(GADRequest())
    
    bannerView?.delegate = self
    
}

Not crashes, however now only a black display is offered.
Appears to be complaining that

[Presentation] Try and current <xxx.ViewController: 0x7fc9c5881a00> on <xxx.LaunchViewController: 0x7fc9c6012aa0> (from <xxx.LaunchViewController: 0x7fc9c6012aa0>) whose view shouldn't be within the window hierarchy.

as a result of I suppose with:

let viewController = ViewController()

I used to be “creating a brand new one relatively than grabbing the occasion (i) created within the storyboard.”

OK candy. Gave my UITabBarControlly a storyboard ID of “mainSB”.
Insert:

....and so on
DispatchQueue.essential.asyncAfter(deadline: .now()+0.5, execute: {
let storyBoard = UIStoryboard(title: "Primary", bundle: nil)
let viewController = storyBoard.instantiateViewController(withIdentifier: "mainSB") as! ViewController
viewController.modalTransitionStyle = .crossDissolve
viewController.modalPresentationStyle = .fullScreen
self.current(viewController, animated: true)
...and so on

No crash, however calculator nonetheless not offered.
Crimson flag on:

let viewController = storyBoard.instantiateViewController(withIdentifier: "mainSB") as! ViewController "Thread 1: sign SIGABRT"

This appears to be the primary grievance:

Couldn't forged worth of kind 'UITabBarController' (0x7fff8679f9e8) to 'xxx.ViewController' (0x10f689ef0).

Oh shoot, possibly there’s one thing mistaken as a result of its not a easy view controller; its a tab bar controller with 2 tabs…?

So my logic informed me to set my tab bar controller with a customized class of “ViewController” and inherit module from goal. screw it.

NOPE! again to this:

[Presentation] Try and current <xxx.ViewController: 0x7fa4d78ba000> on <xxx.LaunchViewController: 0x7fa4d800e920> (from <xxx.LaunchViewController: 0x7fa4d800e920>) whose view shouldn't be within the window hierarchy.

So I simply set my preliminary UITabBarController as preliminary view.
However then it was simply crashing! Could not determine why for an hour. So I undid the very last thing I modified, which was giving the tab bar controller a customized class of “ViewController”.
And now it really works once more with my calculator as preliminary view.

However I did not wanna hand over.
I used to be led to this web page.

It wasn’t very clear as to the place to insert these strains, so I kinda simply guessed.

That is what I ended up with

func getTopMostViewController() -> UIViewController? {
let scenes = UIApplication.shared.connectedScenes
let windowScene = scenes.first as? UIWindowScene
    guard let window = windowScene?.home windows.first else { return nil }
var topMostViewController = window.rootViewController
    whereas let presentedViewController = topMostViewController?.presentedViewController {
        topMostViewController = presentedViewController
                                            }
topMostViewController?.modalTransitionStyle = .crossDissolve
topMostViewController?.modalPresentationStyle = .fullScreen
                                        
getTopMostViewController()?.current(topMostViewController!, animated: true)
//or do I current presentedViewController?I am confused

return topMostViewController
}

I do not even know if that is right/is sensible or the place to place it.

All that I’ve tried; I have been attempting to place after the dispatch queue:

UIView.animate(withDuration: 1.5, animations: {
        self.imageView.alpha = 0
    }, completion: {completed in
        if completed {
            DispatchQueue.essential.asyncAfter(deadline: .now()+0.5, execute: {

                })

I hope you perceive what I’ve tried and what I am attempting to do…
I would relatively not undergo the ache of re-building this factor simply to get an animated launch display. I am hoping to resolve this with code.

Thanks upfront!!!

[ad_2]

RELATED ARTICLES

Most Popular

Recent Comments