2015-03-14 5 views
1

Я изучаю Object C &, работающий над клоном Instagram для назначения класса. В настоящее время у меня проблема с автоматической компоновкой. В частности, изображения & комментарии накладываются друг на друга:Xcode Table Cell Overlap

Image Overlap

Я считаю, что проблема заключается в Автокомпоновка:

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // Initialization code 
     self.mediaImageView = [[UIImageView alloc] init]; 
     self.usernameAndCaptionLabel = [[UILabel alloc] init]; 
     self.usernameAndCaptionLabel.numberOfLines = 0; 
     self.commentLabel = [[UILabel alloc] init]; 
     self.commentLabel.numberOfLines = 0; 

     for (UIView *view in @[self.mediaImageView, self.usernameAndCaptionLabel, self.commentLabel]) { 
      [self.contentView addSubview:view]; 
      view.translatesAutoresizingMaskIntoConstraints = NO; 
     } 
     NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(_mediaImageView, _usernameAndCaptionLabel, _commentLabel); 

     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_mediaImageView]|" options:kNilOptions metrics:nil views:viewDictionary]]; 
     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_usernameAndCaptionLabel]|" options:kNilOptions metrics:nil views:viewDictionary]]; 
     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_commentLabel]|" options:kNilOptions metrics:nil views:viewDictionary]]; 

     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_mediaImageView][_usernameAndCaptionLabel][_commentLabel]" 
                       options:kNilOptions 
                       metrics:nil 
                        views:viewDictionary]]; 
     self.imageHeightConstraint = [NSLayoutConstraint constraintWithItem:_mediaImageView 
                    attribute:NSLayoutAttributeHeight 
                    relatedBy:NSLayoutRelationEqual 
                    toItem:nil 
                    attribute:NSLayoutAttributeNotAnAttribute 
                   multiplier:1 
                    constant:100]; 


     self.usernameAndCaptionLabelHeightConstraint = [NSLayoutConstraint constraintWithItem:_usernameAndCaptionLabel 
                        attribute:NSLayoutAttributeHeight 
                        relatedBy:NSLayoutRelationEqual 
                         toItem:nil 
                        attribute:NSLayoutAttributeNotAnAttribute 
                        multiplier:1 
                        constant:100]; 

     self.commentLabelHeightConstraint = [NSLayoutConstraint constraintWithItem:_commentLabel 
                     attribute:NSLayoutAttributeHeight 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:nil 
                     attribute:NSLayoutAttributeNotAnAttribute 
                     multiplier:1 
                      constant:100]; 

     [self.contentView addConstraints:@[self.imageHeightConstraint, self.usernameAndCaptionLabelHeightConstraint, self.commentLabelHeightConstraint]]; } 
    return self; 
} 

Я прошел через класс учебник несколько раз и исследовали iOS SDK Table Cell Overlapping, но не удалось найти подходящий ответ.

Вот весь код:

#import "AppDelegate.h" 
#import "UITableViewCell+BLCMediaTableViewCell.h" 
#import "NSObject+BLCMedia.h" 
#import "NSObject+BLCComment.h" 
#import "NSObject+BLCUser.h" 


//@implementation UITableViewCell (BLCMediaTableViewCell) 

@interface BLCMediaTableViewCell() { 
    BLCMedia* _mediaItem; 
} 


@property (nonatomic, strong) UIImageView *mediaImageView; 
@property (nonatomic, strong) UILabel *usernameAndCaptionLabel; 
@property (nonatomic, strong) UILabel *commentLabel; 

// Assignment: Added auto layout 
@property (nonatomic, strong) NSLayoutConstraint *imageHeightConstraint; 
@property (nonatomic, strong) NSLayoutConstraint *usernameAndCaptionLabelHeightConstraint; 
@property (nonatomic, strong) NSLayoutConstraint *commentLabelHeightConstraint; 

@end 

