3

I'm using an array of strings where I set the detailTextLabel from. Initially all subtitles are set correctly but if I scroll the detailTextLabel disappears.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath   *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"personCell"  forIndexPath:indexPath];

    Person *person = [_persons objectAtIndex:indexPath.row];
    cell.textLabel.text = person.name;
    cell.detailTextLabel.text = person.phone;

    // also tried setNeedsLayout but does not help
    [cell setNeedsLayout];

    return cell;
}

I'm using an iPhone 6 and iOS 8. I'm also using storyboard and set the UITableViewCell style to Subtitle.

gpichler
  • 2,181
  • 2
  • 27
  • 52
  • If you log the string `person.phone` does it always have the correct value? Also, are you setting the cell type properly? (In interface builder?) – Fogmeister Nov 04 '14 at 11:35
  • Yes, the weird thing is that the string has the right value and is not empty or nil. I'm thinking it could be a iOS 8 specific bug. Cell type is set in IB to Subtitle, that should be correct as the results are fine before I start scrolling. – gpichler Nov 04 '14 at 11:38
  • Do you have any other methods like `tableView:willDisplayCell`? Also, is it just a standard `UITableViewCell` or are you using a subclass? If so, is there any code in there? – Fogmeister Nov 04 '14 at 11:39
  • It's standard `UITableViewCell`. I'm only using `scrollViewWillBeginDragging:` to dismiss the keyboard, but that shouldn't affect the cells. – gpichler Nov 04 '14 at 11:45
  • @user1463853 Did you add registerClass: in your viewdidload? – Rumin Nov 04 '14 at 11:51
  • @RoOmin no I didn't do that, why should I do this? – gpichler Nov 04 '14 at 11:52
  • as per https://developer.apple.com/Library/ios/documentation/UIKit/Reference/UITableView_Class/index.html#//apple_ref/occ/instm/UITableView/dequeueReusableCellWithIdentifier:forIndexPath: it is necessary to do that. Have a look at it. – Rumin Nov 04 '14 at 11:53
  • @RoOmin even if I'm using standard `UITableViewCell` class? – gpichler Nov 04 '14 at 11:55
  • @user1463853 don't worry about registering it. Your storyboard/nib will be doing this for you. If you hadn't done that then you wouldn't see anything in the table. **Anyway** I just made a very simple project to show a table with subtitle cells and it is fine when I scroll it. The only thing I can suggest is to go back to basics with it. Get it to a point where it does work and go forward from there. Unless you can share the project? – Fogmeister Nov 04 '14 at 11:55
  • 1
    @RoOmin if that was the problem then the app would crash when trying to dequeue the cells. This is not the problem. – Fogmeister Nov 04 '14 at 11:56
  • YES. In your case it would be `self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"personCell"];` – Rumin Nov 04 '14 at 11:56
  • @Fogmeister take a look at this question, it seems like this is pretty similar, but I don't want to just set a blank string. http://stackoverflow.com/questions/25793074/subtitles-of-uitableviewcell-wont-update – gpichler Nov 04 '14 at 12:00
  • @Fogmeister okay. Just found in the documentation. I thought may be he would be missing that. – Rumin Nov 04 '14 at 12:02
  • @user1463853 ok, are you using static or prototype cells? (it should be prototype). Also, did you alter the cells in the storyboard in any way? Like changing the font or the size or the labels etc... Also, do you have a `heightForRowAtIndexPath` method? If not, good. If so, can you post it please. :) – Fogmeister Nov 04 '14 at 12:07
  • @Fogmeister first thanks for you effort trying to help me. Yes I'm using prototype cells, but I have changed the font of the title and subtitle to custom Helvetica Light. Could that be the issue? – gpichler Nov 04 '14 at 12:08
  • @user1463853 I just tried on my project. Changed the colour of textLabel and the size/font of the detail and it was fine. Hmm... what happens if you just show fixed text instead... `cell.detailTextLabel.text = @"0123456789";. Thinking it might be something to do with the person. Possibly... – Fogmeister Nov 04 '14 at 12:14
  • @Fogmeister if i set a fixed text then it works, the problem is sometimes the person phone number can be nil, if a person does not have one. I guess this causes the problems. However the phone number still disappears although a valid string would exist for this cell. – gpichler Nov 04 '14 at 12:16
  • @user1463853 yes, I just tried by randomly setting the text to `nil` and it caused the problem. You said you don't want to set it to blank. Is that right? Also, yes, if the detailText starts as nil you don't seem to be able to change it. – Fogmeister Nov 04 '14 at 12:17
  • @user1463853 ok, writing a possible solution. – Fogmeister Nov 04 '14 at 12:18
  • @Fogmeister thank you very much, looking forward to it. Yes, I don't want a blank subtitle, because then the title isn't vertically centered anymore. I also want to avoid a placeholder text, like "No phone number" or something like that. – gpichler Nov 04 '14 at 12:25

2 Answers2

4

OK, now that we've found the problem (with the nil phone number text on the person) you could solve it a couple of ways.

It seems that you don't want to set the text to blank. I imagine this is due to the fact that it lays out the cell in an odd way with the title pushed up to the top but nothing underneath it. Understandable.

So, you could create a custom UITableViewCell subclass. In it you can manage the layout yourself and if the number is nil lay it out one way and if it has a phone number lay it out a different way.

An easier way would be to use two different prototype cells instead.

In the storyboard create two prototype cells.

One with type Basic and give it a reuseIdentifier noPhoneNumberCell. The other with type Subtitle and a reuse identifier phoneNumberCell.

Then in the code you can do something like this...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath   *)indexPath
{
    Person *person = [_persons objectAtIndex:indexPath.row];
    UITableViewCell *cell;

    if (person.phone) {
        cell = [tableView dequeueReusableCellWithIdentifier:@"phoneNumberCell" forIndexPath:indexPath];

        cell.detailTextLabel.text = person.phone;
    } else {
        cell = [tableView dequeueReusableCellWithIdentifier:@"noPhoneNumberCell" forIndexPath:indexPath];
    }

    cell.textLabel.text = person.name;

    return cell;
}

This will now create two queues of cells. One for people with phone numbers and one for people without.

This way you don't mix the two and so avoid the problem you are facing.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306
  • 1
    You are awesome thank you very much for this answer. I just improved it a little bit, because the string could probably be not nil but blank. Therefore I changed the if-statement to `if(person.phone && ![person.phone isEqualToString:@""])` Again thank you very much! – gpichler Nov 04 '14 at 12:36
  • Excellent. Glad you got it working. Good idea with the change too. – Fogmeister Nov 04 '14 at 12:36
1
[cell.detailTextLabel sizeToFit];