I have a UITableView with one section. All of the cells in that one section have cells that are derived from a subclass of UITableViewCell called PLContactCell.
What I'd like to do is, for the very last row of the table only, not use a PLContactCell. I just want to use a normal UITableViewCell that I can format however I would like. I'd also like to be able to have this cell NOT respond to being tapped.
My initial cellForRowAtIndexPath method is:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
PLContactCell *cell = [tableView dequeueReusableCellWithIdentifier:[PLContactCell reuseIdentifier]];
if (!cell) {
cell = [PLContactCell reusableCell];
cell.delegate = self;
}
id modelObject = [[sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if ([modelObject isKindOfClass:[NSString class]]) {
[cell configureWithString:modelObject];
} else {
[cell configureWithUser:modelObject];
}
return cell;
}
EDIT
So I tried created a UITableView cell in the XIB file and added the reuse identifier of "newCell" to it. Then I added this code:
if (indexPath.row == [[sections objectAtIndex:indexPath.section] count] - 1) {
NSString *CellIdentifier = #"newCell";
noFormatCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
This doesn't do anything. My question is, how do I access the last row of the section and how do I make it so that that cell it is not a PLContactCell but a UITableView Cell.
If it's always at the end, you might consider using the footer view of the UITableView. You can then keep some extra logic out of your UITableViewDataSource.
If it HAS to be as a cell, you'd have to add an extra row count on your last section, then do an if statement check to watch out for it in your -tableView:cellForRowAtIndexPath: implementation. I would strongly urge you try the footer approach, as it's cleaner and way easier to figure out what you were doing a few months/years from now.
Here's some code. Note you'd need to make another section if you are using grouped style in the UITableView.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == sections.count - 1) //Looking for last section
{
return [sections objectAtIndex:section].count + 1; //Add one to the last section
}
return [sections objectAtIndex:section].count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSInteger row = indexPath.row;
if ((sections.count == indexPath.section) && [sections objectAtIndex:indexPath.section].count == indexPath.row)
{
//Here you would create and return your UITableViewCell
}
PLContactCell *cell = [tableView dequeueReusableCellWithIdentifier:[PLContactCell reuseIdentifier]];
if (!cell) {
cell = [PLContactCell reusableCell];
cell.delegate = self;
}
id modelObject = [[sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
if ([modelObject isKindOfClass:[NSString class]]) {
[cell configureWithString:modelObject];
} else {
[cell configureWithUser:modelObject];
}
return cell;
}
Related
I am developing Iphone Application.Using Three table view on Single viewcontroller. value show on those tableview's on single array but problem is that those array value show on first tableview not on other two tableview's. please help Thanks in advance
code..
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_arrayResult count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
MEObject *obj = [_arrayResult objectAtIndex:indexPath.row];
if (tableView == _tableView) {
cell.textLabel.text= obj.emp_client_name;
}
if (tableView == _secondTableView) {
cell.textLabel.text= obj.emp_event_name;
}
if (tableView == _thirdTableView) {
cell.textLabel.text=obj.emp_client_name;
}
return cell;
}
Please cross check if you are setting datasource and delegates of all 3 tables to viewcontroller.
When you set your _arrayResult, you need to reload all 3 table view
_arrayResult = #[a,b,c];
[table1 reloadData];
[table2 reloadData];
[table3 reloadData];
After once you set the datasource/Delegate to the all three tableview. I haven't seen any datasource allocation as per your tableview. Like
if tableview == tableview1 {
Return first array
}
Can you please try giving name to those tableview on outlet and then for each datasource and delegates function call as per your requirement but before check which tableview is displayed.
I want UITableView always has the text "No more items" in the last cell, I want this row appears regardless of number of items, include 0 items. How could I do?
You can get the total row of a section by using numberOfRowsInSection: method.
NSInteger total = [self.tableView numberOfRowsInSection:indexPath.section];
// Check if last cell or no cell.
if(indexPath.row == totalRow -1 || indexPath.row == 0)
{
// Do your operation here
}
You can perform this in your cellForRowAtIndexPath or willDisplayCell methods. Hope it helps.
Just add the row regardless of your other items:
- (void)buildMenu {
[_menuItems removeAllObjects];
// ... add your items or not if you have 0
YourCellItem *lastItem = [[YourCellItem alloc] initWithTitle:#"No more items"];
[_menuItems addObject:lastItem];
[self.tableView reloadData];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _menuItems.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"yourCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
YourTableViewCell *basicCell = (YourTableViewCell *)cell;
YourCellItem *item = [_menuItems objectAtIndex:indexPath.row];
basicCell.itemTitle.text = item.title;
return cell;
}
In a VC I have 2 tableViews - 1 main and other is added in a drop down menu. From drop down menu TableView "ddTableView", I have added 5 cells in Storyboard itself as prototype cells. Each cell contains an image and a Label. Have also set identifier for each cell. Have also set Accessory Type as "Disclosure Indicator" for each cell of ddTableView.
DataSource and Delegate for mainTV is set to the VC and delegate for ddTableView is set the VC. As the rows are added within the storyboard, I didn't set any datasource for ddTableView in my VC. I managed my delegate methods like this :-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
// RETURNS NIL ???
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog(#"CELL Identifier = %#", cell.reuseIdentifier);
return cell;
} else {
}
}
-(void )tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSLog (#" CELL Clicked of - %#", cell.reuseIdentifier);
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == ddTableView)
return 44;
else
return 60;
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == ddTableView)
return 5;
else
return [chatMsgsArr count];
}
It does call respective delegate method. For cellForRowAtIndexPath it returns cell as nil. Why so ? And on execution, I don't see any contents of the table view - table is blank. I changed the bg color of image and text color also, but yet nothing is seen on execution.
Why so ? Where I may be going wrong ?
You have to allocate the cell, the first time cellForRowAtIndexPath is called. If the cell is not allocated it would return nil as you are getting right now.
What you need to do is allocate the cell only once, the first time you enter cellForRowAtIndexPath. After that you can reuse it as you have done.
If you are planning to use the default tableViewCell your method should look as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = #"your_cell_identifier_name";
if (cell == nil)
{
UITableViewCell *cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
else
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
}
//write the code to populate your cell with data here
//return the cell object
return cell;
}
Hope this helps! :)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] ;
}
if (tableView == ddTableView) {
NSLog(#"CELL Identifier = %d", indexpath.row);
} else {
NSLog(#"CELL Identifier = %#", [chatMsgsArr objectAtIndex:indexPath.row]);
}
return cell;
}
I'm basically making a settings view on my app and I'm using a static table for it. So I divided the table into 3 sections each with one cell. Not programmatically I can easily label each cell and it works but programmatically I'm not able to initialize each cell. I can only initialize the first cell that gets repeated across the 3 sections. I would like a way to initialize a cell for each section but I can't find a method or a way to do that. My tableview also has reuseIdentifiers but it doesn't seem like the UITableViewController recognizes it.
This is what I have done so far.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EditProfile";
//UITableViewCell *cell = nil; //[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// More initializations if needed.
}
//Observations *currentList = [self.teacherNames objectAtIndex:indexPath.row];
cell.textLabel.text = #"Hey";
//return cell;
return cell;
}
But what I want is the cell in the first section to be labeled: Edit Profile, the second one: Invite and the third:Logout
You have to make a condition for how to handle each different section within the table view.
if (indexPath.section == 0) {
cell.textLabel.text = #"Edit Profile";
}else if (indexPath.section == 1) {
cell.textLabel.text = #"Invite";
}else if (indexPath.section == 2) {
cell.textLabel.text = #"Log out";
}......
Check out the tableView delegate methods:
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section;
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
(IF you're wanting to label the section headers and not the cells in the sections themselves)
I've stucked to this problem for couple days, and I've debugged it many times and can't figure out what's going wrong.
I have a UITableView that has three sections. I'd like to add buttons as accessoryView and UILabel as detailText to the second section.
It looked OK when View first loaded.
But after scroll it, it becomes
After couple scrolls, it freezes (not crash).
Below is my code, any advise will be appreciated.
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section==0) {
return self.status.count;
}
else if (section==1)
return self.overrideCtrl.count;
else
return self.levelStatus.count;
// Return the number of rows in the section.
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MenuCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSLog(#"section %#",indexPath);
if (indexPath.section == 0) {
cell.textLabel.text = [self.status objectAtIndex:indexPath.row];
NSLog(#"Status %#",cell.textLabel.text);
}
else if (indexPath.section == 1) {
cell.textLabel.text = [self.overrideCtrl objectAtIndex:indexPath.row];
cell.detailTextLabel.text =[NSString stringWithFormat:#"00:%02d",[[self.timeLeftArray objectAtIndex:indexPath.row] intValue]];//[[self.timeLeftArray objectAtIndex:indexPath.row] stringValue];
cell.accessoryView=[self.checkButtonArray objectAtIndex:indexPath.row];
NSLog(#"override %#",cell.textLabel.text);
}else{
cell.textLabel.text = [self.levelStatus objectAtIndex:indexPath.row];
NSLog(#"level %#",cell.textLabel.text);
}
return cell;
}
Thanks!
This problem is covered a lot on SO, it's because of cell reuse. You need to set the accessoryView to UITableViewCellAccessoryNone for your other sections, otherwise, a cell that was used for section one might be used in another section, and still have its accessory view.
You only have 1 CellIdentifier. You should have a different one for each section.