UITableView crashes when scroll down - objective-c

I know there's a lot of questions about this topic but I have not be able to solve my problem...
Well, I have detected the problem, it's the contactsArray that's global. If I comment that lines, the table works fine.
The code is this:
#interface ContactsView : UIViewController <UITableViewDelegate, UITableViewDataSource>{
IBOutlet UITableView *table;
NSMutableArray * contactsArray;
}
#property (nonatomic, retain) NSMutableArray *contactsArray;
#property (nonatomic, retain) IBOutlet UITableView *table;
In viewDidLoad I do:
contactsArray = [[NSMutableArray alloc] init];
And here the implementation of each cell:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ContactsCell";
ContactsCell *cell = (ContactsCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell==nil){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"ContactsCell" owner:self options:nil];
for(id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (ContactsCell *) currentObject;
break;
}
}
}
// Configure the cell...
Person *persona = [[Person alloc] init];
persona=[contactsArray objectAtIndex:indexPath.row];
[cell setCellNames:[persona name]];
[cell setCellStates:#"En Donosti"];
[persona release];
return cell;
}
If I comment the persona=[contactsArray objectAtIndex:indexPath.row]; and [cell setCellNames:[persona name]];
So, I'm pretty sure that the problem is with contactsArray
Any idea why is it crashing?
Thanks!

