Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/107.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 不使用contentView框架计算UITableViewCell高度的最佳方法_Ios_Objective C_Iphone_Uitableview_Heightforrowatindexpath - Fatal编程技术网

Ios 不使用contentView框架计算UITableViewCell高度的最佳方法

Ios 不使用contentView框架计算UITableViewCell高度的最佳方法,ios,objective-c,iphone,uitableview,heightforrowatindexpath,Ios,Objective C,Iphone,Uitableview,Heightforrowatindexpath,摘要 考虑到我们并不总是知道单元格或其内容视图的框架是什么(由于编辑、旋转、附件视图等),当单元格包含可变高度文本字段或标签时,在表格视图:heightForRowAtIndexPath:中计算高度的最佳方法是什么 我的UITableViewController的一个包含以下演示文稿: UITableViewCell和UITextView UITextView的宽度和高度应与UITableViewCell相同 我创建了UITableViewCell子类,然后用UITextView初始化它(UI

摘要

考虑到我们并不总是知道单元格或其内容视图的框架是什么(由于编辑、旋转、附件视图等),当单元格包含可变高度文本字段或标签时,在
表格视图:heightForRowAtIndexPath:
中计算高度的最佳方法是什么

我的
UITableViewController的一个
包含以下演示文稿:
UITableViewCell和UITextView

UITextView的宽度和高度应与UITableViewCell相同

我创建了UITableViewCell子类,然后用UITextView初始化它(UITextView是我的UITableViewController的一个私有字段)

我在UITableViewCell子类中实现了以下方法:

- (void)layoutSubviews{
    [super layoutSubviews];
    CGFloat height = [textView.text sizeWithFont:textView.font constrainedToSize:CGSizeMake(textView.frame.size.width, MAXFLOAT)].height + textView.font.lineHeight;
    textView.frame = CGRectMake(0, 0, self.contentView.frame.size.width, (height < textView.font.lineHeight * 4) ? textView.font.lineHeight * 4 : height);    
    [self.contentView addSubview:textView];
}
现在,我的问题是: 加载视图后,UITableViewController将按以下顺序调用方法:(为了简化,我将删除一些方法,如titleForHeaderInSection等)

只有那时

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
看!我应该在cellForRowAtIndexPath之前返回正确的UITableViewCell高度! 这意味着:我不知道UITableViewCell内容视图框架。我无法通过编程来获取它

此宽度可以是以下宽度之一:

  • iPhone普通桌,纵向
  • iPhone普通桌,横向
  • iPhone分组表,纵向
  • iPhone分组表,横向
  • iPad也是如此(另外4个值)
  • 不要忘记,由于UITableViewCell accessoryType或UITableView编辑状态,contentView框架可以更小。(例如,如果我们的UITableViewCell在任何编辑状态下具有任意高度的多行UILabel,并且具有任何accessoryView)

    所以这个问题很基本:我无法获取单元格contentView帧宽度进行约束,因为我应该在单元格布局contentView之前返回这个高度。(顺便说一句,这是非常合乎逻辑的)但是这个contentView框架真的很重要

    当然,有时我可以准确地知道这个宽度,并“硬编码”它 (例如:UITableViewCellAccessoryDisclosureIndicator的宽度为20 px,tableView不能处于编辑状态,那么我可以写入self.view.frame.size.width-20,任务就完成了)! 或者有时contentView等同于UITableViewController的图幅

    有时我在-tableView:heightforrowatinexpath:method.中使用self.view.frame.width。。(就像现在一样,它工作得很好,但不是很完美,因为分组的UITableView应该减去一些常量值,对于2个设备*2个方向,它们是不同的)

    有时我在UITableViewCell中定义了一些常量(如果我确切知道宽度的话)

    有时我使用一些虚拟的预分配UITableViewCell(这很愚蠢,但有时非常优雅且易于使用)

    但我不喜欢这些

    最好的决定是什么? 也许我应该创建一些助手类,该类将使用以下参数进行初始化: 附件视图、设备方向、设备类型、表视图编辑状态、表视图样式(普通、分组)、控制器图幅,以及其他一些,其中包括一些常量(如分组表视图偏移量等),并使用它来查找预期的UITableViewCell内容视图宽度?;)


    谢谢

    在创建任何
    UITableViewCell
    单元格之前,表视图使用
    tableView:heightforrowatinexpath:
    方法确定其内容大小。如果您停下来想一想,这是有意义的,因为您使用
    UIScrollView
    要做的第一件事就是设置其contentSize。我以前也遇到过类似的问题,我发现最好有一个helper函数,它可以将内容放入UITableViewCell并预测该
    UITableViewCell
    的高度。因此,我认为您需要创建某种数据结构,将文本存储在每个
    UITableViewCell
    中,这是一个NSDictionary,NSINDExpath作为键,文本作为值,这样做很好。这样,您就可以在不引用
    UITableViewCell

    的情况下找到所需文本的高度。尽管您可以在UITableViewCell子类的'-layoutSubviews'中真正动态地计算表视图单元格中包含的标签的高度,但没有类似的方法(据我所知)对于表格视图委托的'-tableView:heightForRowAtIndexPath:'中的单元格高度

    考虑这一点:

    - (void)layoutSubviews
    {
        [super layoutSubviews];
    
        CGSize size = [self.textLabel.text sizeWithFont:self.textLabel.font
                                      constrainedToSize:CGSizeMake(self.textLabel.$width, CGFLOAT_MAX)
                                          lineBreakMode:self.textLabel.lineBreakMode];
        self.textLabel.$height = size.height;
    }
    
    不幸的是,到调用“-tableView:heightforrowatinexpath:”时,这还为时过早,因为
    cell.textlab.frame
    尚未设置为
    CGRectZero={{0,0},{0,0}

    好吧,无论是内容视图的框架,还是对单个标签的框架进行汇总,您都无法做到这一点

    我能想到的唯一方法是想出一个方便的类、方法、常量或诸如此类的东西,试图在任何设备上覆盖任何设备方向上的所有可能宽度:

    @interface UITableView (Additions)
    
    @property (nonatomic, readonly) CGFloat padding;
    
    @end
    
    @implementation UITableView (Additions)
    
    - (CGFloat)padding
    {
        if (self.formStyle == PTFormViewStylePlain) {
            return 0;
        }
    
        if (self.$width < 20.0) {
            return self.$width - 10.0;
        }
    
        if (self.$width < 400.0 || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            return 10.0;
        }
    
        return MAX(31.0, MIN(45.0, self.$width * 0.06));
    }
    
    @end
    
    @接口UITableView(添加)
    @属性(非原子,只读)CGFloat填充;
    @结束
    @实现UITableView(添加)
    -(CGFloat)填充
    {
    if(self.formStyle==PTFormViewStylePlain){
    返回0;
    }
    if(自宽<20.0){
    返回自。$width-10.0;
    }
    if(self.$width<400.0 | |[[UIDevice currentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPhone){
    返回10.0;
    }
    返回最大值(31.0,最小值(45.0,自身$width*0.06));
    }
    @结束
    
    还要注意的是,最近我们还推出了新的iPhone5横向4英寸宽(568而不是480)


    这整件事很令人不安,我知道。。。干杯。

    您不是决定表视图数据源和委托方法调用顺序的人。这是由数据源和委托UITableView类完成的,因此
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    - (CGFloat)tableView:(UITableView*)tableView heightForRowAtIndexPath:(NSIndexPath*)indexPath{ 
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
    
        CGSize size = [self.textLabel.text sizeWithFont:self.textLabel.font
                                      constrainedToSize:CGSizeMake(self.textLabel.$width, CGFLOAT_MAX)
                                          lineBreakMode:self.textLabel.lineBreakMode];
        self.textLabel.$height = size.height;
    }
    
    @interface UITableView (Additions)
    
    @property (nonatomic, readonly) CGFloat padding;
    
    @end
    
    @implementation UITableView (Additions)
    
    - (CGFloat)padding
    {
        if (self.formStyle == PTFormViewStylePlain) {
            return 0;
        }
    
        if (self.$width < 20.0) {
            return self.$width - 10.0;
        }
    
        if (self.$width < 400.0 || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
            return 10.0;
        }
    
        return MAX(31.0, MIN(45.0, self.$width * 0.06));
    }
    
    @end