how to create custom UICollectionViewCell - objective-c

I have a UICollectionView and Im trying to set a label and an image in the collectionViewCell. Unfortunately I cant seem to get any labels to display or anything else for that matter.
Here is my code:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
}
Unfortunately no label is being displayed and neither is the text in the label.
Updated: I've added the rest of the code from this class file.
#import "ContainerListController.h"
#import "ContainerController.h"
#import "ContainerList.h"
#implementation ContainerListController
//Deallocate temp variables
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//Initiate objects
- (id)init {
if (self = [super initWithTitle:LocStr(#"CONTAINER_LIST_TITLE") navBarHidden:NO]) {
m_paths = [ContainerList shared].paths;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(onContainerListDidChange)
name:kSDKLauncherContainerListDidChange object:nil];
}
return self;
}
//Load all the views.
- (void)loadView {
//Allocate a UI view
self.view = [[UIView alloc] init];
//Create flow layout
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
//Force Horizontal Scroll
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
layout.minimumInteritemSpacing =[[UIScreen mainScreen] bounds].size.width;
layout.minimumLineSpacing=0.0;
//Create Collection
UICollectionView *coll =[[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
//Allocations
m_coll = coll;
coll.dataSource =self;
coll.delegate =self;
coll.pagingEnabled = YES;
coll.collectionViewLayout = layout;
//Customize Cells
[coll registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[coll setBackgroundColor:[UIColor orangeColor]];
[layout invalidateLayout];
//Create the subview
[self.view addSubview:coll];
//set minimum spacing
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
layout.minimumLineSpacing = 100.0f;
layout.minimumInteritemSpacing = 100.0f;
}
else{
layout.minimumLineSpacing = 40.0f;
layout.minimumInteritemSpacing = 40.0f;
}*/
//Old Layout
//UITableView *table = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
//m_table = table;
//table.dataSource = self;
//table.delegate = self;
//[self.view addSubview:table];
}
- (void)onContainerListDidChange {
m_paths = [ContainerList shared].paths;
[m_table reloadData];
[m_coll reloadData];
}
//Debugging components function
/*-(void)printComps:(NSArray* ) components{
for (NSInteger i =0; i<16; i++) {
NSString * item;
item=components[i];
}
}*/
//old tableview cell
- (UITableViewCell *)
tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:nil];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
cell.textLabel.text = (components == nil || components.count == 0) ?
#"" : components.lastObject;
return cell;
}
//Old tableView
- (void)
tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if (c != nil) {
[self.navigationController pushViewController:c animated:YES];
}
NSLog(#"Selected an item");
}
//old TableView count for epubs
- (NSInteger)
tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section{
return m_paths.count;
}
- (void)viewDidLayoutSubviews {
//m_table.frame = self.view.bounds;
m_coll.frame = self.view.bounds;
}
//Collection View Cell Data Allocation
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *issue = [[UILabel alloc] initWithFrame:CGRectMake(0,10,cell.bounds.size.width,40)];
//UICollectionViewCell *content = [[UICollectionViewCell alloc] init];
if(indexPath.item %2 == 0){
cell.backgroundColor=[UIColor blueColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
else {
cell.backgroundColor=[UIColor redColor];
issue.text = #"Some Text";
issue.textColor = [UIColor greenColor];
issue.textAlignment = NSTextAlignmentCenter;
}
NSString *path = [m_paths objectAtIndex:indexPath.row];
NSArray *components = path.pathComponents;
NSString *Title = components.lastObject;
NSLog(#"Title: %#",Title);
NSString *Titletest = components.lastObject;
NSInteger comp1 = components.count;
NSString *comps = #"components";
NSLog(#"There are: %ld %#", (long)comp1,comps);
NSLog(#"Title: %#",Titletest);
for (NSInteger i =0; i<15; i++) {
NSString * item;
item=components[i];
NSLog(#"Component:%ld %#",(long)i,components[i]);
}
return cell;
}
//Collection View Cell Data De-Allocation
- (void)
collectionView:(UICollectionView *)collectionView
numberofItemsInSection:(NSIndexPath *)indexPath{
[collectionView deselectItemAtIndexPath:indexPath animated:YES];
NSString *path = [m_paths objectAtIndex:indexPath.row];
ContainerController *c = [[ContainerController alloc] initWithPath:path];
if(c !=nil){
[self.navigationController pushViewController:c animated:YES];
}
}
//Collection
-(NSInteger)
collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section{
return m_paths.count;
}
//Set Collection View Cell Size
-(CGSize)
collectionView:(UICollectionView *) collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
//Set Landscape size of cells
/*if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-360;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-60;
NSLog(#"Is Landscape");
return CGSizeMake(cellWidth, cellHeigt);
}
//Set Potrait size of cells
else{
CGFloat cellWidth = [[UIScreen mainScreen] bounds].size.width-60;
CGFloat cellHeigt = [[UIScreen mainScreen] bounds].size.height-160;
NSLog(#"Is Portrait");
return CGSizeMake(cellWidth, cellHeigt);
}*/
return CGSizeMake(collectionView.bounds.size.width, collectionView.bounds.size.height);
}
//Collection View Cell Position
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)){
return UIEdgeInsetsMake(150.0,0.0,150.0,0.0); // top, left, bottom, right
}
else{
return UIEdgeInsetsMake(20.0,0.0,0.0,0.0); // top, left, bottom, right
}
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[m_coll performBatchUpdates:nil completion:nil];
}
-(void)viewWillTransitionToSize:withTransitionCoordinator{
[m_coll performBatchUpdates:nil completion:nil];
}
/*-(CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)
collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section{
CGFloat cellSpacing = ((UICollectionViewFlowLayout *) collectionViewLayout).minimumLineSpacing;
CGFloat cellWidth = ((UICollectionViewFlowLayout *) collectionViewLayout).itemSize.width;
NSInteger cellCount = [collectionView numberOfItemsInSection:section];
CGFloat inset = (collectionView.bounds.size.width - ((cellCount-1) * (cellWidth + cellSpacing))) * 0.5;
inset = MAX(inset, 0.0);
if(UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
NSLog(#"Changed to landscape Spacing");
return inset;
}
else{
return inset;
}
}*/
#end

Clear example to use custom collectionViewCell.
Create a separate class subclass ofUICollectionViewCell see below code:
.h file:
#import <UIKit/UIKit.h>
#interface CollectionViewCell : UICollectionViewCell
#property (weak, nonatomic) IBOutlet UILabel *customLabel;
#end
.m file:
#import "CollectionViewCell.h"
#implementation CollectionViewCell
#end
Now drag and drop the collectionView inside viewController using storyboard then by selecting cell set custom class for it and connect its IBOutlet of label see below image.
Setting up custom class:
Connecting label's outlet: if adding label and other ui component from storyboard
Note: Drag uilabel inside cell before you connect its IBOutlet.
Now configure cell inside your viewController class. And configure collectionView correctly by connecting its delegate, dataSuorce and IBOutlet.
#import "ViewController.h"
#import "CollectionViewCell.h"
#interface ViewController (){
// instance variable deceleration part
NSMutableArray *yourArray;
}
#end
#implementation ViewController
- (void)viewDidLoad{
[super viewDidLoad];
_yourCollView.delegate = self;
_yourCollView.dataSource = self;
yourArray = [[NSMutableArray alloc] initWithObjects:#"1st cell",#"2nd cell",#"3rd cell",#"4th cell", nil];
// Do any additional setup after loading the view, typically from a nib.
}
// collection view delegate methods
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [yourArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"MyCustomCell" forIndexPath:indexPath];
// configuring cell
// cell.customLabel.text = [yourArray objectAtIndex:indexPath.row]; // comment this line if you do not want add label from storyboard
// if you need to add label and other ui component programmatically
UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, cell.bounds.size.height)];
label.tag = 200;
label.text = [yourArray objectAtIndex:indexPath.row];
// this adds the label inside cell
[cell.contentView addSubview:label];
return cell;
}
//Note: Above two "numberOfItemsInSection" & "cellForItemAtIndexPath" methods are required.
// this method overrides the changes you have made to inc or dec the size of cell using storyboard.
- (CGSize)collectionView:(UICollectionView *)collectionView layout: (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
return CGSizeMake(100, 100);
}
} // class ends
Setup the cell identifier (by selecting a cell) MyCustomCell you have given inside cellForItemAtIndexPath method before use see below image:
Note: Change the text color of uilabel to white before because by default collectionView appears black.
Hope here you understand.

