即使它被稱爲「表視圖」這是不是一個真正的表通常我們是怎樣想的表(即,多列多行)。如果你真的想要多個列,這取決於你。要排列它們,你必須完成確定所需寬度的工作,或者選擇一個足夠大的寬度用於所有情況。
我想我會做這樣的事情:
#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;
}
我會用同樣的[self nameColumnWidth]
和[self numberColumnWidth]
生成段標題視圖時,或者我只想讓細胞在部分的行0有名稱和號碼標題。
對於寬度我將延伸NSString
與此:
@implementation NSString (WithWidthNeeded)
- (CGFloat) widthNeeded {
// Either set the font you will use here, add it as a parameter, etc.
UIFont *font = [UIFont systemFontOfSize: 18];
CGSize maximumLabelSize = CGSizeMake(9999, font.lineHeight);
CGSize expectedLabelSize;
if([self respondsToSelector: @selector(boundingRectWithSize:options:attributes:context:)]) {
CGRect expectedLabelRect = [self boundingRectWithSize: maximumLabelSize options: NSStringDrawingUsesLineFragmentOrigin attributes: @{ NSFontAttributeName: font } context: nil];
expectedLabelRect = CGRectIntegral(expectedLabelRect);
expectedLabelSize = expectedLabelRect.size;
} else {
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString: self attributes: @{ NSFontAttributeName: font }];
if([attributedText respondsToSelector: @selector(boundingRectWithSize:options:context:)]) {
CGRect expectedLabelRect = [attributedText boundingRectWithSize: maximumLabelSize options: NSStringDrawingUsesLineFragmentOrigin context: nil];
expectedLabelRect = CGRectIntegral(expectedLabelRect);
expectedLabelSize = expectedLabelRect.size;
} else {
expectedLabelSize = [self sizeWithFont: font
constrainedToSize: maximumLabelSize
lineBreakMode: NSLineBreakByTruncatingTail];
}
}
return expectedLabelSize.width;
}
@end
當數據被改變_nameColumnWidth
和_numberColumnWidth
可以更改爲0.0,它們將被重新計算,以便列寬將被調整。
另一種方法是保持名稱和數的最大寬度的軌道時的細胞cellForRowAtIndexPath
被奠定了。如果它們增加,則觸發可見單元格重繪。這將有更好的性能,因爲它不必遍歷整個數據集以找到最長的名稱和最大的號碼。這,然而,導致列偏移,你通過數據滾動視圖下來,不再名或更大號遇到,除非最長名和最大數正好是最上面一行。
也可以做一種混合,其中nameColumnWidth
和numberColumnWidth
被設置爲最大可見(排序的局部最大值),但是後臺線程開始通過其餘數據並查找絕對最大值。當找到絕對最大值時,重新加載可見單元格。然後,列寬只有一個移位或變化。 (如果sizeWithFont:
被調用,因爲它是在UIKit的後臺線程可能不是安全的。與iOS 6或7,我認爲這將是OK)
同樣,因爲UITableView
真是UIColumnView
它留下相當一點點的工作可以讓你製作多列,可以調整其內容的寬度。
您是否希望這取決於名稱列中的內容(因此可變寬度),還是隻是將標題(「數字」)與數字對齊的情況? – Moonwalkr