I am playing with a piece of code and this is what I have gotten so far. The app gets an XML feed to display job advertisements, and shows them as in the images I attached.
What I am trying to figure out is, how to make the "Description" part display all the information taken from the XML file.
Would the answer be hidden in changing something in this method?
- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
switch(indexPath.section)
{
case 0:
cell.text = aBook.title;
break;
case 1:
cell.text = aBook.author;
break;
case 2:
cell.text = aBook.summary;
break;
}
return cell;
}
Try to implement this:
-(CGFloat ) tableView:(UITableView*) tableView heightForRowAtIndexPath:(NSIndexPath*) indexPath
{
If(indexPath.section==2)
{
return 60;
}
}
Related
I have a tableView with a custom cell. I have the posibility to save to favorites some of the elements , and when this is happening i want to add a star image in cell. I was trying doing this , but after the star appears, i have a problem . I think it's because of reusable cell but i dont know how to solve it . My problem is : stars appear again on the other cells even if the word is not added on favorites.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[dictionaryTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.word.text = self.tableData[indexPath.row];
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
}
return cell;
}
Replace following code in place of cellForRowAtIndexPath. you will get your desire output.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (!cell) {
cell=[[dictionaryTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
cell.favImg.hidden = YES;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.word.text = self.tableData[indexPath.row];
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.hidden = NO;
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
}
return cell;
}
Hope this help you.
You have to remove the image if the object is not TRUE
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
} else {
cell.favImg.image=nil;
}
Yes, you are right it's because of reusing your cells via dequeueReusableCell with identifier as-
dictionaryTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
according to your requirements you set a star image on a cell to indicate some favorite elements on the respective cell, like this
BOOL isTheObjectThere = [self.favoriteArry containsObject:self.tableData[indexPath.row]];
if (isTheObjectThere==TRUE) {
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
}
When any cell with star image is reused than it should be removed if the next cell does not some favorite elements but if it does have some favorite elements than it should be used as-
To resolve this issue just add the else case with the above if statement as
if (isTheObjectThere == TRUE)
cell.favImg.image=[UIImage imageNamed:#"3081#3x.png"];
else
cell.favImg.image=nil;
Here's my code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifierNormal = #"CellNormal";
static NSString *CellIdentifierTracking = #"CellTracking";
switch (self.mapState) {
case MapStateNormal:
{
// UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifierNormal];
// if (cell == nil) {
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierNormal];
// }
[cell.textLabel setText:#"abc"];
return cell;
}
case MapStateTracking:
{
// UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifierTracking];
// if (cell == nil) {
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierTracking];
// }
if (indexPath.row == 0) {
[cell.textLabel setText:#"Lorem ipsum"];
} else {
NSURL *url = [LoremIpsum URLForPlaceholderImageFromService:LoremIpsumPlaceholderImageServicePlaceKittenCom
withWidth:1024
height:1024];
[cell.imageView setImageWithURL:url
placeholderImage:[UIImage imageNamed:#"MenuButton"]];
}
return cell;
}
default:
break;
}
return nil;
}
This piece of code works fine but not the best practice because I re-create UITableViewCell everytime. It display like this:
However, when I uncomment those lines above to enable dequeueReusableCell then the table shows its cells with errors like this (the yellow part is my code):
You can see that there's an UIImage in first row and text in some rows below while I clearly didn't set it in my code.
What could I do to fix this ? or should I stick with the first method ?
Thanks.
You should really re-use the table view cells, because it is a lot of overhead if you recreate them all the time, i.e. the out-commented code is right.
Next, the docs say: "The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell."
If you do not reset the content, it will be shown again.
So I suggest that you set
cell.imageView.image = nil;
in your -(UITableViewCell *)tableView:cellForRowAtIndexPath:(NSIndexPath *)indexPath method.
Simply set [cell.textLabel setText:#""]; for each cell you dont't want to display any text. Cells are reused with the previous text, so you need to clear it.
Try this, clear the cell if it cell != nil
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifierNormal = #"CellNormal";
static NSString *CellIdentifierTracking = #"CellTracking";
switch (self.mapState) {
case MapStateNormal:
{
UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifierNormal];
if (cell == nil) {
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierNormal];
} else {
[cell.textLabel setText:#""];
[cell.imageView setImage:nil];
}
...
return cell;
}
case MapStateTracking:
{
UITableViewCell *cell = [self.table dequeueReusableCellWithIdentifier:CellIdentifierTracking];
if (cell == nil) {
UITableViewCell *cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifierTracking];
} else {
[cell.textLabel setText:#""];
[cell.imageView setImage:nil];
}
....
return cell;
}
default:
break;
}
return nil;
}
I'm confused as to what the problem/difference is with this code. In the first working example, I'm loading the table view from a custom class. This works dandy.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EventCell";
ISEventsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.backgroundColor = [UIColor colorWithWhite:.2 alpha:.7];
ISSingleEvent *singleEvent = events[indexPath.row];
[cell populateWithEvents:(singleEvent)];
return cell;
}
Now I want to add a second section to the table view and everything seems to be going fine until I add the conditions for cellForRowAtIndexPath. I get the error "No visible interface for 'UITableViewCell' declares the selector 'populateWithPasses:'
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = #"EventCell";
static NSString *CellIdentifier2 = #"FlareCell";
NSString *identityString = #"";
switch ([indexPath section]) {
case 0: {
identityString = CellIdentifier1;
break;
}
case 1: {
identityString = CellIdentifier2;
break;
}
default:
break;
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identityString];
if ([indexPath section] == 0) {
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue2
reuseIdentifier:CellIdentifier1];
cell.backgroundColor = [UIColor colorWithWhite:.2 alpha:.7];
ISSingleEvent *singleEvent = events[indexPath.row];
// Error here (below) "No visible interface for 'UITableViewCell' declares the selector 'populateWithEvents:'
[cell populateWithEvents:(singleEvent)];
}
} else {
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier2];
cell.backgroundColor = [UIColor colorWithWhite:.2 alpha:.7];
ISFlareEvent *singleEvent = flareEvents[indexPath.row];
// Error here (below) "No visible interface for 'UITableViewCell' declares the selector 'populateWithFlares:'"
[cell populateWithFlares:(singleEvent)];
}
}
return cell;
}
So what am I doing wrong here? When I called "populateWithEvents" with only one section, it didn't throw an error. Now I've set up two section, each with it's own tableviewcell and it's just not working. Any help would be greatly appreciated.
Thanks,
just cast your cell like this
[(ISEventsCell *)cell populateWithFlares:(singleEvent)];
You are trying to call populateWithFlares: for UITableviewCell. The metho is defined for ISEventsCell
I had a simple question regarding a table view with 3 different kinds of prototype cells. The first two occur just once while the third occurs 4 times. Now what I'm confused about is how to specify in my cellforRowatindexpath which cell prototype to use for which row. So, I want something like for row 0, use prototype 1, for row 1, use prototype 2, for rows 3,4,5 and 6 use prototype 3. What's the best way to do this? Do i give each prototype an identifier and then use dequeueReusableCellWithIdentifier:CellIdentifier ?
Can you'll provide some sample code?
EDIT:
Still not working. This is the code I have at the moment. ( I only have one case for the switch statment because I just want to test and see if the cell is being generated in the first row or not, but currently table view is blank)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch(indexPath.row)
{
case 0: {static NSString *CellIdentifier = #"ACell";
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:#"ACell"];
if(cell==nil) {
cell=[[UITableViewCell alloc]
initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:#"ACell"];
}
return cell;
break;
}
}
}
Acell is my identifier for a cell prototype that I created. I
If you are using three prototype then use three identifiers. Because only one identifier will cause problem. And you will get wrong result. So code like this.
if(indexPath.row==0){
// Create first cell
}
if(indexPath.row==1){
// Create second cell
}
else{
// Create all others
}
You can use switch case also here for best performance.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if (cell.tag == 0)
{
return array1.count;
}
else(cell.tag == 1)
{
return array2.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier;
NSString *membershipType = [membershipTypeArray objectAtIndex:indexPath.row];
if ([membershipType isEqualToString:#"silver"]||[membershipType isEqualToString:#"gold"])
{
cellIdentifier = #"cell";
}
else if ([membershipType isEqualToString:#"platinum"])
{
cellIdentifier = #"premiumCustomCell";
cell.customCellImageView.image = [cellImageArray objectAtIndex:indexPath.row];
}
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.headingLabel.text = [titleArray objectAtIndex:indexPath.row];
}
Here i wrote code like:
#pragma mark == Tableview Datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSInteger nRows = 0;
switch (section) {
case 0:
nRows = shipData.count;
break;
case 1:
nRows = dataArray1.count;
break;
default:
break;
}
return nRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellIdentifier = #"cellIdentifier1";
NSString *cellIdentifier1 = #"cellIdentifier2";
SingleShippingDetailsCell *cell;
switch (indexPath.section) {
case 0:
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
//Load data in this prototype cell
break;
case 1:
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier1];
//Load data in this prototype cell
break;
default:
break;
}
return cell;
}
I have a tableview with multiple prototype cells that i designed in the storyboard, but i´m stuck with the height problem because my first cell is supose to be different from the second one and so on...I have different identifiers for each cell, and because i designed them in storyboard, i know they´re height´s. I have this in my code, but it´s not working, does anyone knows how to fix it?:
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc]init];
switch (indexPath.section)
{
case 1:
cell = [tableView dequeueReusableCellWithIdentifier:#"cell1"];
return 743.0f;
break;
case 2:
cell = [tableView dequeueReusableCellWithIdentifier:#"cell2"];
return 300.0f;
}
}
Thanks for your time.
It looks like you are trying to use this method for purposes it wasn't designed for...
you'll want to override the method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section)
case 1:
static NSString *CellIdentifier = #"cell1";
break;
case 2:
static NSString *CellIdentifier = #"cell2";
break;
UITableViewCell *cell = [tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
return cell;
}
Only change the row height in the heightForRowAtIndexPath:
-(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
switch (indexPath.section)
{
case 1:
return 743.0f;
break; //technically never used
case 2:
return 300.0f;
}
Check out this tutorial http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1 its a good resource