Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/116.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITableViewCell中所有方向的动态UILabel高度/宽度_Ios_Uikit - Fatal编程技术网

Ios UITableViewCell中所有方向的动态UILabel高度/宽度

Ios UITableViewCell中所有方向的动态UILabel高度/宽度,ios,uikit,Ios,Uikit,我的问题基本上归结为支持UITableCell中UILabel(以及我假设的其他元素)动态高度的最佳方法,以及在旋转时正确调整标签宽度/高度和单元格高度的大小 我知道如何获得UILabel的预期高度,并相应地调整高度,但当您支持横向时,事情似乎变得相当棘手 我想这可能是一条路线,但我不确定你如何将其与需要计算细胞高度的表格结合起来。在init上手动设置帧,以确保他们根据已知数量进行计算,但这仅解决部分问题 这是我正在处理的图像,红色箭头指向动态高度标签,蓝色箭头指向将改变高度的单元格 我已经设

我的问题基本上归结为支持UITableCell中UILabel(以及我假设的其他元素)动态高度的最佳方法,以及在旋转时正确调整标签宽度/高度和单元格高度的大小

我知道如何获得UILabel的预期高度,并相应地调整高度,但当您支持横向时,事情似乎变得相当棘手

我想这可能是一条路线,但我不确定你如何将其与需要计算细胞高度的表格结合起来。在init上手动设置帧,以确保他们根据已知数量进行计算,但这仅解决部分问题

这是我正在处理的图像,红色箭头指向动态高度标签,蓝色箭头指向将改变高度的单元格

我已经设法让它正常工作,但不确定它是否是正确的方法

以下是我学到的一些东西:
  • cellforrowatinexpath
    中的cell.frame始终在纵向模式下给出其大小。(例如,对于iphone应用程序,它总是报告320)
  • 将原型单元存储在属性中以供引用也有相同的问题,始终处于纵向模式
  • 在这个用例中,自动调整标签宽度的遮罩大小似乎是无用的,事实上会导致旋转时计算的高度出现问题
  • cellforrowatinexpath
    中的tableView.frame以正确的方向显示其大小
  • 您需要在轮换时调用
    [tableView reloadData]
    。我找不到任何其他方法来更新单元格和标签高度