You must not release persona object as you just get it from array. Also the Person *persona = [[Person alloc] init]; has no effect as you immediately overwrite object you create with object from array. Fixed code should look like:
Person *persona = [contactsArray objectAtIndex:indexPath.row];
[cell setCellNames:[persona name]];
[cell setCellStates:#"En Donosti"];
return cell;

Related

Null data when loading DetailView

I have UITableView I want to click on row and load detail view but I have null information in my Log in detail view
would you please help m win this implementation
Thanks in advance!
cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
{
//Load Cell for reuse
static NSString *CellIdentifier = #"TestCell";
TestCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell =[ [[NSBundle mainBundle] loadNibNamed:#"TestCell" owner:nil options:nil]
lastObject];
}
_tests = [server info];
_t = [NSMutableString stringWithFormat:#"%# ", [_tests objectAtIndex:indexPath.row]];
NSString *testdata = _t;
_components = [testdata componentsSeparatedByString:#","];
for (NSString *aComponent in _components) {
if ([aComponent hasPrefix:#"titletest"]) {
_subComponents = [aComponent componentsSeparatedByString:#":"];
_testString = [_subComponents[1] stringByTrimmingCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"\""]];
}if ([aComponent hasPrefix:#"note"]){
_subComponents = [aComponent componentsSeparatedByString:#":"];
_noteString = [_subComponents[1] stringByTrimmingCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"\""]];
break;
}
}
cell.title.text = _testString;
cell.note.text = _noteString;
return cell;
}
didSelectRowAtIndexPath method
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
TestDetailView *c = [[TestDetailView alloc] init];
///I don't know what should I put here to c
[self.navigationController pushViewController:c animated:YES];
}
but in My detail view
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
NSLog(#" test : %#",_Info.datas); ==>> my log was (null)
}
My Detail View Header
#property (strong, nonatomic) IBOutlet UILabel *bDetailTitle;
#property (strong, nonatomic) IBOutlet UILabel *bDetailNote;
#property (nonatomic, strong) NSArray *datas;
#property (nonatomic,strong) TestTable *Info;
#end
I'm assuming that TestDetailView is a ViewController subclass and that you have a property on it possibly called datas. If that is the case you appear to create your detail view controller in didSelectRowAtIndexPath: like this:
TestDetailView *c = [[TestDetailView alloc] init];
But then immediately change it the pointer to something else (possibly nil):
c = [_datas objectAtIndex:indexPath.row];
objectAtIndex returns an id which means your code probably doesn't throw a warning in Xcode, but at run time if [_datas objectAtIndex:indexPath.row] does not return a UIViewController (and I suspect that it does not) your app could crash. If it is not throwing an error or crashing you possibly have another problem in that _datas is nil in your parent view controller.
It is a very common technique to pass values to view controllers I would recommend reading up on how to do this. This type of question has been asked on S.O. many times:
How to set value for NSString in another view controller from one viewcontroller

Implementing UIWebView on a custom UITableViewCell

I have this UIWebView inside a custom UITableViewCell that I've created.
The problem is, when I implement the UIWebView in "MyMain", it's working but when I scroll the text is readded again and again on over the cells.
When I implement the UIWebView in the custom cell class itself it's not showing it at all.
UITableViewCustomCell.h
#property (nonatomic, weak) IBOutlet UIWebView *wvMainText;
#property (nonatomic, strong) NSString *wvTitle;
#property (nonatomic, strong) NSString *wvPrice;
UITableViewCustomCell.m
#synthesize wvMainText = _wvMainText;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
{
// THIS IS WHERE I IMPLEMENT THE WEBVIEW?
}
return self;
}
MyMain
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"myListCell";
UITableViewCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"UITableViewCustomCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (UITableViewCustomCell *)view;
}
}
}
cell.wvTitle = [[self.arrList objectAtIndex:indexPath.row] valueForKey:#"title"];
cell.wvPrice = [[self.arrList objectAtIndex:indexPath.row] valueForKey:#"price"];
wv.scrollView.scrollEnabled = NO;
NSString *htmlString = [NSString stringWithFormat:
#"<html><body>%#,%#</body></html>", self.wvTitle, self.wvPrice];
[wv loadHTMLString:htmlString baseURL:nil];
[wv setBackgroundColor:[UIColor clearColor]];
[wv setOpaque:NO];
return cell;
}
Try this...It may solve your issue.
In your cellForRowAtIndexPath method please do changes like this....
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"myListCell";
UITableViewCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"UITableViewCustomCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (UITableViewCustomCell *)view;
}
}
cell.wvTitle = [[self.arrList objectAtIndex:indexPath.row] valueForKey:#"title"];
cell.wvPrice = [[self.arrList objectAtIndex:indexPath.row] valueForKey:#"price"];
wv.scrollView.scrollEnabled = NO;
NSString *htmlString = [NSString stringWithFormat:
#"<html><body>%#,%#</body></html>", self.wvTitle, self.wvPrice];
[wv loadHTMLString:htmlString baseURL:nil];
[wv setBackgroundColor:[UIColor clearColor]];
[wv setOpaque:NO];
}
return cell;
}

UITableView in UIViewController - Connecting cells to UIViewController

I have a UITableView in a UIViewController. I have other UIViewControllers created in Storyboard that I want to connect to my cells.
How can I connect UIViewControllers created in Storyboard to my cells?
MyViewController.h
#interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *myTableView;
}
#property (nonatomic, retain) UITableView *myTableView;
MyViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *array = [[NSArray alloc] initWithObjects:#"CELL1", #"CELL2 & CELL3", nil];
self.listData = array;
[array release];
[myTableView setDataSource:self];
[myTableView setDelegate:self];
[[self view] addSubview:myTableView];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UpdatesTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"UpdatesTableViewCell" owner:nil options:nil];
for (UIView *view in views) {
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (UpdatesTableViewCell*)view;
}
}
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
return cell;
}
You can either create segues from this controller to the other ones and then choose which segue to perform when someone taps a cell or you can use a reference to the storyboard to call instantiateViewControllerWithIdentifier: and make that controller active on a tap.

Table check box just for one section objective-c

