I'm quite new to xcode na objective-c so I'm sorry for the dumb question. What I want to do is to load images to cells in UITableView according to id. Every object in xml has the id and the image name id id.jpg. I accomplished to load them right but when I scroll the images dissapear. From what I have found it looks like it has something to do with dequeueReusableCellWithIdentifier but I can't figure out what is it. Here is the code I'm using to load the images:
-(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];
}
theList = [app.listArray objectAtIndex:indexPath.row];
NSString *trimmedString = [theList.t_image stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
cell.imageView.image = [UIImage imageNamed:trimmedString];
cell.textLabel.text = theList.t_name;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
if(cell.imageView.image == nil){
cell.imageView.image = [UIImage imageNamed:#"untitled.jpg"];
}
return cell;
}
and here is the xml:
<taxis>
<taxi>
<t_id>1</t_id>
<t_image>1.jpg</t_image>
<t_name>AAA Taxi</t_name>
<t_tel>+42014014</t_tel>
<t_addr>Vodičkova 40</t_addr>
<t_web>www.radiotaxiaaa.cz</t_web>
<t_getin>40</t_getin>
<t_km>26.9</t_km>
<t_wait>5</t_wait>
<t_city>Praha</t_city>
</taxi>
<taxi>
<t_id>2</t_id>
<t_image>2.jpg</t_image>
<t_name>Modrý anděl</t_name>
<t_tel>+420737222333</t_tel>
<t_addr>Cukrovarská 33</t_addr>
<t_web>www.modryandel.cz</t_web>
<t_getin>40</t_getin>
<t_km>19</t_km>
<t_wait>6</t_wait>
<t_city>Praha</t_city>
</taxi>
</taxis>
Thanks for any answer.
do all rows have picture? if not make sure to set cell.imageView to nil at the beginnign of the method after
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
UPDATE : If i were you i would cache the images in an array and load them from this array in cellforrowatindexpath method.Try this i will probably work.Note that you can not add nil as object to NSmutablearray so you need to add another value rather than nil and UIimage
Related
How do I accomplish something like this:
a table cell with multiple actions inside the text(link to image, since I don't have enough point to paste images)
I want to be able to control what the bold text does (e.g. activate a segue) and I also want the cell itself to have a separate action.
Is this possible? The text is dynamic, so the string lengths are not fixed.
Any help is much appreciated! (this is my first question of StackOverflow btw).
Have a look at TTTAttributedLabel, it can handle multiple links inside text.
Check the below code
- (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];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
NSString *indexpath_str=[NSString stringWithFormat:#"%d",indexPath.row+1];
NSString *ordinary_string=[NSString stringWithFormat:#"This is %d",indexPath.row+1];
NSMutableAttributedString *attri_str=[[NSMutableAttributedString alloc]initWithString:ordinary_string];
int last=[indexpath_str length];
int begin=[ordinary_string length]-[indexpath_str length];
[attri_str addAttribute:NSBackgroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(begin,last)];
[attri_str addAttribute:NSFontAttributeName value:[UIFont fontWithName:#"HelveticaNeue-Bold" size:30] range:NSMakeRange(begin, last)];
cell.textLabel.attributedText =attri_str;
return cell;
}
I am new in iPhone application development. I am currently working on XML parsing. I am extracting records from an xml file and storing it in an mutable array. I have a table view and i am loading the table view from that mutable array. I get 18 rows in the table view which i found by debugging. The problem is when i scroll down upto 10 rows it moves well but as 10th row appears the app crashes. i get the error of EXC_BAD_ACCESS. Here is my code where the cell gets loaded. Thanks.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
Location *record = [[Location alloc] init];
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
}
There are some misstakes in the code you post, first you only return a cell is the table isn't return a cell for dequeueing
Thus changing you code likewise will solve that problem:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
}
Location *record = [[Location alloc] init];
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
Also having to alloc and init a Location every time is very costly, it's better to have a Location with in the class that you call every time a cell is needed.
Beter yet is to just grab the data for the cell only and not do any lengthy method in the tableVieew:cellForRowAtIndexPath: method.
your mistake is " return cell" which is written in inside the if condition take it outside also row title label text set out side condition.like this way..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if(cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"cell"];
Location *record = [[Location alloc] init];
}
else
{
// get record object here by tag.
}
record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;
return cell;
}
You need to write this snippet
`record = [[parse locationarr] objectAtIndex:indexPath.row];
cell.textLabel.text = record.locationname;`
out of if block.
Enjoy Programming!!
I am creating a table with three different types of custom cell, One of them, one custom cell is having UITextField. I create two rows using this custom cell. I set tag and delegate for textfields of both row.
My problem is, when I scroll the table, these rows with textfields move up and disappear from the screen, when scroll down, that time my app gets crash.
I get an error like
-[CellImageViewController txtField]: unrecognized selector sent to instance 0xa0ea5e0
Here is my code for cellForRowAtIndexPath:
if (indexPath.row == 0 )
{
if (cell == nil) {
cell = [[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
}
cell.txtField.tag =1;
cell.txtField.delegate = self;
cell.txtField.text = #"kjfkd";
}
return cell;
}
else if(indexPath.row==1)
{
if (cell == nil) {
cell = [[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID] autorelease];
}
cell.txtField.tag = 2;
cell.txtField.text = #"glk";
cell.txtField.delegate = self;
return cell;
}
Any one have idea about this issue?
you have different type of cells, so you need to use a cellIdentifier different for each one.
Try this:
customOrNormalCell *cell [tableView dequeueReusableCellWithIdentifier:CellIdentifier]
if(!cell){
cell = [[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:[NSString stringWithFormat:#"%i", indexPath.row]];
}
With this code, each cellIdentifier will be 1,2,3,4... (All different)
I'm pretty sure that it will solves the problem
create UITextField before create UITableView and Add your Textfield object in cell Content view
[cell.contentView addSubview:yourTxtFieldOblect];
It looks like you might be reusing a cell of a different type.
Try making sure which kind of class the cell you are reusing is before trying to access it's properties.
why you are define cell for each row?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%d",indexPath.row];
CellWithTextFieldViewController *cell = (CellWithTextFieldViewController *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell =[[[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]autorelease];
cell.txtField.tag = indexPath.row;
cell.txtField.text = [SET TEXT FROM ARRAY];
cell.txtField.delegate = self;
}
}
I had also faced this problem in my project.
just try this:
Disabled the scrolling property in Tableview and create a scrollview.Then add your Tableview in your scrollview.
UITableView *table=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 976, 395) style:UITableViewStylePlain];
[table setSeparatorStyle:UITableViewCellSelectionStyleNone];
UIScroll *scroll=[[UIScrollView alloc]initWithFrame:CGRectMake(24, 168, 978, 395)];
[table setScrollEnabled:NO];
[scroll addSubview:table];
[self.view addSubview:scroll];
[scroll sendSubviewToBack:table];
Try this
static NSString *cellIdentifier= #"Cell";
CellWithTextFieldViewController *cell = (CellWithTextFieldViewController *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[CellWithTextFieldViewController alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.txtField.tag =indexPath.row+1;
cell.txtField.delegate = self;
cell.txtField.text = #"kjfkd";
return cell;
While scrolling tableView your cell is getting reused. Thats why textField is disappearing. Try to use different cell id for different custom cells. Dont forget to give the same id in nib file for cell identifier
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *customCellOne = #"customCell1";
static NSString *customCellTwo = #"customCell2";
UITableViewCell *cell =nil;
if (0 == indexPath.row)
{
cell = (CustomCellOne *)[tableView dequeueReusableCellWithIdentifier:customCellOne];
if (nil == cell)
{
// Create custom cell one and do what ever you want
}
}
else if (1 == indexPath.row)
{
cell=(CustomCellTwo *)[tableView dequeueReusableCellWithIdentifier:customCellTwo];
if (nil == cell)
{
// Create custom cell two and do what ever you want
}
}
return cell;
}
I don't know,may be when reused the cell,the textfield delegate was released.
may be you can set the
textfield.deleagate = self;
in CellWithTextFieldViewController.m
I'm trying to implement "Load more..." on a tableView. I've done it, but I don't know if it's efficient.
The thing is that I have custom cells, and if I do like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
ArticlesCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ArticlesCell" owner:self options:NULL];
cell = (ArticlesCell *) [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
tableView.backgroundColor = cell.backgroundColor;
if (indexPath.row <= (self.bookmarks.count - 1)) {
[self configureCell:cell atIndexPath:indexPath];
}else{
cell.textLabel.text = #"Load more...";
}
return cell;
}
It works great but what happens is it's reusing the cells, and if I scroll, every fifth cell (this is height 77.0) will have the label "Load more...", but actually do it's job as normal.
I found this workaround, but I don't know is it good and efficient.
Here it is:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
if (indexPath.row <= (self.bookmarks.count - 1)) {
ArticlesCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell==nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ArticlesCell" owner:self options:NULL];
cell = (ArticlesCell *) [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
tableView.backgroundColor = cell.backgroundColor;
[self configureCell:cell atIndexPath:indexPath];
return cell;
}else{
UITableViewCell *cell = [[UITableViewCell alloc] init];
cell.textLabel.text = #"Load more...";
return cell;
}
}
As you can see I'm making the "Load more..." cell a simple UITableViewCell, and not reusing it, since it's only one. Is this good approach? Can you advice me in something better?
Thank you!
Another approach would be to use 2 different cell identifiers, one to identify and reuse (once initially created) an ArticlesCell and another to identify and reuse (once initially created) a "Load more..." UITableViewCell. At least then you will only create the "Load more..." UITableViewCell once rather than every time it scrolls into view.
static NSString *ArticleCellIdentifier = #"ArticleCell";
static NSString *LoadMoreCellIdentifier = #"LoadMoreCell";
The LazyTableImages Apple iOS sample project uses a similar approach (see the Classes/ RootViewController.m).
When you are click on loadmore button then increase the number of rows and reload the tableview . i.e in the method numberofrowsinsection.Let me know if you need any more
I have different texts in my custom cells in my UITableView, each text has a category. according to category a certain image is assigned to UIImageView in my CustomCell like that:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CCell";
// Dequeue or create a cell of the appropriate type.
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
}
// Configure the cell.
cell.primaryLabel.text = [self.arrayWithTextsFromSelectedCategory objectAtIndex: indexPath.row];
NSString *keyForText=[self.arrayWithTextsFromSelectedCategory objectAtIndex:indexPath.row];
categoryForPicture=[dicWithTitlesAsKeysAndCategoriesAsValues objectForKey:keyForText];
//cell.categoryImg=[dicWithTitlesAsKeysAndCategoriesAsValues objectForKey:keyForText];
NSLog(#"Current category!!! %#", categoryForPicture);
NSLog(#" %# ", keyForText);
//NSString *textToExtract;
//textToExtract=[self.texts objectForKey:keyForText];
cell.secondaryLabel.text=[self.texts objectForKey:keyForText];
if (categoryForPicture==#"Стихи")
{
NSLog(#"Assigning proper image!!");
cell.iconImage.image=[UIImage imageNamed:#"stixi.png"];
}
if (categoryForPicture==#"Анекдоты")
{
NSLog(#"Assigning proper image!!");
cell.iconImage.image=[UIImage imageNamed:#"jokes.png"];
}
else
{
cell.iconImage.image=[UIImage imageNamed:#"stand_icon.png"];
}
//cell.imageView.image=[UIImage imageNamed:#"cell.png"];
//cell.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"cell.png"]]];
return cell;
}
still doesn't work... any ideas? thanks!
the problem is your string equality check...this categoryForPicture==#"Анекдоты" will return true only if the two are the same object, which will never be the case here, you want to us NSStrings isEqualToString: in order to accomplish your goal... so
[categoryForPicture isEqualToString:#""]
hope that helps