简体   繁体   中英

Present view shows black screen, why?

I'm making an app that, if a specific date has passed, presents a view controller after having started the app. The thing is: it just returns a black screen. I've tested it setting the presented view controller as initial view controller and it worked perfectly; no black screen. Thus, my mistake has to be in the code.

I'm calling this function in viewDidAppear() :

if date.hasPassed {
        presentView(fromDate: date)
    }

This is not the actual code, it's more like a simplified version. Date is in my case a custom object from an array. The object saves it's properties to UserDefaults so that they can be presented in the appearing view controller. My presentView(fromDate: date) function is the following:

func presentView(fromDate: date) {
    let vc = NewViewController()

    let title = date.title ?? "My date"
    let description = date.description ?? "My description"

    UserDefaults.standard.set(title, forKey: "title")
    UserDefaults.standard.set(description, forKey: "description")
    UserDefaults.standard.synchronize()

    self.present(vc, animated: true, completion: nil)
}

But when actually calling this function it presents a black screen without showing any error. Can you tell me why?

If you created your NewViewController in storyboard, instantiating like that will not get the ui interface from there.

You can try to assign a StoryBoardId to it on storyboard and try:

func presentView(fromDate: date) {
   let newViewController = self.storyboard.instantiateViewController(withIdentifier: "NewControllerIdentifier")

   // your code

  self.present(vc, animated: true, completion: nil)
}

if the controller is in the same storyboard of your presenting controller. Or you can create a segue to it, call the segue and set you new controller data in "prepareForSegue".

try to add newviewcontroller by grabbing storyboard reference. and using instantiateviewcontrollerwithidentifier function.

I was having the same issue where try i'm trying to present the View Controller on button pressed. Initially i was trying with following :-

    @IBAction func buttonPressed(_ sender: Any) {
        let vc = PaperViewController()
        self.present(vc, animated: true, completion: nil)
    }

In order to resolve this error i added the storyboard Id which is "paper" in my case and used the instantiateViewController which worked for me.

   @IBAction func buttonPressed(_ sender: Any) {
        if let vc = self.storyboard?.instantiateViewController(withIdentifier: 
     "paper") {
        self.present(vc, animated: true, completion: nil)
    }
 }

If it XIB case Double check that VC and XIB have the same name:

Incorrect:

DebugLogsVC.swift
DebugLogs.xib

Correct:

DebugLogsVC.swift
DebugLogsVC.xib

Present:

let vc = DebugLogsVC()
self.present(vc, animated: true, completion: nil)

In my case, with a .xib file, the problem was that the target membership of the .xib file's owner wasn't set.

To see if it applies in your case, check the "Target Membership" section of the File Inspector.

在此处输入图片说明

This happens a lot to me too in my case I was using a variety of viewControllers , ie UIAlertController , a Custom nib UIViewController , a Storyboard UIViewController , and a Hard Coded UIViewController . I'm not sure if this is a bug on Apple but to fix this problem I presented the viewController on the viewDidAppear after a time delay.

Here's my code.

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    // 1 second delay so the views will render first before presenting the alert
    Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.presentTheAlert), userInfo: nil, repeats: false)
}

func presentTheAlert() {
    let alertController = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
    self.present(alertController, animated: true, completion: nil)
}

So essentially what this does is that, it waits for the view to be fully rendered before presenting another viewController .

I like to put the presentation of the view controller in a method like you did and use

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;

to show it in viewDidAppear. However, I have found I've had to play with the delay value since in the simulator it works with 0.2, but on a device it might not. It's really annoying that Apple can't provide developers with an event that is safe for showing new views.

Hope this helps someone.

try the following:

let bundle = Bundle.main
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
var newViewController: UIViewController!
newViewController = storyboard.instantiateViewController(withIdentifier: "NewControllerIdentifier")
present(newViewController, animated: true, completion: nil)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM