Adding UICollectionView inside UIView without Storyboards
Asked Answered
L

1

0

I have ViewController called myVC with UITablewView - myTable.

What I want is to add some UIView as myTable's headerView from code. So inside viewDidLoad() method of myVC I added this code

    let topView = TopView()
    topView.frame.size.height = 100
    topView.frame.size.width = myTable.frame.width
    myTable.tableHeaderView = featuredEventsView

I also created file called TopView.swift that looks something like

class TopView : UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)            
        self.backgroundColor = .red
    }

    required init?(coder aDecoder: NSCoder) {.....}
}

And it is working as it should. I see red UIView in headerView of myTable.

Now I want to add UICollectionView inside topView and I have problems here. I am trying to do something like

class TopView : UIView, UICollectionViewDataSource, UICollectionViewDelegate {
    override init(frame: CGRect) {
        super.init(frame: frame)            
        self.backgroundColor = .red

        addSubview(myCollectionView)
    }

    required init?(coder aDecoder: NSCoder) {.....}

let myCollectionView : UICollectionView = {
        let cv = UICollectionView()
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.delegate = self as! UICollectionViewDelegate
        cv.dataSource = self as! UICollectionViewDataSource
        cv.backgroundColor = .yellow
        return cv
    }()
}

I also created functions needed to UICollectionViewDataSource but app crashes after building. What am I doing wrong?

Llywellyn answered 4/6, 2017 at 15:1 Comment(10)
"app crashes after building" ... Error message(s)? Have you stepped through in debug to find out where exactly it's causing a crash?Winglet
"libc++abi.dylib: terminating with uncaught exception of type NSException" - this is all I can see - how can I get more?Llywellyn
Set a debug breakpoint, and step through line by line until you find the exact code that is causing the crash.Winglet
Ok, it crashes after let topView = TopView()Llywellyn
What is the line of code after that? Or do you mean it crashes inside that line? Like perhaps in TopView init? If so, on which line in there? And you must be getting more of an error than you show here... Do you have the debug console pane open? Is there really nothing other than "libc++abi.dylib: terminating with uncaught exception of type NSException"?Winglet
Yes, it all i see inside debug pane. By setting breakpoints - I find that it is crashing after let cv = UICollectionView() in TopView.swiftLlywellyn
Is UICollectionView() a valid way to create a collection view instance? I'm pretty sure you need to provide a frame and a UICollectionViewLayout...Winglet
in that case - how should I init it properly?Llywellyn
I'd suggest first searching for uicollectionview programmatically swift and going through a tutorial or two. When you've got a handle on that part, then you can work on adding it in to another class as you're trying to do here.Winglet
can you show an image what you want to achieveVitrics
A
2

You have two problems:

1) You initialise your UICollectionView incorrectly as you must give it a layout. You need something like this (use whatever frame you want but if you are going on to use auto layout it doesn't matter):

let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)

2) You cannot reference 'self' inside the closure when initialising a property. This is because if may not have been initialised (as in this case) so you can't guarantee it's safe to use it.

I think you should be ok if you use lazy initialisation like this (plus you don't even need to cast 'self'):

lazy var myCollectionView : UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: CGRect.zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.delegate = self
    cv.dataSource = self
    cv.backgroundColor = .yellow
    return cv
}()

Using the lazy method should delay until self is initialised and therefore safe to use.

Attorn answered 4/6, 2017 at 22:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.