簡體   English   中英

UITableViewCell子視圖不符合Autolayout約束

[英]UITableViewCell subviews are not honoring the Autolayout constraints

我正在繪制一個相當簡單的自定義UITableViewCell - 左側的縮略圖,右側的名稱和鏈接標簽。 我希望我的名字和鏈接標簽是單行的,如果文本超出單元格的寬度,則在尾部截斷。 我很確定我正確地添加了約束,但我的名字和鏈接標簽不會尊重它們。

這就是運行iOS 8的iPhone 4S上的單元格外觀:

在此輸入圖像描述

在我的代碼中,我將名稱和鏈接標簽的10點尾隨約束添加到superview(單元格的contentView ),然而,請注意,即使在橫向,iOS似乎也不遵守約束。

有人能告訴我我做錯了什么嗎? 這是我整個單元格的代碼。 我以編程方式創建視圖,並且在表視圖單元格的初始化程序中具有Autolayout約束。

#import "PopularWikiCell.h"

// Models
#import "Wiki.h"

// Pods
#import "UIImageView+AFNetworking.h"

// Constants
static const CGFloat kPadding = 10;
static const CGFloat kImageSize = 100;
const CGFloat kPopularWikiCellHeight = kImageSize + kPadding * 2;

@interface PopularWikiCell ()

@property (nonatomic, strong) UIImageView *thumbnailView;
@property (nonatomic, strong) UILabel *nameLabel;
@property (nonatomic, strong) UILabel *linkLabel;

@end

@implementation PopularWikiCell

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        // Initialise the subviews.
        _thumbnailView = [[UIImageView alloc] init];
        _thumbnailView.contentMode = UIViewContentModeScaleAspectFill;
        _thumbnailView.clipsToBounds = YES;

        _nameLabel = [[UILabel alloc] init];
        _nameLabel.backgroundColor = [UIColor blueColor];
        _nameLabel.numberOfLines = 1;
        _nameLabel.lineBreakMode = NSLineBreakByTruncatingTail;
        _nameLabel.text = @"Name";

        _linkLabel = [[UILabel alloc] init];
        _linkLabel.backgroundColor = [UIColor redColor];
        _linkLabel.text = @"Link";
        _linkLabel.numberOfLines = 1;
        _linkLabel.lineBreakMode = NSLineBreakByTruncatingTail;

        // Add the subviews.
        [self.contentView addSubview:_thumbnailView];
        [self.contentView addSubview:_nameLabel];
        [self.contentView addSubview:_linkLabel];

        _thumbnailView.translatesAutoresizingMaskIntoConstraints = NO;
        _nameLabel.translatesAutoresizingMaskIntoConstraints = NO;
        _linkLabel.translatesAutoresizingMaskIntoConstraints = NO;
        self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

        // Add the layout constraints.

        NSDictionary *metrics = @{@"kPadding" : @(kPadding),
                                  @"kImageSize" : @(kImageSize)};
        NSDictionary *views = @{@"thumbnailView" : _thumbnailView,
                                @"nameLabel" : _nameLabel,
                                @"linkLabel" : _linkLabel};

        NSArray *constraints = @[@"H:|-kPadding-[thumbnailView(kImageSize)]-kPadding-[nameLabel]-kPadding-|",
                                 @"H:[thumbnailView]-kPadding-[linkLabel]-kPadding-|",
                                 @"V:|-kPadding-[nameLabel]-0-[linkLabel]",
                                 @"V:|-kPadding-[thumbnailView(kImageSize)]"];

        [self.contentView addConstraintsFromVisualFormatStrings:constraints
                                                        options:0
                                                        metrics:metrics
                                                          views:views];
    }
    return self;
}

- (void)setWiki:(Wiki *)wiki
{
    _wiki = wiki;

    self.thumbnailView.image = nil;
    self.thumbnailView.backgroundColor = [UIColor darkGrayColor];
    __weak typeof(self) weakSelf = self;
    [self.thumbnailView setImageWithURLRequest:[NSURLRequest requestWithURL:wiki.thumbnailURL]
                              placeholderImage:nil
                                       success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
                                           __strong typeof(self) strongSelf = weakSelf;
                                           strongSelf.thumbnailView.image = image;
                                           strongSelf.thumbnailView.backgroundColor = [UIColor whiteColor];
                                       }
                                       failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {

                                       }];

    self.nameLabel.text = wiki.name;
    self.linkLabel.text = wiki.URL;

    [self.contentView setNeedsLayout];
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Selection removes all background colors so re-set it.
    [self resetSubviewBackgroundColors];

    [self.contentView setNeedsLayout];
}

- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];

    // Highlighing removes all background colors so re-set it.
    [self resetSubviewBackgroundColors];

    [self.contentView setNeedsLayout];
}

- (void)resetSubviewBackgroundColors
{
    if (self.thumbnailView.image) {
        self.thumbnailView.backgroundColor = [UIColor whiteColor];
    } else {
        self.thumbnailView.backgroundColor = [UIColor darkGrayColor];
    }
}

@end

這個問題隱藏在

self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

刪除此代碼可以解決您的問題。

如果您不希望將自動調整掩碼變為約束 - 請為cell.contentView設置所需的約束。

在你的cellForRow:方法中確保你正在調用:

cell = [tableView dequeueReusableCellWithReuseIdentifier:@"" forIndexPath:(IndexPath *)

調用this會返回一個正確大小的單元格(對於autolayout很重要)

如果這不能解決問題,請在您的單元格內部執行:

-(void)layoutSubview{ 
    [super layoutSubviews];

    [self layoutIfNeeded];
}

首先,我強烈建議使用自動布局,它解決了很多尺寸問題和許多計算

但是,如果您沒有設置約束,則必須計算字符串的長度以適合所需標簽的寬度

NSString *string = @"this is a very long string to fit into a UILabel";
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 50, 150, 20)];
UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:15.0];
label.font = font;
label.text = string;
CGSize stringSize = [string sizeWithAttributes:@{NSFontAttributeName : font}];

// check if the string is wider then the label
if (stringSize.width > label.bounds.size.width) {
    NSString *newString = [string substringWithRange:NSMakeRange(0, string.length/2)]; <----  i just divided the string into two -----
    // check if the newString fits the label
    // if not the divide again

    label.text = newString;
}else{
    label.text = string;
}
[self.view addSubview:label];

就像我在代碼中寫的那樣,我只是將字符串分成兩個字符串。 如果你有一個很長的字符串,這可能不起作用,所以你需要繼續檢查字符串是否適合標簽。

你可以使用:

[NSString stringWithFormat:@"%@...", [string substringToIndex:20]];

在字符串的末尾添加“...”

您好,您可以在自定義UITableViewCell中嘗試此操作,使用這些設置內容視圖或標簽或任何元素的框架: -

聲明: -

GRect usableSpace;
CGFloat usableWidth, usableHeight;

在實施中: -

usableSpace = [[UIScreen mainScreen] applicationFrame];
usableWidth = usableSpace.size.width;
usableHeight = usableSpace.size.height;

然后使用這些寬度和高度設置框架

我無法加載你的圖片所以我不確定你有什么問題。

我看到這段代碼,有拼寫錯誤嗎?

NSArray *constraints = 
@[
@"H:|-kPadding-[thumbnailView(kImageSize)]-kPadding-[nameLabel]-kPadding-|",
@"H:[thumbnailView]-kPadding-[linkLabel]-kPadding-|",  //this line you forgot the left edge
@"V:|-kPadding-[nameLabel]-0-[linkLabel]",
@"V:|-kPadding-[thumbnailView(kImageSize)]"
];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM