Table View Cell renders incorrectly - ios

I'm creating a table view using custom table view cell using data from the NSSArray property of the controller class. when i ran the app only the first row of the table view display correctly.
#import "MainTableViewController.h"
#interface MainTableViewController ()
#property (strong, nonatomic) NSArray* items;
#end
#implementation MainTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
_items = #[#"Item1", #"Item2", #"Item3"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _items.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
TableViewCell* tableViewCell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell"];
if (!tableViewCell) {
UINib* tableViewCellNib = [UINib nibWithNibName:#"TableViewCell" bundle:nil];
[tableView registerNib:tableViewCellNib forCellReuseIdentifier:#"TableViewCell"];
tableViewCell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell"];
}
return tableViewCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CalculatorViewController* calculatorViewController = [[CalculatorViewController alloc] init];
[self presentViewController:calculatorViewController animated:YES completion:nil];
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(TableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
cell.label.text = [_items objectAtIndex:indexPath.row];
}
the first row renders Item1 but the rest only renders the first two character and dots for each row. ex It... for row 2 and the rest. the expected result is it displays everything in the _items array.

Related

How to display swipe button in uitableviewcell by tap on cell?

I have tried to call the functions manually by programming, those functions are
-(NSArray *)tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(NSIndexPath *)indexPath
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES; //tableview must be editable or nothing will work...
}
When i call the functions it works inside the functions for example the editActionsForRowAtIndexPath function but doesnt show the button.
Any clue or help will be highly appreciated.
Did you forgot to call [self.tableView setEditing:YES animated:YES]; ?
Why do you use above 3 methods for swipe and deleting the table view cell?
Only one method is enough for doing this.I created sample one for your question.It works fine.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>
#property (nonatomic, strong) IBOutlet UITableView *tableViewEdit;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController (){
NSMutableArray *arr;
}
#end
#implementation ViewController
#synthesize tableViewEdit;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
arr = [[NSMutableArray alloc]initWithObjects:#"iOS",#"Android",#"Windows",nil];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
//UITableViewDataSource methods
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return arr.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *strCell = #"cell";
UITableViewCell *cell = [tableViewEdit dequeueReusableCellWithIdentifier:strCell];
if(cell == nil){
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strCell];
}
cell.textLabel.text = arr[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if(editingStyle == UITableViewCellEditingStyleDelete)
{
[arr removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
When I run the application first it shows the below data
Then when I swipe the table view
Finally I delete the data from the table view and the table view

Recreate a uitableview section dynamically on a uibutton`s click

I need to recreate a UITableView section on a UIButton click. Here is an example for this.
AND in button click it should be created like this.
But i am not able to implement this .
Please Help.
I am just creating a simple UITableView with a textLabel.
Code For cellForRowAtIndexPath is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
Create a integer variable index and property for tableview in .h
#property UITableView *tableView;
Then in -(void)viewDidLoad set index=0;
Now, write a method which is get called when you tap on add button
-(void)newTableView
{
tableView = [UITableView alloc] initWithFrame:CGRectMake(x,y+height*index,width,height)];
//other code related to table
tableView.tag = ++index;
[self.view addSubview:tableView];
}
Use tag in delegate methods
Edit: As you requested to add new section in Table View instead of new table view
You have to first create table view of grouped style
tableView = [UITableView alloc] initWithFrame:(CGRect)frame style:UITableViewStyleGrouped];
Now, When you hit on that add button call a method
-(void)newSection
{
count++;
[tableView reloadData];
}
Then, you have to implement this delegate methods for grouped table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"title";
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
//same as your previous code
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//same as your previous code
}
//
// ViewController.m
// DynamicNewSections
//
// Created by J Pulikkottil on 14/07/15.
// Copyright (c) 2015 J Pulikkottil. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic) NSMutableArray *arrayData;
#property (strong, nonatomic) IBOutlet UITableView *tableViewTest;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrayData = [NSMutableArray array];
//section1
[self addSectionArray];
}
- (IBAction)addSection:(UIButton *)sender {
[self addSectionArray];
[self.tableViewTest reloadData];
}
- (void) addSectionArray{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Height",#"label", #"", #"value", nil];
NSArray *arraysection = [NSArray arrayWithObjects:dict, nil];
[self.arrayData addObject:arraysection];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableViewTest.frame.size.width, 45)];
view.backgroundColor = [UIColor yellowColor];
return view;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return [self.arrayData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [[self.arrayData objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellDetails" forIndexPath:indexPath];
NSArray *arraysection = [self.arrayData objectAtIndex:indexPath.section];
NSDictionary *dict = [arraysection objectAtIndex:indexPath.row];
cell.textLabel.text = [dict valueForKey:#"label"];
cell.detailTextLabel.text = [dict valueForKey:#"value"];
return cell;
}
#end
Try this:
Just have a property (e.g. numberOfSections)
Set it to 1 in viewDidLoad
In the numberOfSectionsInTableView: return self.numberOfSections;
In the IBAction of your UIButton add this code:
self.numberOfSections++;
[self.tableView beginUpdates];
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:self.numberOfSections-1]
withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];

Pass array of images from multiple UITableView selected cells

I am having such an issue right now. I have a UIViewController that has a UITableView, I have it set up so that when the UITableView is in editing mode it returns 3 - circles with the check marks. My UITableView has custom cells with in image and text. When I put the UITableView in edit mode, I am trying to pass an array of the images from multiple selected rows to a second view controller to use those images in a collection view, but I am just having a hard time passing the array of images. Any suggestions would be appreciated.
here is my TableView code:
-(void)didTapEditBUtton:(id)sender{
if ([self.ribbonTableView isEditing]) {
viewButton.hidden = YES;
headerLabel.hidden = NO;
[ribbonTableView setEditing:NO animated:YES];
[selectButton setTitle:#"select"];
}
else {
[selectButton setTitle:#"Cancel"];
// Turn on edit mode
headerLabel.hidden = YES;
viewButton.hidden = NO;
[ribbonTableView setEditing:YES animated:YES];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection (NSInteger)section{
return [ribbonsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
RibbonCustomCell *cell = (RibbonCustomCell *) [ribbonTableView dequeueReusableCellWithIdentifier:#"RibbonDetail"];
if (cell != nil)
{
RibbonsInfo *ribbonsInfo = [ribbonsArray objectAtIndex:indexPath.row];
//NSLog(#"%#", ribbonsInfo);
//Ribbon Image
cell.ribbonImageView.image = ribbonsInfo.ribbonImage;
cell.ribbonLabel.text = ribbonsInfo.ribbonName;
}
return cell;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return 3;
}
-(void)tableView:(UITableView *)tableView didSelectRowsAtIndexPath:(NSIndexPath *)indexPath{
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
}
You should take the property of NSMutableArray...
#property (nonatomic, strong) NSMutableArray *selectedImages;
- (void)viewDidLoad {
[super viewDidLoad];
self.selectedImages = [NSMutableArray new];
}
now when you select or deselect the cell the delegates are called -
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",indexPath);
RibbonsInfo *ribbonsInfo = [ribbonsArray objectAtIndex:indexPath.row];
[self.selectedImages addObject:ribbonsInfo.ribbonImage];
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",indexPath);
if (self.selectedImages.count > 0) {
[self.selectedImages removeObjectAtIndex:indexPath.row];
}
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return 3;
}
Now the selectedImages array contains the selected cell images and you can pass this array.
Hope it will solve your problem.

Populate UI Table View with array of strings

I can't find a simple, concise answer anywhere and I refuse to believe that XCode makes things as hard as other tutorials I've found out there...
Say I have the following array
NSArray* days = [NSArray arrayWithObjects:#"Sunday",#"Monday",#Tuesday",#"Wednesday",#"Thursday",#"Friday",#"Saturday",nil];
I have a UI Table View, table_Days, that I would like to simply show the items from my array. What is the proper way to go about populating my table?
Here's my full explanation, starting with a case extremely similar to yours:
http://www.apeth.com/iOSBook/ch21.html#_table_view_data
So suppose days is stored as an instance variable accessed through a property self.days. Then set self as the table view's datasource and use this code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (!self.days) // data not ready?
return 0;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.days count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:#"Cell"
forIndexPath:indexPath];
cell.textLabel.text = (self.days)[indexPath.row];
return cell;
}
You should populate your table view using the data source methods. Returning the count of the array for the number of rows.
If you need to detect when a user taps on a cell you can use the delegate methods.
#interface ViewController<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, copy) NSArray *days;
#property (nonatomic, strong) UITableView *tableDays;
#end
#implementation ViewController
-(void)viewDidLoad
{
[super viewDidLoad];
UITableView *tableDays; // Set this up
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
tableDays.delegate = self;
tableDays.dataSource = self;
[self.view addSubview:tableDays];
self.tableDays = tableDays;
self.days = #[#"Sunday", #"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday"];
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.days count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.days[indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *day = self.days[indexPath.row];
NSLog(#"Day tapped: %#", day);
}
#end
You should consider using a UITableViewController if you just want to show a table view.
Note that its better practice to use camel case for variables.

UITableViewController ignores tap after deleting row in iOS7

Consider the following plain and simple UITableViewController: when you tap a row, it logs the selected row, and when you swipe and delete, it removes an item in the model and reloads the data.
#interface DummyTableViewController : UITableViewController
#property (nonatomic, strong) NSMutableArray *items;
#end
#implementation DummyTableViewController
- (instancetype)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self)
{
_items = [ #[ #"A", #"B", #"C", #"D", #"E" ] mutableCopy];
}
return self;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
cell.textLabel.text = self.items[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.items removeObjectAtIndex:indexPath.row];
[tableView reloadData];
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Row %# tapped.", self.items[indexPath.row]);
}
In iOS6, this all works as expected, but in iOS7 I get the following behavior: after a row has been removed and the data has been reloaded, the first next tap on a table cell is ignored. It is only the second tap that triggers a table cell select again. Any idea what might be causing this or how to work around it? Issue should be easy to reproduce in iOS7 with the above code.
The tableview is in editing state when you delete a particular row. SO you have to turn off the editing state to allow the tableView to go back to the selection mode. Change your code to this -
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete)
{
[self.items removeObjectAtIndex:indexPath.row];
// Turn off editing state here
tableView.editing = NO;
[tableView reloadData];
}
}

Resources