initWithCoder and initWithNibName - iphone

I am trying to encode some data state in a UITableViewController. In the first time, I init the object with Nibname without any problem. However, when I initWithCoder, the UITableViewController still loads but when I clicked on a cell, the application crash and the debugger tells me about EXEC_BAD_ACCESS, something wrong with my memory, but I do not know
Here is my code:
- (id) init {
if(self = [self initWithNibName:#"DateTableViewController" bundle:nil]) {
self.dataArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
}
return self;
}
// Customize the appearance of table view cells.
- (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] autorelease];
}
// Set up the cell...
int index = indexPath.row;
cell.textLabel.text = [self.dataArray objectAtIndex:index];;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return #"Test Archiver";
}
- (void)encodeWithCoder:(NSCoder *)coder {
[super encodeWithCoder:coder];
[coder encodeObject:self.dataArray];
}
- (id)initWithCoder:(NSCoder *)coder {
return [self init];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
int index = indexPath.row;
[self.dataArray addObject:[NSString stringWithFormat:#"Hello %d", index]];
[self.tableView reloadData];
}

I see two problems here:
1) You are serializing your dataArray using encodeObject: but omit to deserialize it in initWithCoder:
2) You should rather use NSKeyedArchiver's method encodeObject:forKey:. Then you are free to use the serialized information in the decoding or not.
Other than that I can only say to answer your question it would be helpful to include information about where the crash happens.

There is only one memory problem in this code: In init you are leaking the NSMutableArray. But that’s kind of the opposite problem you are looking for. The bug you described is not in the posted code.

Related

display data in UITableView on view navigation

i have 2 views-view1 and view2, one for entering data and another for displaying the entered data.
I am able to display the entered data in view2 in labels. But how to display the data in a UITableView. Following is my code to display the data:
view2.m
#synthesize details; //details is an object of NSMutableArray.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
textLabel.text = self.name;
lblCity.text = self.city;
lblGender.text = self.gender;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [details count];
}
- (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 = [details objectAtIndex:indexPath.row];
//cell.imageView.image = [UIImage imageNamed:#"creme_brelee.jpg"];
return cell;
i debuuged and found that cellForRowAtIndexPath is never called.
Where am i getting wrong? How do i solve it?
You need to create a NSMutableArray of display Data in to UITableViewCell like below and don't forget to declare UITableView delegates in .h file <UITableViewDataSource,UITableViewDelegate> and also connect your UITableView IBOutlet in your xib and also connect the delegate:
- (void)viewDidLoad
{
[super viewDidLoad];
arrCategorisation=[[NSMutableArray alloc] initWithObjects:#"DataOne",#"DataTwo",#"DataThree", #"DataFour",#"DataFive",nil];
}
#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 arrCategorisation.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier =[NSString stringWithFormat:#"%d",indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.textLabel.text=[arrCategorisation objectAtIndex:indexPath.row];
}
// Configure the cell...
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
}
your Table load data like:-

UITableView Cells get reordered after editing the cell

