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.
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---
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
}
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
}
Creating UICollectionView programmatically (outside of UIViewController)
You can declare your CollectionView as
class AlbumPlayerProgressBar: UICollectionView, UICollectionViewDataSource {
var progressBarType :ProgressBarType = .Player
var numOfSlides: Int = 0
var numOfPlayingSlide: Int = 0
override func awakeFromNib() {
super.awakeFromNib()
//gets called when you instantiate your collectionView from xib
self.register(UINib(nibName: NSStringFromClass(ProgressBarCell.self), bundle: nil), forCellWithReuseIdentifier: NSStringFromClass(ProgressBarCell.self))
self.dataSource = self
}
override init(frame: CGRect, collectionViewLayout layout: UICollectionViewLayout) {
super.init(frame: frame, collectionViewLayout: layout)
self.register(UINib(nibName: NSStringFromClass(ProgressBarCell.self), bundle: nil), forCellWithReuseIdentifier: NSStringFromClass(ProgressBarCell.self))
self.dataSource = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.register(UINib(nibName: NSStringFromClass(ProgressBarCell.self), bundle: nil), forCellWithReuseIdentifier: NSStringFromClass(ProgressBarCell.self))
self.dataSource = self
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return numOfSlides
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(ProgressBarCell.self), for: indexPath) as! ProgressBarCell
cell.setType(self.progressBarType)
if (indexPath.row < numOfPlayingSlide)
{
cell.setPlayed()
}
else if (indexPath.row == numOfPlayingSlide)
{
cell.setPlaying()
}
else
{
cell.setUnplayed()
}
return cell
}
}
Depending on how would you initialize/instantiate collectionView decide where would like to register your nib and setting data source as self.
Hope it helps
How to create and use UIcollectionView programmatically?
There is not alternative to create or allocate cells in itemAtIndex method. We need to register the customised class to create any views inside the custom class. something like this :
[UICollectionView registerClass:[CustomCollectionViewClass class] forCellWithReuseIdentifier:@"cellIdentifier"];
here is the best link which I found useful. Hope it helps others
Related Topics
How to Programmatically Send Sms on the Iphone
Vertically Align Text to Top Within a Uilabel
Split a String into an Array in Swift
How to Set Up a Simple Delegate to Communicate Between Two View Controllers
Ios Uiimagepickercontroller Result Image Orientation After Upload
Getting the Difference Between Two Dates (Months/Days/Hours/Minutes/Seconds) in Swift
How to Export Uiimage Array as a Movie
How to Take a Screenshot Programmatically on Ios
Set the Maximum Character Length of a Uitextfield
Hide Strange Unwanted Xcode Logs
How to Get My Ip Address Programmatically on Ios/Macos
Load Resources from Relative Path Using Local HTML in Uiwebview
How to Change Navigation Bar Color in iOS 7
How to Validate an Url on the Iphone
Difference Between Observedobject and Stateobject in Swiftui