Create subclass of UICollectionViewCell. For instance TestCollectionViewCell.
In Storyboard drag label in cell and set "Custom class" for this UICollectionViewCell with your created class. Set Reusable identifier, if your collection view in UIViewController don't forget to set DataSource and Delegate for that collectionView.
Connect IBOutlet in your Cell subclass.
Set at least 1 value inside numberOfItemsInSection method.
Then use your subclass of cell in cellForItemAt and try set text for a label.

You are missing the:
[cell.contentView addSubview:issue];

Related

Avoiding UICollectionViewCell re-selection during reuse (from cell's prepareForResue) 'apparently' deselects the original cell as well

In my collection view when (custom) cells are reused they, again, get the highlight I have set in didSelectItemAtIndexPath for the original selection. To prevent this, I am using the custom cell's prepareForReuse method, and post calling [super], I check to see if its the selected cell.
If it is I am change the highlight to default else I restore to the original selection highlight when the cell in question is brought back in scroll view's visible area.
Here's the code...
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
But I notice that the second if block is never executed even when I bring back the original cell in view. This is where I need help. How do I ensure re-highlighting or the original cell/item?
Note, if I try and save the original cell- even though not highlighted, remains the one selected and the corresponding value is saved.
So, this is just about the re-highlight.
Also, here is the selection code...* didSelectItemAtIndexPath*
- (void)collectionView:(UICollectionView *)collectionView
didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath!=nil) {
if (indexPath.row==selectedIndexPath.row)
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor clearColor];
selectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath=nil;
[newDictionary setValue:[NSNull null] forKey:#"type"];
}
else
{
[tagCollectionView deselectItemAtIndexPath:indexPath animated:YES];
TagCollectionViewCell *previousSelectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
previousSelectedCell.backgroundColor = [UIColor systemBackgroundColor];
previousSelectedCell.tagImageView.tintColor = [UIColor systemBlueColor];
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
else if (selectedIndexPath==nil)
{
selectedIndexPath = indexPath;
TagCollectionViewCell *selectedCell = (TagCollectionViewCell *)[tagCollectionView cellForItemAtIndexPath:selectedIndexPath];
selectedCell.backgroundColor = [UIColor systemBlueColor];
selectedCell.tagImageView.tintColor = [UIColor systemBackgroundColor];
dictionaryType = _typesArray[selectedIndexPath.row];
[newDictionary setValue:dictionaryType forKey:#"type"];
}
}
Any help? Thanks.
Edit:
This is the part of the code that doesn't get called.
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
I think you are way over-complicating things.
A UICollectionView keeps track of its own "selected" cell(s), and calls setSelected on each cell when it is displayed.
You can put all of your "selected" appearance code inside your cell class:
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
self.tagImageView.tintColor = selected ? UIColor.systemBackgroundColor : UIColor.systemBlueColor;
self.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
Now you don't need to do anything in didSelectItemAt.
Here's a quick example...
SampleCollectionViewCell.h
#interface SampleCollectionViewCell : UICollectionViewCell
- (void)fillData:(NSInteger)n;
#end
SampleCollectionViewCell.m
#import "SampleCollectionViewCell.h"
#interface SampleCollectionViewCell ()
{
UIImageView *theImageView;
UILabel *theLabel;
}
#end
#implementation SampleCollectionViewCell
- (instancetype)init
{
self = [super init];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self commonInit];
}
return self;
}
- (instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
[self commonInit];
}
return self;
}
- (void)commonInit {
// add an image view and a label
theImageView = [UIImageView new];
theImageView.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theImageView];
theLabel = [UILabel new];
theLabel.textAlignment = NSTextAlignmentCenter;
theLabel.font = [UIFont systemFontOfSize:20.0 weight:UIFontWeightBold];
theLabel.translatesAutoresizingMaskIntoConstraints = NO;
[self.contentView addSubview:theLabel];
[NSLayoutConstraint activateConstraints:#[
[theImageView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:0.0],
[theImageView.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theImageView.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theImageView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:0.0],
[theLabel.leadingAnchor constraintEqualToAnchor:self.contentView.leadingAnchor constant:0.0],
[theLabel.trailingAnchor constraintEqualToAnchor:self.contentView.trailingAnchor constant:0.0],
[theLabel.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-4.0],
]];
// image would probably be set by the data source, but
// for this example we'll use the same system image in every cell
UIImage *img = [UIImage systemImageNamed:#"person.fill"];
if (img) {
theImageView.image = img;
}
// let's give the content view rounded corners and a border
self.contentView.layer.cornerRadius = 8.0;
self.contentView.layer.borderWidth = 2.0;
self.contentView.layer.borderColor = UIColor.systemGreenColor.CGColor;
// default (not-selected) colors
theImageView.tintColor = UIColor.cyanColor;
theLabel.textColor = UIColor.blackColor;
self.contentView.backgroundColor = UIColor.systemBackgroundColor;
}
- (void)fillData:(NSInteger)n {
theLabel.text = [NSString stringWithFormat:#"%ld", (long)n];
}
- (void)setSelected:(BOOL)selected {
// change our color properties based on selected BOOL value
theImageView.tintColor = selected ? UIColor.redColor : UIColor.cyanColor;
theLabel.textColor = selected ? UIColor.yellowColor : UIColor.blackColor;
self.contentView.backgroundColor = selected ? UIColor.systemBlueColor : UIColor.systemBackgroundColor;
}
#end
SampleViewController.h
#interface SampleViewController : UIViewController <UICollectionViewDelegate, UICollectionViewDataSource>
#end
SampleViewController.m
#import "SampleViewController.h"
#import "SampleCollectionViewCell.h"
#interface SampleViewController ()
{
UICollectionView *collectionView;
}
#end
#implementation SampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *fl = [UICollectionViewFlowLayout new];
fl.scrollDirection = UICollectionViewScrollDirectionVertical;
fl.itemSize = CGSizeMake(60, 60);
fl.minimumLineSpacing = 8;
fl.minimumInteritemSpacing = 8;
collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:fl];
collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:collectionView];
UILayoutGuide *g = [self.view safeAreaLayoutGuide];
[NSLayoutConstraint activateConstraints:#[
// constrain collection view 40-points from all 4 sides
[collectionView.topAnchor constraintEqualToAnchor:g.topAnchor constant:40.0],
[collectionView.leadingAnchor constraintEqualToAnchor:g.leadingAnchor constant:40.0],
[collectionView.trailingAnchor constraintEqualToAnchor:g.trailingAnchor constant:-40.0],
[collectionView.bottomAnchor constraintEqualToAnchor:g.bottomAnchor constant:-40.0],
]];
[collectionView registerClass:SampleCollectionViewCell.class forCellWithReuseIdentifier:#"c"];
collectionView.dataSource = self;
collectionView.delegate = self;
// let's give the collection view a very light gray background
// so we can see its frame
collectionView.backgroundColor = [UIColor colorWithWhite:0.95 alpha:1.0];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 50;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
SampleCollectionViewCell *c = (SampleCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
[c fillData:indexPath.item];
return c;
}
#end
Based on the code you posted, it looks like you want to be able to de-select an already selected cell. If so, add this to the controller:
// this allows us to de-select an already selected cell
- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath {
// get array of already selected index paths
NSArray *a = [collectionView indexPathsForSelectedItems];
// if that array contains indexPath, that means
// it is already selected, so
if ([a containsObject:indexPath]) {
// deselect it
[collectionView deselectItemAtIndexPath:indexPath animated:NO];
return NO;
}
// no indexPaths (cells) were selected
return YES;
}
When run, it starts like this:
Tapping cell "1" selects it:
Tapping cell "7" automatically de-selects cell "1" and selects cell "7":
We can scroll up and down and the selected cell will automatically maintain its "selected appearance":
Edit
To explain why your prepareForReuse wasn't doing what you expected...
The collection view does not set the selected property of the cell until it is going to be displayed.
So, in:
- (void)prepareForReuse
{
[super prepareForReuse];
if (!self.isSelected) {
[self setBackgroundColor:[UIColor systemBackgroundColor]];
[_tagImageView setTintColor:[UIColor systemBlueColor]];
}
else if (self.isSelected)
{
[self setBackgroundColor:[UIColor systemBlueColor]];
[_tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
}
self.isSelected will never be true.
If you want to stick with changing the cell UI properties (colors, tint, etc) in didSelectItemAt, you need to update your cell appearance in cellForItemAt:
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
TagCollectionViewCell *c = (TagCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:#"c" forIndexPath:indexPath];
// whatever you are currently doing, such as
//c.tagImageView.image = ...;
if (selectedIndexPath != indexPath) {
[c setBackgroundColor:[UIColor systemBackgroundColor]];
[c.tagImageView setTintColor:[UIColor systemBlueColor]];
}
else
{
[c setBackgroundColor:[UIColor systemBlueColor]];
[c.tagImageView setTintColor:[UIColor systemBackgroundColor]];
}
return c;
}

Objective C Passing CGFloat value between two classes

I have a small problem ..
For convenience and to make you understand better how to share the collection View:
Collectionview 1 has the customized segment control function (it has a custom UICollectionView custom class)
Collectionview 2 contains the cells that function as pages (it has a UICollectionViewController class).
I have an UIViewController that contains the collectionview1 that I used to create a custom segment control (like a menu)
The cursor indicating which cell was selected was created with a uiview in the collectionView 1 class.
In my main view controller in addition to having a collectionview I also inserted a container view that contains a collectionview controller that will be used to show the selected pages through a horizontal scroll.
My problem now appears when I want to pass the ContentOffset value into the collectionView2 scrollViewDidScroll to the cursor in the collectionView 1.
I tried to initialize the collectionview 1 class in the collectionView 2 class to use the cursor directly but I do not get any results.
Can you help me understand how to solve this problem?
This is Class CollectionView 1 ( Menu )
-(instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setupControl];
}
return self;
}
-(void)setupControl {
self.delegate = self;
self.dataSource = self;
self.pagingEnabled = YES;
self.showsHorizontalScrollIndicator = NO;
UINib *nib = [UINib nibWithNibName:#"UDSectionNavCell" bundle: nil];
[self registerNib:nib forCellWithReuseIdentifier:#"SCC"];
[self layout];
_horizontalCursorBar = [[UDSectionNavCursor alloc] init];
_horizontalCursorBar.frame = CGRectMake(0, self.frame.size.height - 6, self.frame.size.width / 4, 3);
_horizontalCursorBar.layer.cornerRadius = 3;
_horizontalCursorBar.backgroundColor = [UIColor colorWithHexString:#"#C1C1C1" setAlpha:1];
_horizontalCursorBar.alpha = 1;
[self addSubview:_horizontalCursorBar];
NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:0];
[self selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone];
}
-(void)layout {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
layout.itemSize = CGSizeMake(self.frame.size.width / 4, self.frame.size.height);
layout.minimumInteritemSpacing = 10;
layout.minimumLineSpacing = 0;
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
self.collectionViewLayout = layout;
[self reloadData];
}
-(NSArray *)dataPage {
return [NSArray arrayWithObjects:#"ATENEO",#"STATISTICHE",#"CALENDARIO",#"NOTIFICHE", nil];
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self dataPage].count;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
static NSString *cellID = #"SCC";
UDSectionNavCell *cell = (UDSectionNavCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
cell.titlePage.text = [[self dataPage] objectAtIndex:indexPath.item];
return cell;
}
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSIndexPath *newIndexPath = [NSIndexPath indexPathForItem:indexPath.row inSection:0];
[self scrollToItemAtIndexPath:newIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
if (indexPath == newIndexPath) {
[self scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
[UIView animateWithDuration:.5 delay:0 usingSpringWithDamping:1 initialSpringVelocity:1 options:UIViewAnimationOptionCurveEaseOut animations:^{
CGFloat x = (indexPath.item) * self.frame.size.width / 4;
_horizontalCursorBar.frame = CGRectMake(x, self.frame.size.height - 6, self.frame.size.width / 4, 3);
} completion:nil];
}
This is the code of CollectionView 2 (page cell)
static NSString * const reuseIdentifier = #"Cell";
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:reuseIdentifier];
UICollectionViewFlowLayout *collectionLayout = [[UICollectionViewFlowLayout alloc] init];
collectionLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
collectionLayout.minimumLineSpacing = 0;
self.collectionView.collectionViewLayout = collectionLayout;
[self.collectionView reloadData];
self.collectionView.pagingEnabled = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
#pragma mark <UICollectionViewDataSource>
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4;
}
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
return CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
NSArray *array = [NSArray arrayWithObjects:[UIColor redColor],[UIColor blueColor], [UIColor clearColor], [UIColor grayColor], nil];
cell.backgroundColor = array[indexPath.item];
return cell;
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
NSLog(#"%f",scrollView.contentOffset.x / 4);
}
I would need to pass the ContentOffset value of the scrollViewDidScroll method in the collectionView 2 class and use it in the collectionView class 1

UILabel will does not show up in collectionView Cell

I have a collectionView that will display a cell from the dataArray. The dataArray is changed to self.postsArray or self.eventsArray from a segmentControl as well as the reuseIdentifier to determine the cell(a post cell and a event cell). The events work fine, but the Post Cell, which contains a label with a tag of 95, does not work. When I NSLog(#"label: %#", label); I get nil. So i have no idea what the problem is.
#pragma mark Collection View:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [dataArray count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
if (dataArray == self.postsArray) {
UILabel *label = (UILabel *)[cell viewWithTag:95];
[label.text isEqualToString:#"Hello"];
NSLog(#"label: %#", label);
return cell;
}
if (dataArray == self.eventsArray) {
PFObject *temp = [dataArray objectAtIndex:indexPath.row];
UIButton *eventButton = (UIButton *) [cell viewWithTag:10];
NSLog(#"Event: %#", eventButton);
UIButton *groupButton = (UIButton *) [cell viewWithTag:11];
[eventButton setTitle:[temp objectForKey:#"Title"] forState:UIControlStateNormal];
[groupButton setTitle:[temp objectForKey:#"Group_Name"] forState:UIControlStateNormal];
eventButton.tag = indexPath.row;
groupButton.tag = indexPath.row;
return cell;
}
return cell;
}
#pragma mark SegmentControl:
- (void) segmentChanged: (id) sender{
UISegmentedControl *seg = (UISegmentedControl *) sender;
if (seg.selectedSegmentIndex == 0) {
dataArray = self.postsArray;
reuseIdentifier = #"postsCell";
[self.collectionView reloadData];
}
if (seg.selectedSegmentIndex == 1) {
dataArray = self.eventsArray;
reuseIdentifier = #"eventCell";
[self.collectionView reloadData];
}
}
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:groupReuseIdentifier]; was left in my viewDidLoad and was hiding my first cells

how to create image in cell table view

I want create one page in way table view. its display 4 cell that different image and name for any cell. (this information get url in loop)
first : I create one class that I can meaning 2 variable.
Recipe.h
#import
#interface Recipe : NSObject
#property (nonatomic, strong) NSString *name; // name of recipe
#property (nonatomic, strong) NSString *imageFile; // image filename of recipe
#end so now in RecipeViewController (root) I write this code :
#import "RecipeViewController.h"
#import "Recipe.h"
#interface RecipeViewController ()
{
IBOutlet UIImageView *ab;
}
#end
#implementation RecipeViewController
{
NSMutableArray *recipes;
NSInteger num;
}
#synthsize ab;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.title = #"Recipe Book";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil
action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
NSString *numberbook = [[NSString alloc]initWithContentsOfURL:[NSURL
URLWithString:#"http://192.168.1.102/mamal/book.php?all"]];
NSInteger numbook = [numberbook integerValue];
NSMutableArray *b = [[NSMutableArray alloc]initWithCapacity:numbook];
for (int i = 1; i <= numbook; i++)
{
Recipe *si = [Recipe new];
NSLog(#"%d,%#",i,si);
NSString *c = [[NSString alloc]initWithContentsOfURL:[NSURL URLWithString:[NSString
stringWithFormat:#"http://192.168.1.102/mamal/book.php?info=1&b=%d",i]]];
NSString *a = [NSString stringWithFormat:#"http://192.168.1.102/mamal/book.php?p=1&b=%d",i];
[b addObject:a];
UIImage *myImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:a]]];
[ab setImage:myImage];
NSLog(#"%#",a);
NSLog(#"%#",c);
si.name = [NSString stringWithString:c];
si.imageFile =[]; //I so confused!!!
if(!recipes){
recipes = [NSMutableArray array];
}
[recipes addObject:si];
}
num = numbook;
// Remove table cell separator
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
// Assign our own backgroud for the view
self.parentViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"common_bg"]];
self.tableView.backgroundColor = [UIColor clearColor];
// Add padding to the top of the table view
UIEdgeInsets inset = UIEdgeInsetsMake(5, 0, 0, 0);
self.tableView.contentInset = inset;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return recipes.count;
}
- (UIImage *)cellBackgroundForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger rowCount = [self tableView:[self tableView] numberOfRowsInSection:0];
NSInteger rowIndex = indexPath.row;
UIImage *background = nil;
if (rowIndex == 0) {
background = [UIImage imageNamed:#"cell_top.png"];
} else if (rowIndex == rowCount - 1) {
background = [UIImage imageNamed:#"cell_bottom.png"];
} else {
background = [UIImage imageNamed:#"cell_middle.png"];
}
return background;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
// Display recipe in the table cell
Recipe *recipe = [recipes objectAtIndex:indexPath.row];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [UIImage imageNamed:recipe.imageFile];
UILabel *recipeNameLabel = (UILabel *)[cell viewWithTag:101];
recipeNameLabel.text = recipe.name;
UILabel *recipeDetailLabel = (UILabel *)[cell viewWithTag:102];
recipeDetailLabel.text = recipe.detail;
// Assign our own background image for the cell
UIImage *background = [self cellBackgroundForRowAtIndexPath:indexPath];
UIImageView *cellBackgroundView = [[UIImageView alloc] initWithImage:background];
cellBackgroundView.image = background;
cell.backgroundView = cellBackgroundView;
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
#end
I so confused and get this error :
"connection cannot have a prototype object as its destination"
also I don't know one way for display image in cell!!!
cell.imageView.image = yourImage
Try this
cell.yourImage.image = [UIImage imageNamed:#"imageName"];

how to create dynamic TableCells for Tableview in ios

What I want to achieve is something like this. its kind of Facebook or twitter functionality where you have a tableview in which you have a Thread and the thread contains different number of articles. the number of articles varies in each row. So basically Its like i'm sending a post on facebook and people respond to that post and those posts are added under that particular Thread(I'm just concern about the How to display it every thing else is been taken care).here is the picture
I know how to create cell and all but I don't know how to set its size dynamically. any tutorial or any piece of advise to achieve this??
Any Help is appreciated..
thanks
Perhaps this will help you. I am sending you my code, I am using a Custom Cell , which having an Emial on first index, PhoneNumber on second index and Address on third index (in your case Article). I am dynamically changing the height of Address label in CellForRowAtIndexPath ,,, and also cell height in heightForRowAtIndexPath mehthod. Here is my code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = #"FeedCell";
FeedDetailCell *cell = (FeedDetailCell*)[tableView dequeueReusableCellWithIdentifier:identifier];
if (cell==nil) {
cell = (FeedDetailCell*)[[[NSBundle mainBundle] loadNibNamed:#"FeedDetail" owner:nil options:nil] objectAtIndex:0];
}
[tableView setSeparatorColor:[UIColor grayColor]];
switch (indexPath.section) {
case 0:
if (indexPath.row == 0) {
cell.nameLabel.text = #"Telephone";
[cell.detailLabel setText:[_feedDictionary valueForKey:#"mobile"]];
}
else {
cell.nameLabel.text = #"Mobile";
[cell.detailLabel setText:[_feedDictionary valueForKey:#"iPhone"]];
}
break;
case 1:
cell.nameLabel.text = #"E-mail";
[cell.detailLabel setText:[_feedDictionary valueForKey:#"Email"]];
break;
case 2:
cell.nameLabel.text = #"address";
[cell.detailLabel setText:[_feedDictionary valueForKey:#"address"]];
CGSize size = [[_feedDictionary valueForKey:#"address"] sizeWithFont:[UIFont systemFontOfSize:14.0]
constrainedToSize:CGSizeMake(200.0, 400.0) lineBreakMode:UILineBreakModeWordWrap];
CGRect frm = cell.detailLabel.frame;
frm.size.height = size.height;
[cell.detailLabel setFrame:frm];
default:
break;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 2) {
NSString *address = [_feedDictionary valueForKey:#"address"];
CGSize recommendedSize = [address sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(320, INT_MAX)];
return 44 + recommendedSize.height;
}
else {
return 44;
}
}
You can use this for dynamic cell height
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath;
you can use switch cases and check indexPath.row and indexPath.section to return the required height
take a custom UITableViewCell ,
in .h file
#interface PartnerCell : UITableViewCell {
UILabel *user_name,*lbldate,*lbldesc;
LoadImage *img_trade;
UIImageView *partnerimage;
}
#property (nonatomic, strong) UILabel *user_name,*lbldate,*lbldesc;
#property (nonatomic, strong) LoadImage *img_trade;
#property (nonatomic, strong) UIImageView *partnerimage;
#end
in .m file,
#import "PartnerCell.h"
#implementation PartnerCell
#synthesize user_name,lbldate,lbldesc;
#synthesize img_trade,partnerimage;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
[self setSelectionStyle:UITableViewCellSelectionStyleNone];
user_name = [[UILabel alloc] initWithFrame:CGRectMake(75,8,200,15)];
[user_name setBackgroundColor:[UIColor clearColor]];
user_name.font = [UIFont fontWithName:#"Arial-BoldMT" size:15];
[user_name setTextColor:[UIColor colorWithRed:70/255.00f green:70/255.00f blue:70/255.00f alpha:1.0]];
[self addSubview:user_name];
lbldate = [[UILabel alloc] initWithFrame:CGRectMake(75,28,200,15)];
[lbldate setBackgroundColor:[UIColor clearColor]];
lbldate.font = [UIFont fontWithName:#"Arial" size:14];
[lbldate setTextColor:[UIColor darkGrayColor]];
[self addSubview:lbldate];
lbldesc = [[UILabel alloc] initWithFrame:CGRectMake(75,45,170,35)];
[lbldesc setBackgroundColor:[UIColor clearColor]];
lbldesc.font = [UIFont fontWithName:#"Arial" size:13];
lbldesc.numberOfLines = 2;
[lbldesc setTextColor:[UIColor darkGrayColor]];
[self addSubview:lbldesc];
img_trade = [[LoadImage alloc] initWithFrame:CGRectMake(3, 5, 54, 55)];
img_trade.userInteractionEnabled = YES;
[self addSubview:img_trade];
}
return self;
}
in main table view class write this code,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"%#",[[Partarray objectAtIndex:indexPath.row-1] valueForKey:#"part_id"]];
cell = (PartnerCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell=nil;
if (cell == nil)
{
cell = [[PartnerCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[Partarray objectAtIndex:indexPath.row]] autorelease];
cell.selectionStyle= UITableViewCellSelectionStyleGray;
cell.backgroundColor = [UIColor clearColor];
cell.user_name.frame=CGRectMake(75,8,340,15);
cell.lbldate.frame=CGRectMake(75,28,340,15);
cell.lbldesc.frame=CGRectMake(75,45,340,35);
cell.user_name.text = #"user name";
cell.lbldate.text = #"date";
cell.lbldesc.text = #"description";
}
return cell;
}
take condition and add number of objects based on that condition.