以下是我采取的措施,以使其为我工作:
  • 禁用UILabels上的任何自动调整大小遮罩,因为它们会因某些原因干扰获得正确的标签高度
  • viewdiload
    上,我获取每个标签字体的引用,以及标签宽度百分比与纵向视图中的tableView的浮点值

    CWProductDetailDescriptionCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
    self.descriptionLabelWidthPercentage = cell.descriptionLabel.frame.size.width / 320;
    self.descriptionLabelFont = cell.descriptionLabel.font;
    
  • heightforrowatinexpath
    中,我使用tableView宽度和已获取的百分比计算单元格高度:

    case TableSectionDescription:
        CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
        CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:self.descriptionLabelFont];
        return newLabelFrameSize.height + kTextCellPadding;
    
  • cellforrowatinexpath
    中,我计算标签帧的帧并更新它

    cell = [tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
    ((CWProductDetailDescriptionCell *)cell).descriptionLabel.text = self.product.descriptionText;
    CGRect oldFrame = ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame;
    CGFloat labelWidth = self.tableView.frame.size.width * self.descriptionLabelWidthPercentage;
    CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(labelWidth, MAXFLOAT) AndFont:((CWProductDetailDescriptionCell *)cell).descriptionLabel.font];
    ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, labelWidth, newLabelFrameSize.height);
    
  • didRotateFromInterfaceOrientation
    中,您需要
    [self.tableView重载数据]

  • 此方法存在的问题:
  • 您不能利用自动调整大小的遮罩和边距
    • 在返回
      cellforrowatinedexpath
      中的单元格之前(不确定这是否正确)
    • 它们在某种程度上打乱了高度计算,而你的标签最终会比风景画中的标签更糟糕
  • 如果标签的宽度在和中的百分比不相等,则需要知道这两个百分比
  • 您需要知道/计算标签宽度百分比。理想情况下,在自动调整大小的遮罩完成工作后,您可以动态计算这些
  • 感觉很笨拙。我有一种感觉,在缩进编辑模式下,我会遇到更多的麻烦

  • 是这样。正确的方法是什么?我见过很多这样的问题,但没有一个能完全解决这个问题。

    显然,我需要写下我的巨大问题,然后在电脑前休息一下才能弄清楚

    这就是解决方案: 动态计算UILabel高度并利用自动调整遮罩大小的主要步骤包括:
  • 为每个需要调整高度的单元保留一个原型单元
  • rowAtIndexPath高度中
    • 根据所处的方向调整参考单元格宽度
    • 然后,您可以可靠地使用包含的UILabel框架宽度来计算高度
  • 除了初始设置外,不要在
    cellForRowAtIndexPath
    中进行任何帧调整
    • UITableViewCell在调用后立即执行所有布局工作,因此您的努力充其量是徒劳的,最坏的情况下,它们会把事情搞砸
  • 您在
    中的帧调整是否会显示单元格中的行路径
    • 我很生气我忘了这件事
    • 它发生在所有UITableViewCell内部布局之后和绘制之前
    • 带有自动调整大小遮罩的标签已具有正确的宽度,可用于计算
  • 在viewDidLoad中,将抓取引用加载到需要调整高度的单元 请注意,这些是保留的/strong(ARC),从不添加到表本身

    self.descriptionReferenceCell = [self.tableView dequeueReusableCellWithIdentifier:@"DescriptionCell"];
    self.attributeReferenceCell = [self.tableView dequeueReusableCellWithIdentifier:@"AttributeCell"];
    
    heightforrowatinexpath
    do计算可变高度单元格 我首先更新引用单元格的宽度,以便它显示其子视图(UILabels),然后我可以将其用于计算。然后,我使用更新的标签宽度来确定标签的高度,并添加任何必要的单元格填充来计算单元格高度。(请记住,只有当单元格的高度随标签一起改变时,才需要进行这些计算)

    cellforrowatinexpath
    中,不要根据方向执行任何与布局相关的动态更新 在
    中,将为rowatinedxpath显示单元格
    更新标签高度 由于表格单元格已经执行了
    布局子视图
    ,因此标签已经具有正确的宽度,我使用它来计算标签的确切高度。我可以安全地更新我的标签高度

    case TableSectionDescription:
        CGRect oldFrame = ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame;
        CGSize newLabelFrameSize = [self sizeForString:self.product.descriptionText WithConstraint:CGSizeMake(oldFrame.size.width, MAXFLOAT) AndFont:((CWProductDetailDescriptionCell *)cell).descriptionLabel.font];
        ((CWProductDetailDescriptionCell *)cell).descriptionLabel.frame = CGRectMake(oldFrame.origin.x, oldFrame.origin.y, oldFrame.size.width, newLabelFrameSize.height);
        break;
    
    在旋转时重新加载数据 如果不重新加载数据,可见单元格将不会更新其高度和标签

    -(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
        [self.tableView reloadData];
    }
    
    需要指出的另一点是,我使用了一个helper类来计算标签高度,这个标签高度只包含基本调用。实际上,它不再保存太多的代码(我以前在那里有其他东西),所以直接使用普通的方法

    - (CGSize) sizeForString:(NSString*)string WithConstraint:(CGSize)constraint AndFont:(UIFont *)font {
        CGSize labelSize = [string sizeWithFont:font
                              constrainedToSize:constraint 
                                  lineBreakMode:UILineBreakModeWordWrap];
        return labelSize;
    }
    
    我同意大多数人的看法
    - (CGSize) sizeForString:(NSString*)string WithConstraint:(CGSize)constraint AndFont:(UIFont *)font {
        CGSize labelSize = [string sizeWithFont:font
                              constrainedToSize:constraint 
                                  lineBreakMode:UILineBreakModeWordWrap];
        return labelSize;
    }
    
    NSLog(@"Cell frame.size.width=%f", cell.frame.size.width);
    
    @interface MyViewController () {
        NSArray *_cellHeights; // array of arrays (for each table view section) of numbers (row heights)
    }
    
    - (void)_recalculateCellHeights
    {
        NSMutableArray *cellHeights = [[NSMutableArray alloc] init];
    
        for (NSUInteger section=0; section<[self.tableView numberOfSections]; section++) {
            NSMutableArray *sectionCellHeights = [[NSMutableArray alloc] init];
    
            for (NSUInteger row=0; row<[self.tableView numberOfRowsInSection:section]; row++) {
                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:section];
                UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    
                // Set cell's width to match table view's width
                CGRect cellFrame = cell.frame;
                cellFrame.size.width = CGRectGetWidth(self.tableView.frame);
                cell.frame = cellFrame;
    
                CGFloat cellHeight = self.tableView.rowHeight; // default
    
                if (cell.textLabel.numberOfLines == 0 || (cell.detailTextLabel && cell.detailTextLabel.numberOfLines == 0)) {
                    [cell layoutIfNeeded]; // this is necessary on iOS 7 to give the cell's text labels non-zero frames
    
                    // Calculate the height of the cell based on the text
                    [cell.textLabel sizeToFit];
                    [cell.detailTextLabel sizeToFit];
    
                    cellHeight = CGRectGetHeight(cell.textLabel.frame) + CGRectGetHeight(cell.detailTextLabel.frame);
    
                    // This is the best I can come up with for this :(
                    if (self.tableView.separatorStyle != UITableViewCellSeparatorStyleNone) {
                        cellHeight += 1.0;
                    }
                }
    
                [sectionCellHeights addObject:[NSNumber numberWithFloat:cellHeight]];
            }
    
            [cellHeights addObject:sectionCellHeights];
        }
    
        _cellHeights = cellHeights;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    
            // Assign any fonts or other adjustments which may affect height here
    
            // Enable multiple line support so textLabel can grow vertically
            cell.textLabel.numberOfLines = 0;
        }
    
        // Configure the cell...
        cell.textLabel.text = [self.texts objectAtIndex:indexPath.section];
    
        return cell;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        if (_cellHeights) {
            NSArray *sectionCellHeights = [_cellHeights objectAtIndex:indexPath.section];
            return [[sectionCellHeights objectAtIndex:indexPath.row] floatValue];
        }
    
        return self.tableView.rowHeight; // default
    }
    
    - (void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
    
        [self _recalculateCellHeights];
        [self.tableView reloadData];
    }
    
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
    {
        [self _recalculateCellHeights];
        [self.tableView reloadData];
    }