I have a uiTableView with 3 sections and different rows, I want to add check box JUST to my third sections,
I create custom cell and I linke img and label
like this picture:
![enter image description here][1]
and my code for custom cell is :
.h
: UITableViewCell
#property (strong, nonatomic) IBOutlet UIImageView *checkBox;
#property (strong, nonatomic) IBOutlet UILabel *absenceCode;
#end
.m
#synthesize checkBox;
#synthesize absenceCode;
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
// Initialization code
checkBox.image = [UIImage imageNamed:#"emptycheck-box.png"];
}
return self;
}
#end
and code for UITableViewController
viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *staKey = #"Start";
NSString *endKey = #"End";
NSString *absKey= #"Absence";
[contents setObject:[NSArray arrayWithObjects:#"Time: 08:00 Date: Fri,3 Aug, 2012", nil] forKey:staKey];
[contents setObject:[NSArray arrayWithObjects:#"Time: 17:57 Date: Fri,3 Aug, 2012", nil] forKey:endKey];
[contents setObject:[NSArray arrayWithObjects:#"Red",#"Black",#"Blue", nil] forKey:absKey];
[keys addObject:staKey];
[keys addObject:endKey];
[keys addObject:absKey];
[self setSectionKeys:keys];
[self setSectionContents:contents];
}
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
CheckBoxTableViewCell *cell = (CheckBoxTableViewCell*)[tableView
dequeueReusableCellWithIdentifier:#"CheckBoxTableViewCell"];
cell.imageView.image=[UIImage imageNamed:#"emptycheck-box.png"];
cell.checkBox.image = image;
cell.absenceCode.text =#"Redddd";
cell.text =contentForThisRow;
return cell;
}
would you please help me
Thanks in advance!
Something like the following should do what you want.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *key = [[self sectionKeys] objectAtIndex:[indexPath section]];
NSArray *contents = [[self sectionContents] objectForKey:key];
NSString *contentForThisRow = [contents objectAtIndex:[indexPath row]];
if (indexPath.section != 2) {
//Set up default cell here.
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
cell.textLabel.text =contentForThisRow;
return cell;
}
else {
CheckBoxTableViewCell *cell = (CheckBoxTableViewCell*)[tableView dequeueReusableCellWithIdentifier:#"CheckBoxTableViewCell"];
cell.imageView.image=[UIImage imageNamed:#"emptycheck-box.png"];
cell.checkBox.image = image;
cell.absenceCode.text =#"Redddd";
return cell;
}
}

Loading data in NSUserDefaults

i have done the coding to save the highscore in NSuserdefaults, but i am not sure how can i load the data from the nsuserdefaults and display it in a table. PLease help.
NSString *name;
name = nametextbox.text;
NSDictionary *player = [NSDictionary dictionaryWithObjectsAndKeys: [NSString stringWithFormat:#"%#", name], #"name",[NSString stringWithFormat:#"%d", myScore], #"score",nil];
[highScore addObject:player];
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"score" ascending:NO];
[highScore sortUsingDescriptors:[NSArray arrayWithObject:sort]];
[sort release];
[[NSUserDefaults standardUserDefaults] setObject:highScore forKey:#"highScore"];
You should be able to load it just the way you'd expect (like accessing a value in an NSDictionary):
NSArray *highScore = [[NSUserDefaults standardUserDefaults] objectForKey:#"highScore"];
Update
To display the data from this array in a table view, you'll need to create a view controller and use the array as your data source. The easiest way to do this is by subclassing UITableViewController. This should get you started on the implementation of that controller:
// HighScoreViewController.h
#interface HighScoreViewController : UITableViewController {
NSArray *highScores;
}
#property (nonatomic, retain) NSArray *highScores;
#end
.
// HighScoreViewController.m
#import HighScoreViewController.h
static const NSInteger kNameLabelTag = 1337;
static const NSInteger kScoreLabelTag = 5555;
#implementation HighScoreViewController
#synthesize highScores;
- (void)viewDidLoad {
[self setHighScores:[[NSUserDefaults standardUserDefaults]
objectForKey:#"highScore"]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [self.highScores count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"PlayerCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cel == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier] autorelease];
// Create UILabels for name and score and add them to your cell
UILabel *nameLabel = [[UILabel new] autorelease];
[nameLabel setTag:kNameLabelTag];
[cell.contentView addSubview:nameLabel];
UILabel *scoreLabel = [[UILabel new] autorelease];
[scoreLabel setTag:kScoreLabelTag];
[cell.contentView addSubview:scoreLabel];
// Set other attributes common to all of your cells here
// You will also need to set the frames of these labels (nameLabel.frame = CGRectMake(...))
}
NSDictionary *player = [self.highScores objectAtIndex:indexPath.row];
NSString *name = [player objectForKey:#"name"];
NSString *score = [player objectForKey:#"score"];
[(UILabel *)[cell.contentView viewWithTag:kNameLabelTag] setText:name];
[(UILabel *)[cell.contentView viewWithTag:kScoreLabelTag] setText:score];
return cell;
}
#end
A key thing to remember with UITableView is that cells get reused, so you need to be careful about where you initialize/configure your cell's subviews.