How to Add an Uicollectionviewlayout Programmatically

Creating a UICollectionView programmatically

Header file:--

@interface ViewController : UIViewController<UICollectionViewDataSource,UICollectionViewDelegateFlowLayout>
{
UICollectionView *_collectionView;
}

Implementation File:--

- (void)viewDidLoad
{
[super viewDidLoad];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
_collectionView=[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
[_collectionView setDataSource:self];
[_collectionView setDelegate:self];

[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[_collectionView setBackgroundColor:[UIColor redColor]];

[self.view addSubview:_collectionView];

// Do any additional setup after loading the view, typically from a nib.
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return 15;
}

// The cell that is returned must be retrieved from a call to -dequeueReusableCellWithReuseIdentifier:forIndexPath:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:@"cellIdentifier" forIndexPath:indexPath];

cell.backgroundColor=[UIColor greenColor];
return cell;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
return CGSizeMake(50, 50);
}

Output---

Sample Image

UICollectionView Programmatically

You need to use UICollectionViewController's designated intialiser as below.

let layout = UICollectionViewLayout()
let homeViewController = HomeController(collectionViewLayout: layout)
window?.rootViewController = UINavigationController(rootViewController: homeViewController)

Along with that, you will need to modify you HomeViewController to implement UICollectionViewDataSource required methods.

override func viewDidLoad() {
super.viewDidLoad()

// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false

// Register cell classes
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "Cell")

// Do any additional setup after loading the view.
}

// MARK: UICollectionViewDataSource

override func numberOfSections(in collectionView: UICollectionView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}

override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of items
return 0
}

override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)

// Configure the cell

return cell
}

How can I programmatically make a UICollectionView fill a UITableViewCell?

In your code you have added just 1 constraint - bottomAnchor. Autolayout doesn't work like that. Just add all the required constraints after adding UICollectionView as subview of UITableViewCell, i.e.

override init(style: UITableViewCellStyle, reuseIdentifier: String?)
{
super.init(style: style, reuseIdentifier: reuseIdentifier)

self.collectionViewLayout = UICollectionViewFlowLayout()
self.collectionViewLayout.sectionInset = UIEdgeInsets(top: 1.0, left: 1.0, bottom: 1.0, right: 1.0)
self.collectionViewLayout.scrollDirection = .vertical

let frame = CGRect(x: 0.0, y: 0.0, width: self.frame.width, height: self.frame.height)
self.collectionView = UICollectionView(frame: frame, collectionViewLayout: self.collectionViewLayout)
self.collectionView?.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(self.collectionView!)

NSLayoutConstraint.activate([
self.collectionView!.topAnchor.constraint(equalTo: self.topAnchor),
self.collectionView!.bottomAnchor.constraint(equalTo: self.bottomAnchor),
self.collectionView!.leftAnchor.constraint(equalTo: self.leftAnchor),
self.collectionView!.rightAnchor.constraint(equalTo: self.rightAnchor),
])

self.collectionView?.dataSource = self
self.collectionView?.delegate = self
}

How to create UICollectionViewCell programmatically

Your problem lies here. In your viewDidLoad(), you're registering your collectionView cell twice. You are registering the collectionview's cell to your custom cell class in the first line and then in the second line you are registering it to the class UICollectionViewCell.

 collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: cellReuseIdentifier)
collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "collectionCell")

Just remove the second line and your code should work.

How can I programmatically insert UICollectionView into UITableViewCell ? [Swift]

  1. declare collectionView in the TableViewCell swift file.

    var viewPhotos: UICollectionView!

    func reset(with cellData: CellData) {
    self.data = cellData
    viewPhotos.dataSource = self
    viewPhotos.delegate = self
    viewPhotos.reloadData()
    }
  2. in the init function or awakeFromNib check if photoCollectionView is initialized and add it to the cell.

let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
viewPhotos = UICollectionView(frame: self.bounds, collectionViewLayout: layout)
viewPhotos.collectionViewLayout = layout
viewPhotos.showsHorizontalScrollIndicator = false
viewPhotos.isPagingEnabled = true
viewPhotos.register(PhotoCollectionViewCell.self, forCellWithReuseIdentifier: PhotoCollectionViewCell.cellIdentifier)

  1. Add UICollectionView Datasource and Delegate To the UITableViewCell
extension TableViewCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {  

func collectionView(_ collectionView: UICollectionView,numberOfItemsInSection > section: Int) -> Int {
return photoUrls?.count ?? 0
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: PhotoCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: PhotoCollectionViewCell.cellIdentifier, for: indexPath) as! PhotoCollectionViewCell

if let value = photoUrls {
cell.reset(with url: value[indexPath.row]);
}
return cell
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: kPhotoWidth, height: kPhotoHeight)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

return UIEdgeInsets.init(top: 0, left: 0, bottom: 0, right: 0)

}

func collectionView(_ collectionView: UICollectionView, layout > collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return 0.0
}

}

  1. PhotoCollectionViewCell

create a PhotoCollectionViewCell derived from UICollectionViewCell
and add a UIImageView, and make all edge constraints to 0 to the
superview. load UIImageView based on photoUrl.

Programmatically placing collectionView in view

because I subtract the height of the different elements on the view from the total height of the view

But you don’t know the total height of the view. That’s the problem.

You are calling loadCollectionView in viewDidLoad. That is way too early, because nothing has its correct frame yet. Therefore all your calculations to calculate the frame of the collection view, based on the frame of other things, are incorrect.

You could solve this by waiting until viewDidLayoutSubviews to call loadCollectionView, but don't. You shouldn't be calculating frames at all! Instead, do everything with autolayout and let the autolayout engine do the layout for you. That way, you can do the construction in viewDidLoad without any frame values coming into play.



Related Topics



Leave a reply



Submit