Cubs Fan Ron
Cubs Fan Ron

Reputation: 697

UITableViewCell display issue

EDIT: Not related to NSAttributedString, OHAttributedLabel or TTTAttributedLabel!

Short question: I'm using UILabel, OHAttributedLabel or TTTAttributedLabel with the same issue - scrolling the table view screws up the display of the label. More on that below...

Long form: I have an NSAttributedString object representing the text from a tweet. I've decorated the string based on various contents in the tweet (e.g., hashtags are colored blue, urls are colored green and underlined, user mentions are red).

For example, this tweet:

 @MeetGreen Keep up the good work. Say Hi to Nancy for me - she convinced me that I can be green and save green at the same time!

results in this NSAttributedString: (displayed using a utility I wrote to help me see what's going on):

@MeetGreen{
    NSColor = "UIDeviceRGBColorSpace 1 0 0 1";
    NSFont = "<UICFFont: 0x93c57d0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 17px";
} Keep up the good work. Say Hi to Nancy for me - she convinced me that I can be green and save green at the same time!{
    CTForegroundColor = "<CGColor 0x93c8f20> [<CGColorSpace 0x938b570> (kCGColorSpaceDeviceGray)] ( 0 1 )";
    NSFont = "<UICFFont: 0x93c57d0> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 17px";
}

The code that generates the NSAttributedString object seems to be doing what I want it to do, but when I try to display this object in a UILabel (or TTTAttributedLabel or OHAttributedLabel) I can't convince it to work correctly. The principal issue seems to be scrolling behavior - the cells do not plot correctly (the text is in some strange position). However, if I simply select the cell (by touching it, for example), the cell is plotted exactly as it should be. It makes me think the issue is with the table scrolling handling in my delegate methods and NOT the attributed label itself (since the behavior is the same for OHAttributedLabel and TTTAttributedLabel), but I'm not sure WHY that is. (One thing I haven't tried yet is plain text and a plain UILabel for the tweet content - that's on the list for tonight. Ok, same behavior with UILabel and plain text content. What am I doing wrong???)

Here's my code for tableView:cellForRowAtIndexPath:, tableView:heightForRowAtIndexPath: and tableView:didSelectRowAtIndexPath:; note that this code resides in a UIViewController subclass, not a subclass of UITableViewController.

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    TweetingTweetCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Tweet"];

    TSTweet *tweet = [self.model tweetAtIndexPath:indexPath];

    cell.userHandleLabel.text = tweet.user.screenName;
    cell.userNameLabel.text = tweet.user.name;
    cell.timestampLabel.text = timeStamp;
    cell.tweetTextLabel.attributedText = [self.model decoratedStringForTweetAtIndexPath:indexPath];

    UIImage *image = [UIImage imageNamed:@"avatar"];

    cell.userImage.image = image;

    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    CGFloat tweetHeight = [self.model heightForTweetAtIndexPath:indexPath
                                                     usingWidth:label_width];

    CGFloat height = tweetHeight + label_headroom + label_footroom;

    CGFloat result = MAX(height,defaultHeight);

    NSLog(@"[%@ %@] %@ (%@)\ntweetHeight=%f, height=%f, defaultHeight=%f, result=%f", NSStringFromClass([self class]), NSStringFromSelector(_cmd),indexPath,[self.model decoratedStringForTweetAtIndexPath:indexPath].string,tweetHeight,height,defaultHeight,result);

    return result;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"[%@ %@] indexPath=%@", NSStringFromClass([self class]), NSStringFromSelector(_cmd),indexPath);

    TweetingTweetCell *cell = (TweetingTweetCell *)[tableView cellForRowAtIndexPath:indexPath];

    NSLog(@"decoratedString=%@",[self.model decoratedStringForTweetAtIndexPath:indexPath]);
    [cell dumpDebugInfo];
    [tableView deselectRowAtIndexPath:indexPath
                             animated:NO];
}

TweetingTweetCell is a subclass of UITableViewCell that contains 4 objects: a UIImageView for the avatar, a UILabel for the sender's screen name, a UILabel for the time it was sent, and a "label" object for the tweet content. As I said above, I've tried OHAttributedLabel and TTTAttributedLabel and the behavior is the same.

Bad scroll:

strange scroll

During selection:

fixed by selection

Upvotes: 0

Views: 939

Answers (1)

Cubs Fan Ron
Cubs Fan Ron

Reputation: 697

Resolved - pilot error. The issue was an evil cabal of springs/struts and how I was setting the size of the label.

The code for tableView:heightForRowAtIndexPath: presented above works as intended. I made two changes that effected the resulting behavior:

  1. I added code to tableView:cellForRowAtIndexPath: to set the height of the tweetTextLabel, namely:

    CGRect rect = cell.tweetTextLabel.frame;
    rect.size.height = [self.model heightForTweetAtIndexPath:indexPath
                                                  usingWidth:label_width];
    cell.tweetTextLabel.frame = rect;
    
  2. I turned off the right and bottom struts as well as the vertical spring on tweetTextLabel (in IB).

These two changes made the initial presentation as well as scrolling behave correctly.

Upvotes: 1

Related Questions