static UIFont *lightFont; 
static UIFont *boldFont; 
static UIColor *usernameLabelGray; 
static UIColor *commentLabelGray; 
static UIColor *linkColor; 
static NSParagraphStyle *paragraphStyle; 

@implementation BLCMediaTableViewCell : UITableViewCell 

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    // Before layout, calculate the intrinsic size of the labels (the size they "want" to be), and add 20 to the height for some vertical padding. 

    self.imageView.contentMode = UIViewContentModeScaleAspectFill; 
    self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y, 100, 100); 

    CGSize maxSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX); 
    CGSize usernameLabelSize = [self.usernameAndCaptionLabel sizeThatFits:maxSize]; 
    CGSize commentLabelSize = [self.commentLabel sizeThatFits:maxSize]; 

    self.usernameAndCaptionLabelHeightConstraint.constant = usernameLabelSize.height + 20; 
    self.commentLabelHeightConstraint.constant = commentLabelSize.height + 20; 

    // Hide the line between cells 
    self.separatorInset = UIEdgeInsetsMake(0, 0, 0, CGRectGetWidth(self.bounds)); 
} 


+ (void)load { 
    lightFont = [UIFont fontWithName:@"HelveticaNeue-Thin" size:11]; 
    boldFont = [UIFont fontWithName:@"HelveticaNeue-Bold" size:11]; 
    usernameLabelGray = [UIColor colorWithRed:0.933 green:0.933 blue:0.933 alpha:1]; /*#eeeeee*/ 
    commentLabelGray = [UIColor colorWithRed:0.898 green:0.898 blue:0.898 alpha:1]; /*#e5e5e5*/ 
    linkColor = [UIColor colorWithRed:0.345 green:0.314 blue:0.427 alpha:1]; /*#58506d*/ 

    NSMutableParagraphStyle *mutableParagraphStyle = [[NSMutableParagraphStyle alloc] init]; 
    mutableParagraphStyle.headIndent = 20.0; 
    mutableParagraphStyle.firstLineHeadIndent = 20.0; 
    mutableParagraphStyle.tailIndent = -20.0; 
    mutableParagraphStyle.paragraphSpacingBefore = 5; 

    paragraphStyle = mutableParagraphStyle; 

} 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     // Initialization code 
     self.mediaImageView = [[UIImageView alloc] init]; 
     self.usernameAndCaptionLabel = [[UILabel alloc] init]; 
     self.usernameAndCaptionLabel.numberOfLines = 0; 
     self.commentLabel = [[UILabel alloc] init]; 
     self.commentLabel.numberOfLines = 0; 


     for (UIView *view in @[self.mediaImageView, self.usernameAndCaptionLabel, self.commentLabel]) { 
      [self.contentView addSubview:view]; 
      view.translatesAutoresizingMaskIntoConstraints = NO; 
     } 
     NSDictionary *viewDictionary = NSDictionaryOfVariableBindings(_mediaImageView, _usernameAndCaptionLabel, _commentLabel); 

     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_mediaImageView]|" options:kNilOptions metrics:nil views:viewDictionary]]; 
     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_usernameAndCaptionLabel]|" options:kNilOptions metrics:nil views:viewDictionary]]; 
     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[_commentLabel]|" options:kNilOptions metrics:nil views:viewDictionary]]; 

     [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[_mediaImageView][_usernameAndCaptionLabel][_commentLabel]" 
                       options:kNilOptions 
                       metrics:nil 
                        views:viewDictionary]]; 
     self.imageHeightConstraint = [NSLayoutConstraint constraintWithItem:_mediaImageView 
                    attribute:NSLayoutAttributeHeight 
                    relatedBy:NSLayoutRelationEqual 
                    toItem:nil 
                    attribute:NSLayoutAttributeNotAnAttribute 
                   multiplier:1 
                    constant:100]; 


     self.usernameAndCaptionLabelHeightConstraint = [NSLayoutConstraint constraintWithItem:_usernameAndCaptionLabel 
                        attribute:NSLayoutAttributeHeight 
                        relatedBy:NSLayoutRelationEqual 
                         toItem:nil 
                        attribute:NSLayoutAttributeNotAnAttribute 
                        multiplier:1 
                        constant:100]; 

     self.commentLabelHeightConstraint = [NSLayoutConstraint constraintWithItem:_commentLabel 
                     attribute:NSLayoutAttributeHeight 
                     relatedBy:NSLayoutRelationEqual 
                      toItem:nil 
                     attribute:NSLayoutAttributeNotAnAttribute 
                     multiplier:1 
                      constant:100]; 

     [self.contentView addConstraints:@[self.imageHeightConstraint, self.usernameAndCaptionLabelHeightConstraint, self.commentLabelHeightConstraint]]; } 
    return self; 
} 




