Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.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表/集合视图中的单元格间布局逻辑_Ios_Ipad_Uitableview_Layout_Uicollectionview - Fatal编程技术网

iOS表/集合视图中的单元格间布局逻辑

iOS表/集合视图中的单元格间布局逻辑,ios,ipad,uitableview,layout,uicollectionview,Ios,Ipad,Uitableview,Layout,Uicollectionview,将UITableView或UICollectionView中单独单元格的部分与单独的标题行对齐的惯用方法是什么 例如,假设我想显示如下内容: Name Number Bob 34587 Jane 32489 Barbara 23766 Montgomery 34892 #define COLUMN_SPACE 10 - (UITableViewCell) tableView: (UITableView *) tableView cellForRowA

UITableView
UICollectionView
中单独单元格的部分与单独的标题行对齐的惯用方法是什么

例如,假设我想显示如下内容:

Name       Number
Bob        34587
Jane       32489
Barbara    23766
Montgomery 34892
#define COLUMN_SPACE 10
- (UITableViewCell) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"cell"];
    // Layout the cell
    NSString *name = [myDataStore nameForIndexPath: indexPath];
    NSNumber *number = [myDataStore numberforIndexPath: indexPath];

    CGRect frame = cell.nameLabel.frame;
    frame.size.width = [self nameColumnWidth];
    cell.nameLabel.frame = frame;
    frame = cell.numberLabel.frame;
    frame.origin.x = cell.nameLabel.origin.x + cell.nameLabel.size.width + COLUMN_SPACE;
    frame.size.width = [self numberColumnWidth];
    cell.numberLabel.frame = frame;

    cell.nameLabel.text = name;
    // You would probably want to use an NSNumberFormatter here
    cell.numberLabel.text = [NSString stringWithFormat: @"%d", number.intValue];

    return cell;
}

- (CGFloat) nameColumnWidth {
    if( _nameColumnWidth <= 0.0 ) {
        _nameColumnWidth = 0.0;
        for( NSInteger s = 0; s < [myDataStore numberOfSections]; ++s ) {
            for( NSInteger r = 0; r < [myDataStore numberOfRowsInSection: s]; ++r ) {
                NSIndexPath *path = [NSIndexPath indexPathForRow: r inSection: s];
                NSString *name = [myDataStore nameForIndexPath: indexPath];
                CGFloat widthForName = [name widthNeeded];
                if( widthForName > _nameColumnWidth )
                    _nameColumnWidth = widthForName;
            }
        }
    }
    return _nameColumnWidth;
}

- (CGFloat) numberColumnWidth {
    if( _numberColumnWidth <= 0.0 ) {
        _numberColumnWidth = 0.0;
        for( NSInteger s = 0; s < [myDataStore numberOfSections]; ++s ) {
            for( NSInteger r = 0; r < [myDataStore numberOfRowsInSection: s]; ++r ) {
                NSIndexPath *path = [NSIndexPath indexPathForRow: r inSection: s];
                NSNumber *number = [myDataStore numberforIndexPath: indexPath];
                // You would probably want to use an NSNumberFormatter here
                // (in fact you want to do the same is you do in cellForRowAtIndexPath)
                NSString *numberAsString = [NSString stringWithFormat: @"%d", number.intValue];
                CGFloat widthForNumber = [numberAsString widthNeeded];
                if( widthForNumber > _numberColumnWidth )
                    _numberColumnWidth = widthForNumber;
            }
        }
    }
    return _numberColumnWidth;
}
“Name”和“Number”位将位于某种类型的头单元中。我想我可以使用一个节标题(带有一个节)

标题下的每个单元格都需要根据其内容智能地调整大小,但该大小需要影响所有其他单元格的布局


在iOS中通常是如何实现这一点的?

如果我理解正确,那么您希望第二列尽可能靠近第一列,而不中断第一列中的内容

据我所知,这在iOS上并不常用,因为对两列使用固定宽度的空间要容易得多,而且通常不需要水平压缩它们

