简体   繁体   中英

Collection View returns nil when called in function

I want to run a function which involves adding a sublayer to a collection view. However when I run the function the app crashes saying Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value When I print the collection view it shows up in the log as none so I know the collection view is the problem. The view has already been loaded when I call the function and I can see all of it's cells. The function is being called from another class, which I think might have something to do with the problem.

Here is the function that I am calling...

func displayCircle() {
         let shapeLayer = CAShapeLayer()
        shapeLayer.path = circlePath.cgPath

        //change the fill color
        shapeLayer.fillColor = UIColor.green.cgColor
        //you can change the stroke color
        shapeLayer.strokeColor = UIColor.green.cgColor
        //you can change the line width
        shapeLayer.lineWidth = 3.0
        print(shapeLayer)


        print(collectionView)
        collectionView!.layer.addSublayer(shapeLayer)

    }

Here is how I am calling this function from another class...

ViewController().displayCircle()

EDIT: This is my storyboard layout...

在此处输入图片说明

What could the problem be?

As you can see, I am using a page view controller. Hope this helps

There's likely a few issues here.

If you wanted to say ViewController.displayCircle() then displayCircle would need to be a static function. But I don't think that was your intention, you probably don't want to do that in this case, and also your static function syntax is wrong ( ViewController().displayCircle() is wrong). But moving on... :)

ViewController().displayCircle() isn't how you properly reference the collectionView. First you need a reference to the other view controller. Then inside displayCircle you need to grab a reference to the collectionView if it's in another View Controller. So that would be otherViewController.collectionView provided the collectionView is public of course, and provided you have a reference to that other view controller somehow. Note that you can't just make a new reference of the other view controller, otherwise you'll be adjusting the layer on the new instance, not the original.

Last but not least, you're force unwrapping the collectionView - don't do that. Your app will crash if it's ever nil. Instead, take advantage of Swift's paradigms:

if let collView = collectionView {
     collView.layer...// etc
}

This last bit isn't the issue, but just good practice.

If the collectionView is part of this same viewController, use self:

self.collectionView.layer.addSublayer(shapeLayer)

If the collectionView is in a different viewController, as it seems to be, you would need to get a reference to that view controller. How you do this depends on the structure of your app. You mention using a UIPageViewController and presumably both the view controllers are presented on it.

From one view controller, you can refer to another like this:

let pvc = self.parent as? UIPageViewController // Or your custom class
let targetViewController = pvc.viewControllers[index] as? YourTargetViewControllerClass

You might need to figure out what index you need. An alternative is to make sure each child view controller of the UIPageViewController has its own subclass, then find the one you want like this:

let pvc = self.parent as? UIPageViewController
let viewControllers = pvc.viewControllers.filter { $0 is CustomSubclass }
if let viewController = viewControllers.first as? CustomSubclass {
    viewController.displayCircle()
}

As the other answer states, using ViewController() creates a brand new view controller instance, not the one that already exists.

This

ViewController()

creates a new instance other than the presented one ,when you reference the collectionView from it it's actually nil as you have to load the VC either from storyboard / xib , so you have to use delegate to reference the current VC that contains the collectionView

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