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上并不常用,因为对两列使用固定宽度的空间要容易得多,而且通常不需要水平压缩它们 然而,如果我真的需要完成这一点,那么:
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
,您需要做大量的工作来创建多个可以调整其内容宽度的列。您希望这取决于名称列中的内容(因此是可变宽度),还是仅仅是对齐标题(“数字”)的情况有数字吗?