Using Collectionview in Uiview with Xib File

Using CollectionView in UIView with xib file

The main way to use UICollectionView is by managing the logic programmatically.

  1. First, create a new class which inherits from UICollectionViewCell. Choose if you want to include a xib to easily design your cell:
    Sample Image

  2. Design your cell with Interface Builder or programmatically.

  3. Create your main view controller including a xib (or a storyboard) with the collection view inside and link it to the associated class via Interface Builder. Alternatively you can add a collection view programmatically to your UIViewController

Sample Image


  1. Make the target view controller conform to the UICollectionViewDelegate and UICollectionViewDataSource protocols by declaring them after the father class:

    class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    @IBOutlet weak var collectionView: UICollectionView!

    //...
    }
  2. Register the associated nib or the class for your cell in the viewDidLoad method and associate the datasource and delegate protocols to the view controller class:

     let cellIdentifier = "cellIdentifier"

    override func viewDidLoad() {
    super.viewDidLoad()
    //if you use xibs:
    self.collectionView.register(UINib(nibName:"MyCollectionCell", bundle: nil), forCellWithReuseIdentifier: cellIdentifier)
    //or if you use class:
    self.collectionView.register(MyCollectionCell.self, forCellWithReuseIdentifier: cellIdentifier)

    self.collectionView.delegate = self
    self.collectionView.dataSource = self
    }
  3. Implement the methods declared in the UICollectionViewDelegate and UICollectionViewDataSource protocols :

     let objects = ["Cat", "Dog", "Fish"]

    func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return self.objects.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! MyCollectionCell

    //in this example I added a label named "title" into the MyCollectionCell class
    cell.title.text = self.objects[indexPath.item]

    return cell
    }
  4. Run your app in the simulator (or on a real device) and.. Et voilà! :)

Sample Image

For more info: https://developer.apple.com/reference/uikit/uicollectionview

Can´t add items to UICollectionView inside UIView xib

You can't have UICollectionViewCell when the UICollectionView is on a Nib. What you need to do is to create the UICollectionViewCell as another nib and get it registered in the class that you are using for your CollectionView.

Create a new nib, drag a UICollectionViewCell inside it, and do something like this in the class that works with your UICollectionView.

override func awakeFromNib() {
let nibName = UINib(nibName: "ClassCollectionCell", bundle:nil)
collectionView.registerNib(nibName, forCellWithReuseIdentifier: "collectionCell")
}

Remember you can add a custom class to the UICollectionViewCell so you can pass dynamic data to it.

iOS Swift - CollectionView INSIDE UIView XIB INSIDE UIViewController

Figured it out. Yes, if you want to use a CollectionView inside a XIB, and you have a custom CollectionViewCell, you have to create a XIB for the CollectionViewCell. You cannot just have a CollectionViewCell without a XIB in this case. Then, in the ViewController that contains the XIB, you have to use:

xibView.collectionView.register(UINib(nibName: "CustomCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "CustomCollectionViewCell")

Most tutorials say to do this in viewDidLoad, however I'm creating not just one XIB in the ViewController, but a bunch of them based on data pulled from a database. So I do this within the loop that builds each XIB. I was worried this wouldn't work, but it does.

The reason why you have to do this continues to elude me.

Reusing XIB views for collectionviews as a partial for other views?

(a) I have a swift file which I created; it a custom subclassed UICollectionViewCell. It has a XIB file.

Register the nib with the collection view. In cellForItemAt, when you need a cell, dequeue it. You will receive a copy of the collection view cell from the nib. Configure it as desired. Return it.

(b) I want to reuse the same XIB elsewhere in the app, including all outlets and connections

Load the nib and pull out the first (and only) top-level view. You will receive a copy of the collection view cell from the nib. Add it as a subview to a view in the interface.

(The easiest way to do that is through UINib and its instantiate method. This returns an array of the top-level objects.)

True, one does not usually use a collection view cell as a subview of an ordinary view. But I cannot think of any reason against it; after all, a view is a view is a view.

(If you would prefer not to do that, I can think of workarounds; for example, make the view in the nib a custom UIView and configure each cell by loading the nib and putting that view inside the cell. This will introduce some inconveniences, but it will make the nib more universally usable.)


I made a quick example. Here's the nib, very simple because it's only an example:

Sample Image

Here's my app, showing a collection view (showing four cells on a blue background) and also the view from the nib extracted and stuck into the interface:

Sample Image

Here's the entire code:

class MyView : UIView {
@IBOutlet var iv : UIImageView?
}

class MyCell : UICollectionViewCell {
var v : MyView?
}

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var cv: UICollectionView!

override func viewDidLoad() {
super.viewDidLoad()
self.cv.register(MyCell.self, forCellWithReuseIdentifier: "cell")
let arr = UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil, options: nil)
let v = arr[0] as! UIView
self.view.addSubview(v)
v.frame.origin = CGPoint(x:20, y:300)
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
if cell.v == nil {
let arr = UINib(nibName: "View", bundle: nil).instantiate(withOwner: nil, options: nil)
let v = arr[0] as! MyView
cell.contentView.addSubview(v)
cell.v = v
}
print(cell.v?.iv) // image view
return cell
}

}

