iOS8包含大小类的UIView.systemLayoutSizeFittingSize的值不正确

时间:2015-07-22 13:24:11

标签: ios xcode autolayout size-classes

在iOS 8上启用UIView.systemLayoutSizeFittingSize时,我遇到了方法Size Classes的奇怪问题。 作为示例,我使用Paul的自动高度单元教程项目。还可以找到用于演示目的的矿山修改项目,here

所以在iOS 7上看起来很不错。

enter image description here enter image description here

但是在iOS 8方法中,返回的值越来越小,然后单元格开始分崩离析。

enter image description here enter image description here

Size Classes关闭时,此问题已消失。我不知道如何接受这一点,此时只有我知道的解决方案是转为Size Classes

代码

ViewController.m (108行)

#import "ViewController.h"
#import "CustomTableViewCell.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate> {

    NSMutableArray *_fontArray;
    NSMutableArray *_quoteArray;

}

@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (strong, nonatomic) CustomTableViewCell *customCell;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    self.tableView.delegate = self;
    self.tableView.dataSource = self;

//    self.navigationItem.rightBarButtonItem = self.editButtonItem;

    _fontArray = [[UIFont familyNames] mutableCopy];
    for(int i = 0; i < 100; i++) {
        [_fontArray addObjectsFromArray:[UIFont familyNames]];
    }
    NSLog(@"Size: %d", [_fontArray count]);

    _quoteArray = [@[@"For the past 33 years, I have looked in the mirror every morning and asked myself: 'If today were the last day of my life, would I want to do what I am about to do today?' And whenever the answer has been 'No' for too many days in a row, I know I need to change something. -Steve Jobs",
                     @"Be a yardstick of quality. Some people aren't used to an environment where excellence is expected. - Steve Jobs",
                     @"Innovation distinguishes between a leader and a follower. -Steve Jobs"] mutableCopy];


    // Use iOS 8 new auto sizing feature for heights (don't need to calculate yourself)
//    _tableView.rowHeight = UITableViewAutomaticDimension;

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    return [_fontArray count];
}

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

    CustomTableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomCell"];

    cell.fontNameLabel.text = _fontArray[indexPath.row];

    int quoteIndex = indexPath.row % [_quoteArray count];
    cell.quoteLabel.text = _quoteArray[quoteIndex];
    cell.quoteLabel2.text = _quoteArray[quoteIndex];
    NSString *fontName = _fontArray[indexPath.row];
    cell.quoteLabel.font = [UIFont fontWithName:fontName size:17];
    cell.quoteLabel2.font = [UIFont fontWithName:fontName size:17];
    return cell;

}

// NOTE: in iOS 8 you can use the automatic height calculations from AutoLayout,
//  and you can avoid writing this height method. Just comment it out, and uncomment
//  the line in viewDidLoad for
//  _tableView.rowHeight = UITableViewAutomaticDimension;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Calculate a height based on a cell
    if(!self.customCell) {
        self.customCell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    }

    // Configure the cell
    self.customCell.fontNameLabel.text = _fontArray[indexPath.row];

    int quoteIndex = indexPath.row % [_quoteArray count];
    self.customCell.quoteLabel.text = _quoteArray[quoteIndex];
    self.customCell.quoteLabel2.text = _quoteArray[quoteIndex];
    NSString *fontName = _fontArray[indexPath.row];
    self.customCell.quoteLabel.font = [UIFont fontWithName:fontName size:17];
    self.customCell.quoteLabel2.font = [UIFont fontWithName:fontName size:17];


    // Layout the cell

    [self.customCell layoutIfNeeded];

    // Get the height for the cell

    CGFloat height = [self.customCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    // Padding of 1 point (cell separator)
    CGFloat separatorHeight = 1;
    NSLog(@"%f",height);

    return height + separatorHeight;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {

    return 140;

}

@end

CustomTableViewCell.h (10行)

#import <UIKit/UIKit.h>

@interface CustomTableViewCell : UITableViewCell

@property (weak, nonatomic) IBOutlet UILabel *quoteLabel;
@property (weak, nonatomic) IBOutlet UILabel *fontNameLabel;
@property (strong, nonatomic) IBOutlet UILabel *quoteLabel2;

@end

CustomTableViewCell.m (39行)

#import "CustomTableViewCell.h"

@implementation CustomTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)awakeFromNib
{
    // Initialization code
}

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

    // Configure the view for the selected state
}

// CODE FIX layouts by setting the maxPreferredWidth on any UILabel that can be
//  multiline – you may have to do similar settings to other UI elements
//  This logic fixes the layout for any UILabels that don't go up to the margins, they
//  might be offset by a constraint that isn't the standard.

- (void)layoutSubviews {
    [super layoutSubviews];
    [self.contentView layoutIfNeeded];
    self.fontNameLabel.preferredMaxLayoutWidth = self.fontNameLabel.frame.size.width;
    self.quoteLabel.preferredMaxLayoutWidth = self.quoteLabel.frame.size.width;
    self.quoteLabel2.preferredMaxLayoutWidth = self.quoteLabel2.frame.size.width;
}

@end

1 个答案:

答案 0 :(得分:1)

您的问题可能是因为当您使用使用dequeueReusableCellWithIdentifier创建的原型单元格时,返回的单元格没有大小类,因为它不是视图层次结构的一部分,因此没有关联traitCollection用它。

我通过暂时将单元格添加到表视图,进行大小调整然后删除它来解决这个问题。添加后,customCell获取控制器和布局的大小类,然后使用任何大小类相关的字体,约束等...真实单元格与UITableView的一部分没有相同的问题,因为它们具有大小类。 / p>

因此,请尝试按如下方式更改身高计算:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {

    // Calculate a height based on a cell
    if(!self.customCell) {
        self.customCell = [self.tableView dequeueReusableCellWithIdentifier:@"CustomCell"];
    }

    // ***
    // *** Add custom cell to the table view so it obtains a size class
    // *** for layout. Also mark it as needing layout.
    // ***
    [self.tableView addSubview:customCell];
    [customCell setNeedsLayout];

    // Configure the cell
    self.customCell.fontNameLabel.text = _fontArray[indexPath.row];

    int quoteIndex = indexPath.row % [_quoteArray count];
    self.customCell.quoteLabel.text = _quoteArray[quoteIndex];
    self.customCell.quoteLabel2.text = _quoteArray[quoteIndex];
    NSString *fontName = _fontArray[indexPath.row];
    self.customCell.quoteLabel.font = [UIFont fontWithName:fontName size:17];
    self.customCell.quoteLabel2.font = [UIFont fontWithName:fontName size:17];


    // Layout the cell

    [self.customCell layoutIfNeeded];

    // Get the height for the cell

    CGFloat height = [self.customCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;

    // Padding of 1 point (cell separator)
    CGFloat separatorHeight = 1;
    NSLog(@"%f",height);

    // ***
    // *** Remove cell from the table view
    // ***
    [customCell removeFromSuperview];

    return height + separatorHeight;
}