【问题标题】:iOS8 incorrrect value of UIView.systemLayoutSizeFittingSize with Size ClassesiOS 8 UIView.systemLayoutSizeFitting Size 与 Size Classes 的值不正确
【发布时间】:2015-10-12 09:47:41
【问题描述】:

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

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


但在 iOS 8 上,方法返回的值要小得多,然后单元格开始分裂。


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

【问题讨论】:

    标签: ios xcode autolayout size-classes


    【解决方案1】:

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

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

    所以试着改变你的身高计算如下:

    - (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;
    }
    

    【讨论】:

    • @Dudi 很确定主要的性能影响是实际大小计算。添加/删除视图应该相对便宜。 traitCollection 是 UITraitEnvironment 接口的只读属性。另一种选择是覆盖 traitCollection 属性 getter 并在真实的以某种方式为 nil 时提供默认值。发布的方法还处理与呈现它们的代码具有不同大小类别的弹出框等(例如 iPad)。压倒一切的方法需要您以某种方式计算出正确的尺寸等级。
    猜你喜欢
    • 2015-11-01
    • 2015-05-18
    • 2021-06-08
    • 2015-04-18
    • 2020-11-18
    • 1970-01-01
    • 2020-03-22
    • 2022-12-09
    • 2013-07-28
    相关资源
    最近更新 更多