- (NSAttributedString *) usernameAndCaptionString { 
    CGFloat usernameFontSize = 15; 

    // Make a string that says "username caption text" 
    NSString *baseString = [NSString stringWithFormat:@"%@ %@", self.mediaItem.user.userName, self.mediaItem.caption]; 

    // Make an attributed string, with the "username" bold 
    NSMutableAttributedString *mutableUsernameAndCaptionString = [[NSMutableAttributedString alloc] initWithString:baseString attributes:@{NSFontAttributeName : [lightFont fontWithSize:usernameFontSize], NSParagraphStyleAttributeName : paragraphStyle}]; 

    NSRange usernameRange = [baseString rangeOfString:self.mediaItem.user.userName]; 
    [mutableUsernameAndCaptionString addAttribute:NSFontAttributeName value:[boldFont fontWithSize:usernameFontSize] range:usernameRange]; 
    [mutableUsernameAndCaptionString addAttribute:NSForegroundColorAttributeName value:linkColor range:usernameRange]; 

    return mutableUsernameAndCaptionString; 
} 


- (void) setMediaItem:(BLCMedia *)mediaItem { 
    _mediaItem = mediaItem; 
    self.mediaImageView.image = _mediaItem.image; 
    self.usernameAndCaptionLabel.attributedText = [self usernameAndCaptionString]; 
    self.commentLabel.attributedText = [self commentString]; 

    self.imageHeightConstraint.constant = self.mediaItem.image.size.height/self.mediaItem.image.size.width * CGRectGetWidth(self.contentView.bounds); 
} 

//Added 
- (CGSize) sizeOfString:(NSAttributedString *)string { 
     CGSize maxSize = CGSizeMake(CGRectGetWidth(self.contentView.bounds) - 40, 0.0); 
     CGRect sizeRect = [string boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin context:nil]; 
     sizeRect.size.height += 20; 
     sizeRect = CGRectIntegral(sizeRect); 
     return sizeRect.size; 
    } 



- (NSAttributedString *) commentString { 
    NSMutableAttributedString *commentString = [[NSMutableAttributedString alloc] init]; 

    for (BLCComment *comment in self.mediaItem.comments) { 
     // Make a string that says "username comment text" followed by a line break 
     NSString *baseString = [NSString stringWithFormat:@"%@ %@\n", comment.from.userName, comment.text]; 

     // Make an attributed string, with the "username" bold 

     NSMutableAttributedString *oneCommentString = [[NSMutableAttributedString alloc] initWithString:baseString attributes:@{NSFontAttributeName : lightFont, NSParagraphStyleAttributeName : paragraphStyle}]; 

     NSRange usernameRange = [baseString rangeOfString:comment.from.userName]; 
     [oneCommentString addAttribute:NSFontAttributeName value:boldFont range:usernameRange]; 
     [oneCommentString addAttribute:NSForegroundColorAttributeName value:linkColor range:usernameRange]; 

     [commentString appendAttributedString:oneCommentString]; 
    } 

    return commentString; 
} 

