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---
iOS - How to init and insert UICollectionViewCell programmatically when data is ready?
I am unable to get a clear picture of the code and specific requirements of your AdSDK. So i will go ahead and write a pseudo code as per my understanding of what needs to be done. Here is what I purpose, instead of calling adFactory.loadAds()
into the UICollectionViewCell
object, you can perform this task into a different class object. Let say AdLoader
So your add loader should be something like this.
class Adloader {
var adFactory = AdsSDKFactory()
typealias adLoadCompletionHandler = (adView: AdsObject) -> Void
var loadCompletion
func initLoader() {
//Set some properties for the Ads SDK
adFactory.nativeDelegate = self
// method from the SDK to request the Ad
adFactory.loadAds()
}
}
Once the ad is loaded, you can use a completion handler to get update the collection view.
func adObjectDidLoad(adView: AdsObject!) {
adLoadCompletionHandler(adView)
}
So your code can be something like this.
if (needToInsertAd) {
var newAd = Adloader.initLoader()
newAd.adLoadCompletionHandler {
//Code to insert cell at indexpath
}
}
Hope this helps you.
Program UICollectionViewCell Programmatically
The size of the cell is not known when the init method is called. So setting the width and height to contentView.bounds.size.width
and contentView.bounds.size.height
won't work.
Instead of adding constraints for horizontal and vertical sizes you can add left, right, top and bottom constraints, like this:
let productCategoryImageViewHorizontalConstrain = NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[productCategoryImageViewKey]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: subViewDictionary)
let productCategoryImageViewVerticalConstrain = NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[productCategoryImageViewKey]-0-|", options: NSLayoutFormatOptions(rawValue: 0), metrics: nil, views: subViewDictionary)
And you should also call contentView.addSubview(productCategoryImageView)
before adding the constraints.
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
}
Create UICollectionViewCell programmatically without nib or storyboard
Its not necessary to use Storyboard/Xib for the CollectionViewCell. You can even create it programmatically. Subclass UICollectionViewCell
and write up the code for the cell. Then in CollectionView controller class you have to register you custom cell class with the collectionView
[self.collectionView registerClass:[CustomCollectionViewCell class] forCellWithReuseIdentifier:CELL_ID];
You can have different cell class if you are using different type cells. Reuse identifier should be unique.
In cellForItemAtIndexPath use the proper identifier to dequeue
[collectionView dequeueReusableCellWithReuseIdentifier:CELL_ID forIndexPath:indexPath];
Related Topics
Swift: Double Conversion Inconsistency. How to Correctly Compare Doubles
Swiftui: How to Make Entire Shape Recognize Gestures When Stroked
Animating a Navigation Bar Color
Gcd with Static Functions of a Struct
How to Use a Variadic Closure in Swift
How to Loop Through an Array from the Second Element in Elegant Way Using Swift
Why Is Calendar.Date(From: Datecomponents) Adding Time
Extension for Generic Type 'Unsafemutablepointer<Uint8>'
How Are Hash Collisions Handled
Swift Combine How to Skip an Event
Swift: Using "/" Slash in Filename with Createdirectoryatpath
Adding Items to Array as a Dictionary Value
How to Delete an Item in a Collection View with a Button in the Cell
Map and Flatmap Difference in Optional Unwrapping in Swift 1.2