然而,如果我真的需要完成这一点,那么:

  • 我会循环运行我所有的单元格内容并确定大小 通过调用NSString方法创建左侧内容的
    sizeWithFont:containedtosize:
    (如果在iOS7或之前使用)
    boundingRectWithSize:options:attributes:context:
    if on iOS7)
  • 我将最大的值存储在实例变量中(例如
    \u maxLeftContentWidth
  • 在我的
    -tableView:cellforrowatinexpath:
    中,我为我的 左单元格内容和右单元格内容根据我存储的 实例变量(
    \u maxLeftContentWidth
  • 每当我的单元格内容发生变化时,我都会再次运行左单元格宽度计算方法,然后调用
    [self.tableView reloadData]
    重新绘制单元格

  • 尽管它被称为“表视图”,但它并不是我们通常认为的表(即多行多列)的真正的表。如果你真的想要多个栏目,这取决于你。要排列它们,你必须计算出所需的宽度,或者选择一个适合所有情况的宽度

    我想我会这样做:

    Name       Number
    Bob        34587
    Jane       32489
    Barbara    23766
    Montgomery 34892
    
    #define COLUMN_SPACE 10
    - (UITableViewCell) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
        MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: @"cell"];
        // Layout the cell
        NSString *name = [myDataStore nameForIndexPath: indexPath];
        NSNumber *number = [myDataStore numberforIndexPath: indexPath];
    
        CGRect frame = cell.nameLabel.frame;
        frame.size.width = [self nameColumnWidth];
        cell.nameLabel.frame = frame;
        frame = cell.numberLabel.frame;
        frame.origin.x = cell.nameLabel.origin.x + cell.nameLabel.size.width + COLUMN_SPACE;
        frame.size.width = [self numberColumnWidth];
        cell.numberLabel.frame = frame;
    
        cell.nameLabel.text = name;
        // You would probably want to use an NSNumberFormatter here
        cell.numberLabel.text = [NSString stringWithFormat: @"%d", number.intValue];
    
        return cell;
    }
    
    - (CGFloat) nameColumnWidth {
        if( _nameColumnWidth <= 0.0 ) {
            _nameColumnWidth = 0.0;
            for( NSInteger s = 0; s < [myDataStore numberOfSections]; ++s ) {
                for( NSInteger r = 0; r < [myDataStore numberOfRowsInSection: s]; ++r ) {
                    NSIndexPath *path = [NSIndexPath indexPathForRow: r inSection: s];
                    NSString *name = [myDataStore nameForIndexPath: indexPath];
                    CGFloat widthForName = [name widthNeeded];
                    if( widthForName > _nameColumnWidth )
                        _nameColumnWidth = widthForName;
                }
            }
        }
        return _nameColumnWidth;
    }
    
    - (CGFloat) numberColumnWidth {
        if( _numberColumnWidth <= 0.0 ) {
            _numberColumnWidth = 0.0;
            for( NSInteger s = 0; s < [myDataStore numberOfSections]; ++s ) {
                for( NSInteger r = 0; r < [myDataStore numberOfRowsInSection: s]; ++r ) {
                    NSIndexPath *path = [NSIndexPath indexPathForRow: r inSection: s];
                    NSNumber *number = [myDataStore numberforIndexPath: indexPath];
                    // You would probably want to use an NSNumberFormatter here
                    // (in fact you want to do the same is you do in cellForRowAtIndexPath)
                    NSString *numberAsString = [NSString stringWithFormat: @"%d", number.intValue];
                    CGFloat widthForNumber = [numberAsString widthNeeded];
                    if( widthForNumber > _numberColumnWidth )
                        _numberColumnWidth = widthForNumber;
                }
            }
        }
        return _numberColumnWidth;
    }
    
    更改数据时,可以将
    \u name columnwidth
    \u numberColumnWidth
    更改为0.0,并重新计算它们,以便调整列宽

    另一种方法是在
    cellforrowatinexpath
    中排列单元格时,跟踪名称和编号的最大宽度。如果它们增加,则触发要重绘的可见单元格。这将有更好的性能,因为它不必遍历整个数据集来查找最长的名称和最大的数字。但是,这将导致在向下滚动视图浏览数据时,列发生移动,并且会遇到更长的名称或更大的数字,除非最长的名称和最大的数字恰好位于顶行

    也可以进行一种混合,将
    nameColumnWidth
    numberColumnWidth
    设置为可见的最大值(局部最大值的排序),然后启动一个后台线程遍历其余数据并找到绝对最大值。当发现绝对最大值时,可见单元格将重新加载。然后,列宽只有一次移动或更改。(如果正在调用
    sizeWithFont:
    ,则后台线程可能不安全,因为它位于UIKit中。对于iOS 6或7,我认为可以)


    同样,由于
    UITableView
    实际上是一个
    UIColumnView
    ,您需要做大量的工作来创建多个可以调整其内容宽度的列。

    您希望这取决于名称列中的内容(因此是可变宽度),还是仅仅是对齐标题(“数字”)的情况有数字吗?