+ (CGFloat) heightForMediaItem:(BLCMedia *)mediaItem width:(CGFloat)width { 
    // Make a cell 
    BLCMediaTableViewCell *layoutCell = [[BLCMediaTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"layoutCell"]; 
    [layoutCell setNeedsLayout]; 
    [layoutCell layoutIfNeeded]; 

    // Get the actual height required for the cell 
    return CGRectGetMaxY(layoutCell.commentLabel.frame); 
} 

@end 
+0

Так как это должно выглядеть? Изображение и текст ниже, затем следующее изображение и текст и т. Д.? И если вы используете ограничения, почему вы также устанавливаете фреймы? – Wain

+0

Как работает таблица VC по высоте? - Вы вызываете heightForMediaItem в -heightForRowAtIndexPath :? Или вы используете только метод justHeight для iOS 8. Кроме того, -heightForMediaItem: width: выглядит странно - вы передаете параметры BLCMedia, которые не используются. Он будет создавать новую ячейку каждый раз, когда вы вычисляете высоту. Более эффективно использовать одну ячейку прототипа, хранящуюся как ivar на контроллере табличного представления. Если вы только iOS 8, вам даже этого не нужно. –

+0

@RichTolley, я понял, что пропустил какой-то код '// Это был недостающий код // layoutCell.mediaItem = mediaItem; layoutCell.frame = CGRectMake (0, 0, width, CGRectGetHeight (layoutCell.frame)); //^^^Отсутствует код^^^', который исправил большую часть проблемы (обновленное изображение в Dropbox), но все еще немного перекрывается. Я не знал о новом методе iOS8, поэтому я попытаюсь его реализовать. –

ответ

0

Так я понял, что я делаю неправильно. Мои layoutSubViews были неправильными. Я включил скриншот плохой версии & исправленной версии в мою публикацию Dropbox. Надеюсь, это поможет кому-то еще по дороге.

enter image description here

Исходный код был:

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    // Before layout, calculate the intrinsic size of the labels (the size they "want" to be), and add 20 to the height for some vertical padding. 

    self.imageView.contentMode = UIViewContentModeScaleAspectFill; 
    self.imageView.frame = CGRectMake(self.imageView.frame.origin.x, self.imageView.frame.origin.y, 100, 100); 

    CGSize maxSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX); 
    CGSize usernameLabelSize = [self.usernameAndCaptionLabel sizeThatFits:maxSize]; 
    CGSize commentLabelSize = [self.commentLabel sizeThatFits:maxSize]; 

    self.usernameAndCaptionLabelHeightConstraint.constant = usernameLabelSize.height + 20; 
    self.commentLabelHeightConstraint.constant = commentLabelSize.height + 20; 

    // Hide the line between cells 
    self.separatorInset = UIEdgeInsetsMake(0, 0, 0, CGRectGetWidth(self.bounds)); 
} 

Это следует читать:

- (void) layoutSubviews 
{ 
    [super layoutSubviews]; 

    if (self.mediaItem == nil){ 
     return; 
    } 

    // Before layout, calculate the intrinsic size of the labels (the size they "want" to be), and add 20 to the height for some vertical padding. 
    CGSize maxSize = CGSizeMake(CGRectGetWidth(self.bounds), CGFLOAT_MAX); 
    CGSize usernameLabelSize = [self.usernameAndCaptionLabel sizeThatFits:maxSize]; 
    CGSize commentLabelSize = [self.commentLabel sizeThatFits:maxSize]; 

    self.usernameAndCaptionLabelHeightConstraint.constant = usernameLabelSize.height + 20; 
    self.commentLabelHeightConstraint.constant = commentLabelSize.height + 20; 

    if (_mediaItem.image) 
    { 
     self.imageHeightConstraint.constant = self.mediaItem.image.size.height/self.mediaItem.image.size.width * CGRectGetWidth(self.contentView.bounds); 
    } 
    else 
    { 
     self.imageHeightConstraint.constant = 100; 
    } 

    //Hide the line between cells 
    self.separatorInset = UIEdgeInsetsMake(0, 0, 0, CGRectGetWidth(self.bounds)); 
}