Note the use of subclasses and outlets. cell.v takes us to the view, so cell.v?.iv takes us to the image view — and now we could perform further configuration, as desired. Thus we have one level of indirection added in order to reach a subview from the nib, but this seems a very small price to pay.

How to load custom cell ( xib) in UICollectionView cell using swift

Here is what you can do,

  1. Change your MyCustomView class to be a subclass of UICollectionViewCell and not UIView.

  2. Remove override init(frame : CGRect),required init?(coder aDecoder: NSCoder),func xibSetup(),func loadViewFromNib() -> UIView from MyCustomView

  3. I seriously could not understand how are you using your setter and getter for mytitleLabelText and myCustomImage. If its of no use get rid of it as well.

  4. Finally you will be left with just IBOutlets in MyCustomView.

  5. For better coding practice change the name from MyCustomView to MyCustomCell (optional)

  6. Go to your xib, select the xib and set its class as MyCustomView.

Sample Image


  1. In the same screen change file owner to yourView controller hosting collectionView

Sample Image


  1. In ViewDidLoad of your viewController register your nib.
self.collectionView.registerNib(UINib(nibName: "your_xib_name", bundle: nil), forCellWithReuseIdentifier: "your_reusable_identifier")

  1. In cellForItemAtIndexPath,
let cell : MyCustomView = collectionView.dequeueReusableCellWithReuseIdentifier("your_reusable_identifier", forIndexPath: indexPath) as! MyCustomView
cell.lblName.text = "bla bla" //access your Cell's IBOutlets
return cell

  1. Finally in order to control the size of cell either override the delegate of collectionView or simply go to your collectionView select the collectionCell in it and drag it to match your dimension :) Thats it :)

Happy coding. Search tutorials for better understanding. I can't explain all delegates as I'll end up writing a blog here.

Happy coding

UICollectionView inside UIView Nib

In case of adding a collection view/ table view in a UIView with separated .xib file, you should also create a separated .xib custom cell.

In your UIView Custom class, you should implement register(_:​for​Cell​With​Reuse​Identifier:​), for example:

// collectionView is the IBOutlet for the collection view that exists in the view .xib file
collectionView.register(UINib(nibName: "CustomCollectionViewCell", bundle: nil), forCellReuseIdentifier: "CustomCollectionViewCell")

And you will be good to go.

How to create outlet from collection cell xib file to collection view controller

You can't do that.
You can't create an outlet that references a UITextField placed inside a custom CollectionViewCell in your CollectionViewController.

What you can do is create an outlet that references the UITextField in your .xib in the respective CollectionViewCell .swift class (1), create an outlet that references your collectionView in the CollectionViewController (2), and use these CollectionViewCells in your collectionView (3).

You can then access the UITextField of a specific CollectionViewCell in your CollectionViewController through the cell itself (3), like for instance with:

let indexPath = IndexPath(row: 2, section: 0)
let cell = self.collectionView.cellForItemAtIndexPath(indexPath) as! CollectionViewCell // so the compiler knows that the cell you are referring to is of type CollectionViewCell and thus has your custom textField property

let textInTextField = cell.textField.text

(1)

Sample Image

(2)

Sample Image

(3)

Sample Image

Strange UIView in a UICollectionViewCell created from nib

It's the contentView of the cell – see the documentation.

Your subviews should be added to the contentView rather than the cell directly, where they are currently. This has happened because your nib is a plain UIView which doesn't contain the contentView property.

What you need to do is design your nib with a UICollectionViewCell object, by simply dragging the appropriate object into the interface builder:

image



Related Topics



Leave a reply



Submit