In my app, You can tap a cell, and it brings up a new view. You can edit the tableviewCell's textLabel, and save it. But when you switch views and come back to the tableView, the cells are in a different order. What could be the reason for this?
Here is my Code:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * identifier = #"identifier";
self.cell = [tableView dequeueReusableCellWithIdentifier:identifier];
h = [self.tableArray objectAtIndex:indexPath.row];
NSString *brandModel = [[h.brand stringByAppendingString:#" "] stringByAppendingString:h.model];
self.cell.mainLabel.text = brandModel;
self.cell.nicknameLabel.text = handguns.nickname;
return self.cell;
}
If you are reloading tableView after saving UITableView cell then It will be reordered as initial because array from which you are setting cell data is as it is.You can change only table View cells not array data position in an array.
Below I have written a UITableView code to move cells and it is working fine after pushing view.If I remove reload method from viewWillAppear:
#import "MoveCellViewController.h"
#interface MoveCellViewController ()
#end
#implementation MoveCellViewController
- (void)viewDidLoad
{
UIBarButtonItem *left=[[UIBarButtonItem alloc] initWithTitle:#"Edit" style:UIBarButtonItemStyleBordered target:self action:#selector(edit)];
self.navigationItem.leftBarButtonItem=left;
myArray=[[NSMutableArray alloc]init]; //mutable array;
myArray=[NSMutableArray arrayWithObjects:#"Aman",#"Ankit",#"Sumit",#"Hercules",#"Jackie Chan", nil];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
-(void)edit
{
if (self.navigationItem.leftBarButtonItem.title==#"Edit") {
self.navigationItem.leftBarButtonItem.title=#"Done";
[_tableView setEditing:YES];
}else
{
[_tableView setEditing:NO];
self.navigationItem.leftBarButtonItem.title=#"Edit";
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [myArray count];
}
// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier=#"cellIdentifier";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil) {
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.userInteractionEnabled=YES;
cell.textLabel.text=[myArray objectAtIndex:indexPath.row];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath{
return UITableViewCellEditingStyleNone;
}
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath{
id ob = [myArray objectAtIndex:destinationIndexPath.row];
[myArray replaceObjectAtIndex:destinationIndexPath.row withObject:[myArray objectAtIndex:sourceIndexPath.row]];
[myArray replaceObjectAtIndex:sourceIndexPath.row withObject:ob];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NextViewController *nx=[[NextViewController alloc] init];
[self.navigationController pushViewController:nx animated:YES];
}
#end
This is working code and will not change after push view controller.
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *CellIdentifier = [NSString stringWithFormat:#"S%1dR%1d",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
h = [self.tableArray objectAtIndex:indexPath.row];
NSString *brandModel = [[h.brand stringByAppendingString:#" "] stringByAppendingString:h.model];
self.cell.mainLabel.text = brandModel;
self.cell.nicknameLabel.text = handguns.nickname;
return self.cell;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2 reuseIdentifier:nil];
}
Write rest of the code here
}

How UITableView show two different arrays one at a time?

The below Code works but not as i wish.i want that when i click UIbutton its automaically update the new value in UITableview instead of old value.Below Code works only when i press the UIbuttons and after that when i scroll the UITableview then it update the UItableview with new values.
In my application i using UITableview as Subclass of my mainclass.as image show below
I add Tableview in my Mainclass which is "testingViewController" like this way
In testingViewController.h
#import "Inputtableview.h"
#interface testingViewController :UIViewController<UITableViewDelegate,UITableViewDataSource> {
Inputtableview *inputview;
IBOutlet UITableView *inputtbl;
}
#end
In testingViewController.m
- (void)viewDidLoad {
btn1bool=FALSE;
if (inputview == nil) {
inputview = [[Inputtableview alloc] init];
}
[inputtbl setDataSource:inputview];
[inputtbl setDelegate:inputview];
inputview.view = inputview.tableView;
}
Now in Button action method
-(IBAction)input:(id)sender
{
btn1bool=TRUE;
}
my Subclass code "inputtableview.m" is show below
- (void)viewDidLoad {
[super viewDidLoad];
listOfItems=[[NSMutableArray alloc] initWithObjects:#"Iceland",#"Greenland",#"Switzerland",
#"Norway",#"New Zealand",#"Greece",#"Italy",#"Ireland",nil];
array1 = [[NSMutableArray alloc] initWithObjects:#"A",#"B",#"C",#"D",#"E",#"F",#"G",#"H", nil] ;
}
#pragma mark -
#pragma mark Table View datasource methods
-(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
if (btn1bool) {
return [array1 count];
}
else {
return [listOfItems count];
}
[self.tableView reloadData];
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSLog(#"Row: %i", indexPath.row);
if (btn1bool) {
NSString *cellValue = [array1 objectAtIndex:indexPath.row];
cell.text = cellValue;
}
else {
NSString *cellValue = [listOfItems objectAtIndex:indexPath.row];
cell.text = cellValue;
}
return cell;
}
Any help will be appriated.
Just put the following code:
[inputtbl reloadData];
There are a few things you need to change in your project, but I assume this project is just for testing stuff.
You want the date to reload after you pressed the button, so you call the method in the IBAction.
-(IBAction)input:(id)sender
{
btn1bool=TRUE;
[inputview.tableView reloadData];
}
To switch between the 2 data sources when the button is pressed you can change to this line of code: btn1bool=!btn1bool;
(NSInteger) tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
if (btn1bool) {
return [array1 count];
} else {
return [listOfItems count];
}
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath is correct

UITableView not displaying data from array

Code:
In .h:
NSMutableArray *contentArray;
I'm declaring my array.
In .m
- (void)viewDidLoad
{
[super viewDidLoad];
contentArray = [[NSMutableArray alloc] initWithObjects:#"view", #"browse", #"create", nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
I'm setting it up in my view did load.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [contentArray count];
}
I'm setting the number of rows to the array 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] autorelease];
}
// Configure the cell...
[[cell textLabel] setText:[contentArray objectAtIndex:indexPath.row]];
return cell;
}
Nothing. But if I do "[[cell textLabel] setText:#"Hello World."];" instead, it works fine.
Are you at least getting 3 empty rows in table ? If yes then just change your code
NSString *tempString = [your_array objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
If you are not even getting empty strings then make property of your array in .h file. Synthesize it in .m (also release it in delloc function) and finally in viewDidLoad right following
NSMutableArray tempContentArray = [[NSMutableArray alloc] arrayWithObjects:#"view", #"browse", #"create", nil];
self.contentArray=tempArray;
and then write following code to get cell title
NSString *tempString = [self.contentArray objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
Try to initialize your Array in your init method or call reloadDataon your UITableView after you set your Array.
Your code in .m file is fine. Write property .h file synthesize and dealloc your NSMutable array .m file it may be help you.
simply use following line of code
//initlize nsarray with objects.
-(void)viewDidLoad
{
NSArray *practice_ArrayForDisplayingEx=[NSArray alloc]initWithObjects:#"bhupi",#"bhupi",#"bhupi",#"bhupi",nil];
}
//then use in tableview.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
// UIButton *practice_takeTest_button;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]autorelease];
}
cell.textLabel.text =[practice_ArrayForDisplayingEx objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont fontWithName:#"Arial" size:15];
return cell;
}
make sure you included UITableViewDelegate & UITableViewDataSourse prtocol in .h file.
hope it will help you..
Make sure that your .h implements the tableview delegate and datasource... should look like this
#interface myClass : UITableViewController <UITableViewDelegate, UITableViewDataSource>
then make this code in your ViewDidLoad method
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];

UITableViewCell reloadcellsAtIndexPaths increases the height of the following cell but not the actual one

[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
after this I am increasing the height of the 1st cell in heightforRowAtIndexPath. But to my surprise it is increasing the height of the second cell, but when I scroll the table view... the height of the first one is set back to desired.
If I reload the entire table using [tv reloaddata] it works fine.. does not work only if i do the particular cell
Any help on this would be helpful..
As written in the comments above, I only have a vague understanding about what you want to achieve. I assume you want to extend cell by changing their height. You just mention the first cell, but I guess, you want to be able, to do it for any cell when being clicked.
The complete project is available at github
.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSIndexPath *selectedIndexPath;
NSDictionary *articles;
}
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
selectedIndexPath = nil;
articles = [[NSDictionary dictionaryWithObject:[NSArray arrayWithObjects:#"one", #"two", #"three",
#"four", #"five", #"six",
#"seven", #"eight", #"nine",
#"ten", #"eleven", nil]
forKey:#"title"] retain];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[selectedIndexPath release];
[articles release];
[super dealloc];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[articles allKeys] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[articles allKeys] objectAtIndex : section];
}
- (int)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
id key = [[articles allKeys] objectAtIndex:section];
return [[articles objectForKey : key] count];
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row))
return 80.0;
return 40.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * MyIdentifier = #"MyIdentifier";
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
id key = [[articles allKeys] objectAtIndex:indexPath.section];
cell.textLabel.text = [[articles objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath == indexPath) {
selectedIndexPath = nil;
} else {
selectedIndexPath = indexPath;
}
[self.tableView deselectRowAtIndexPath : indexPath animated : NO];
[tableView beginUpdates];
[tableView endUpdates];
}
#end
This code is quite rough, as I just extracted it from a project in my very early iPhone-days. i.e. properties are missing.