how to load multiple cell from UITableViewCell - ios

I have one table that I want load from xib two cell.
in UITableViewCell xib file I have two cell (two part with tag 100 and 200) that I want load first view (first cell) in first row and load second cell in second row.
both cells are in xib file like this:
this is my code :
#pragma mark Table View Data Source Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 2;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section == 0) {
CustomCell *cell = (CustomCell *)[self.table dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil)
{
NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
NSLog(#"%#",topLevelObject);
cell = [topLevelObject objectAtIndex:0];
NSLog(#"%#",cell);
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
else if (indexPath.section == 1) {
CustomCell *cell2 = (CustomCell *)[self.table dequeueReusableCellWithIdentifier:#"Cell2"];
if (cell2 == nil)
{
NSArray *topLevelObject = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
for (id currentObject in topLevelObject) {
if ([currentObject isKindOfClass:[CustomCell class]]) {
cell2 = (CustomCell *)currentObject;
break;
}
}
}
cell2.selectionStyle = UITableViewCellSelectionStyleNone;
return cell2;
}
return nil;
}
I don't know where is my wrong because when run code I see only first cell in tableView

You are using first cell from XIB at section = 0
cell = [topLevelObject objectAtIndex:0];
so, in the same way you can get the second cell at index 1 for the section 1
cell = [topLevelObject objectAtIndex:1];

Related

UITableViewCell changes its label value every time I scroll

I have a reusableCell that has a label for which the values are supplied by an array. But the values of the label and the constraints change every time, my cellForRowAtIndexPath code looks like
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if(indexPath.row % 2 == 0)
{
isReceived =TRUE;
}
else{
isReceived = FALSE;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"id" forIndexPath:indexPath];
ChatMessageCellTableViewCell *messageCell = (ChatMessageCellTableViewCell*) cell;
if(messageCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatMessageCellTableViewCell" owner:self options:nil];
messageCell = [nib objectAtIndex:0];
}
else{
[[messageCell formLabel]setText:messages[indexPath.row]];
[messageCell setSelectionStyle:UITableViewCellSelectionStyleNone];
} // this else part is just to make sure that the if has a else part as I saw many people it will work , but in my case it didn't help.
[[self tableView] setEstimatedRowHeight:50.0];
[self.tableView setRowHeight:UITableViewAutomaticDimension];
return messageCell;
}
When I scroll the table, Values are changing. I tried many different way, but could not find a solution and I am so confused that I had to post my question.
Thank You
I know it's bad practice to answer your own post, but I hope this helps someone
I was able to avoid those changes by changing the method cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIdentifier = (indexPath.row % 2 == 0 ? #"EvenCell" : #"OddCell"); //using different identifier for every cell did the trick I guess
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
ChatMessageCellTableViewCell *messageCell = (ChatMessageCellTableViewCell*) cell; ;
if (messageCell == nil) {
messageCell = [[ChatMessageCellTableViewCell alloc] initWithStyle: UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
if(indexPath.row % 2 == 0)
{
isReceived =TRUE;
}
else{
isReceived = FALSE;
}
}
[[messageCell formLabel]setText:messages[indexPath.row]];
[messageCell setSelectionStyle:UITableViewCellSelectionStyleNone];
[[self tableView] setEstimatedRowHeight:50.0];
[self.tableView setRowHeight:UITableViewAutomaticDimension];
return messageCell;
}
I have commented the change's which I have made in order to prevent changes in the cell's while scrolling.
Thanks for all the support :)
There is a wrong logic in your code, your code is only assign data for reused cell but not for new created cell. You should move the code in else bracket out like this.
ChatMessageCellTableViewCell *messageCell = (ChatMessageCellTableViewCell*) cell;
if(messageCell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ChatMessageCellTableViewCell" owner:self options:nil];
messageCell = [nib objectAtIndex:0];
}
[[messageCell formLabel]setText:messages[indexPath.row]];
[messageCell setSelectionStyle:UITableViewCellSelectionStyleNone];
I'm not familiar with Obj-C, but this may helpful to you.
if youHaveTitleText {
cell.title.text = data.displayText
} else {
cell.title.text = ""
}

Customise single cell in UITableview

I would like to change the format of the first cell in my UITableView (masterViewController), so that the image stretches across thewidth of the whole cell and the text label is shown above the image. Also would like to add a second text label to this cell only?
Any help on how to do this would be great, I have looked without success for this particular problem and I am fairly new to UITableViews.
Make one custom cell as per your requirement and load it for indexpath.row== 0 and simple UITableViewCell for all other cells. hope it will helps you
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"CustomCell";
CustomCell *customcell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
static NSString * identifier = #"Cell";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if(indexPath.row == k)
{
if(customcell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
scrlcell = [nib objectAtIndex:0];
}
}
else{
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
}
if(indexPath.row == k)
return customcell;
else
return cell;
}
You should build a custom cell (you can build it in Interface builder) and then use it on your indexPath.row == 0. Like this:
static NSString *CellIdentifier = #"CellIdentifier";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
NSArray *topLevel = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:nil options:nil];
for (id currentObject in topLevel){
if ([currentObject isKindOfClass:[CustomCell class]])
{
cell = currentObject;
break;
}
}
}
if(indexPath.row == 0){
// Use your cell here
}else{
// Build a new cell
}
return cell;

Two NSMutableArrays in one UITableView with custom cells in iOS

In my iOS app, I am having two NSMutableArray
#implementation MyViewController {
NSMutableArray *arrOne;
NSMutableArray *arrTwo;
}
declared in my implementation file and one UITableView
#property (strong, nonatomic) IBOutlet UITableView *tableView;
declared inside MyController.h
What I want is to load both those array contents in the same table where arrOne content at first and arrTwo contants next.
Below is the way how I got number of table rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if ([arrOne count] > 0 && [arrTwo count] > 0) {
return [arrOne count] + [arrTwo count];
} else if ([arrTwo count] > 0) {
return [arrTwo count];
} else {
return 10;
}
}
and below is the place where I tried to create my table cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"myTable";
if ([arrOne count] > 0 && [arrOne count] > indexPath.row) {
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (defaultCell == nil) {
defaultCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
return defaultCell;
} else {
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
return cell;
}
}
With the above code, and assume arrOne has only one element, the tableView supposed to display first cell white and all others with my custom cell. Instead, it display, first cell white as expected and again some cells in the middle (5, 9, 13...) also in white. Cannot identify the reason yet. Any idea why?
If this is not the correct way of implementing two arrays in a single table view, what is it?
If arrOne contains only a single element (as you say it does) and arrTwo is empty, then you will have 10 total cells according to numberOfRowsInSection. The first cell will be a UITableViewCellStyleDefault cell, and the next 9 should be MyTableViewCell cells.
The reason you're seeing multiple UITableViewCellStyleDefault cells is because you're using the same cell identifier. Move your ID declaration inside each of the if/else statements and use a different identifier for each cell type.
if ([arrOne count] > 0 && [arrOne count] > indexPath.row) {
static NSString *defaultTableIdentifier = #"defaultReuse";
UITableViewCell *defaultCell = [tableView dequeueReusableCellWithIdentifier:defaultTableIdentifier];
if (defaultCell == nil) {
defaultCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:defaultTableIdentifier];
}
return defaultCell;
} else {
static NSString *simpleTableIdentifier = #"myCustomCellReuse";
MyTableViewCell *cell = (MyTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"MyTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
return cell;
}
(Also, is your Nib name different than the class name? MyTableViewCell vs MyTableCell. Because you declare a cell of the class MyTableViewCell and then load a nib named MyTableCell.)

Is it possible to have two different UiTableViewCells in one UiTableView? [duplicate]

This question already has answers here:
2 different types of custom UITableViewCells in UITableView
(3 answers)
Closed 9 years ago.
I'm having an issue and would like to know if what I am trying to do is even possible.
I have a ViewController that has a UITableView as a subview. I then loaded a custom cell and it worked fine. However, I needed another custom cell in the same tableview - this second cell has a separate nib as well.
Is this possible?
Two different custom cells in on section in a UITableView?
I did try something like this:
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
// Space Cell
if (indexPath.row== 0) {
CellSpace *cell = (CellSpace *) [tableViewdequeueReusableCellWithIdentifier:CellIdentifier2];
return cell;
}
// Content cell
else {
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
// Configure cell
return cell;
}
}
However it seems the else statement is never fired and I normally get a crash saying the method returned nil.
UPDATE
I used the advice and code here and came up with this:
#pragma mark - UITableView Delegate Methods
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 160;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 22;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier1 = #"UsernameCell";
static NSString *CellIdentifier2 = #"PasswordCell";
if(indexPath.row == 0) {
BBUsernameRegistrationCell *cell = (BBUsernameRegistrationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier1 owner:self options:nil]; // set properties
cell = nib[0];
}
// set properties
return cell;
}
// Content cell
else {
BBPasswordTableViewCell *cell = (BBPasswordTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier2 owner:self options:nil]; // set properties
cell = nib[0];
}
// set properties
return cell;
}
}
However I only see the first Cell in my tableview. If I switch the cells around the second one loads. But not both at the same time. Does anyone have any idea why?
Yes, it is possible..
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
// Space Cell
if (indexPath.row== 0) {
CellSpace *cell = (CellSpace *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
cell = [[CellSpace alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1];
// set properties
}
// set properties
return cell;
}
// Content cell
else {
CellView *cell = (CellView *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell == nil) {
cell = [[CellView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
// set properties
}
// set properties
return cell;
}
}
in your custom cell, do something like this in initWithStyle method:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CellView" owner:self options:nil];
for (id currentObj in topLevelObjects ) {
if ([currentObj isKindOfClass:[CellView class]]) {
self = (CellView*) currentObj;
}
}
return self;
}
Yes it is possible. But before use this dequeueReusableCellWithIdentifier:. Just register your cell and corresponding nib files.
code as..
-(void)initiateCellRegisteration
{
static NSString *CellIdentifier1 = #"ContentCell";
static NSString *CellIdentifier2 = #"SpaceCell";
[self.tableView registerClass:[ContentCell class] forCellReuseIdentifier:CellIdentifier2];
[self.tableView registerNib:[UINib nibWithNibName:CellIdentifier2 bundle:nil] forCellReuseIdentifier:CellIdentifier2];
[self.tableView registerClass:[SpaceCell class] forCellReuseIdentifier:CellIdentifier1];
[self.tableView registerNib:[UINib nibWithNibName:CellIdentifier1 bundle:nil] forCellReuseIdentifier:CellIdentifier1];
}
Call this method in viewDidLoad
If you are using the cell nib then you need little tricky way to get your cell nib like
static NSString *CellIdentifier = #"ProductCell";
IVProductCell *cell = (IVProductCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* objects = [[NSBundle mainBundle] loadNibNamed:#"IVProductCell" owner:nil options:nil];
for (id currentObject in objects) {
if ([currentObject isKindOfClass:[IVProductCell class]]){
cell = (IVProductCell*) currentObject;
}
}
}

UITableViewCell custom cell's content resets to default values after scrolling the table view

UITableViewCell custom cell's contents such as UILabel text, UIButton title resets to default values(Label, Button) after Scrolling the Table View.I using number of custom cell in single table view. These is are code which i used to generate number of custom cell in single table view with different identifier and different custom cell name for each and every cell.
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = (customCell1 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) cell = [[customCell1 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"customCell1" owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell = (customCell1 *)currentObject;
break;
}
}
}
static NSString *CellIdentifier2 = #"cell2";
UITableViewCell *cell2 = (customCell2 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell2 == nil) cell2 = [[customCell2 alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
{
NSArray* topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"customCell2" owner:self options:nil];
for (id currentObject in topLevelObjects)
{
if ([currentObject isKindOfClass:[UITableViewCell class]])
{
cell2 = (customCell2 *)currentObject;
break;
}
}
}
cell.label = #"Test";
[cell2.button setTitle:#"Test Button" forState:UIControlStateNormal];
return cell;
return cell2;
As you are setting the cell/cell2 to a UITableViewCell loaded from NIB, the reuse identifier(s) will be whatever was set in the XIB.
Anyway, the code you pasted in has quite a few issues. Is that the one you are really using? cell2 will be never returned.
The cells in table view are dynamically created by dequeuing using the cell identifier.In the code you mentioned above will always return first "return cell";
The data source method can return only one cell at a time after the creation. So if you want to return a cell depending of your use you have to do like below
(UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Ideally a custom cell should be created like this
if(condition when you wan this cell1)
{
//create the custom cell1 here and return it as given below
static NSString *cellIdentifier = #"MyCustomCell";
// Similar to UITableViewCell
MyCustomCell *cell = (MyCustomCell *)[theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
return cell1;
}
else if(when you want to create this cell2)
{
// create the custom cell2 here and return it
return cell2;
}
// Create the default UI table view cell and return it . if any of the above condition did not satisfied, it will return the default cell.
// create default UI table here and return it
return cell;
}

Resources