无论设备或方向如何,我都试图让单元格中的标签尺寸合适。我能够正确地调整行高。我也可以在cellForRowAtIndexPath
中正确设置标签高度,并可以在我的日志中检查它。但是,当它到达willDisplayRowAtIndexPath
时,标签高度已经改变,但只有在单元格不是320磅时才会改变。
这是我的代码 -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CustomCellIdentifier";
CustomInfoCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[CustomInfoCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
NSArray *objects = [[NSBundle mainBundle] loadNibNamed:@"CustomInfoCell" owner:self options:nil];
cell = objects[0];
}
// Configure the cell...
cell.customTitleLabel.text = [_data[indexPath.row] objectForKey:t];
CGFloat labelWidth = self.view.frame.size.width-40;
NSLog(@"labelWidth:%f",labelWidth);
NSString *text = [_data[indexPath.row] objectForKey:d];//correct text
CGSize labelsize=[text sizeWithFont:cell.customDetailLabel.font constrainedToSize:CGSizeMake(labelWidth, 2000.0) lineBreakMode:cell.customDetailLabel.lineBreakMode];
NSLog(@"labelsize:%f,%f",labelsize.width,labelsize.height);
//For testing
cell.customDetailLabel.backgroundColor = [UIColor redColor];
NSLog(@"Pre: %@",cell.customDetailLabel);
cell.customDetailLabel.frame=CGRectMake(20, 22, labelWidth, labelsize.height);
cell.customDetailLabel.text = text;
NSLog(@"Post: %@",cell.customDetailLabel);
return cell;
}
在willDisplayRowAtIndexPath
中,我还会打印标签信息。这是一行打印的内容 -
2013-03-24 18:33:44.009 Bridge Alert[57793:1e503] labelWidth:728.000000
2013-03-24 18:33:44.010 Bridge Alert[57793:1e503] labelsize:713.000000,76.000000
2013-03-24 18:33:44.010 Bridge Alert[57793:1e503] Pre: <UILabel: 0xad3eaf0; frame = (20 20; 280 21); text = 'Detail'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x17372eb0>>
2013-03-24 18:33:44.011 Bridge Alert[57793:1e503] Post: <UILabel: 0xad3eaf0; frame = (20 22; 728 76); text = 'Detail'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x17372eb0>>
2013-03-24 18:33:44.011 Bridge Alert[57793:1e503] Text set: <UILabel: 0xad3eaf0; frame = (20 22; 728 76); text = 'A bridge is considered “f...'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x17372eb0>>
2013-03-24 18:33:44.014 Bridge Alert[57793:1e503] Display:<UILabel: 0xad3eaf0; frame = (20 20; 728 190); text = 'A bridge is considered “f...'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x17372eb0>>
如您所见,通过Display,标签的大小已调整。我假设高度是以某种方式重新计算的,基于单元格是否为320 pt宽,这是内置的UITableViewCell宽度。
如何正确调整标签尺寸?
答案 0 :(得分:19)
使用 AutoLayout ,尽可能使用最少的代码对我有用。
在我的ViewController中,我添加了以下方法
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * yourText = //place here the text you want to calculate its size;
return 40 + [self heightForText:yourText];
}
-(CGFloat)heightForText:(NSString *)text
{
NSInteger MAX_HEIGHT = 2000;
UITextView * textView = [[UITextView alloc] initWithFrame: CGRectMake(0, 0, 320, MAX_HEIGHT)];
textView.text = text;
textView.font = [UIFont boldSystemFontOfSize:12];
[textView sizeToFit];
return textView.frame.size.height;
}
上面的代码基本上根据我的UILabel的大小+填充数来改变UITableViewCell的大小,在我的例子中我将其定义为40。
在此之后,我必须添加一些约束,如下所示,以便UILabel像UITableViewCell一样“拉伸”
运行后:
注意:我从SO中的许多线程中获取了不同的代码来提供此解决方案。我希望我能记得所有人在这里提到
希望它适合你们。
干杯
答案 1 :(得分:3)
您是否尝试取消选中自动布局?这将删除不必要的(主要是无用的)约束。
答案 2 :(得分:2)
在我看来,界面构建器/故事板可能很有用,但通常会增加另一个不需要的复杂层。我只是简单地继承UITableViewCell(就像你一样,但纯粹以编程方式完成)并使用layoutSubviews设置customDetailLabel的框架。
答案 3 :(得分:1)
我曾经遇到过完全相同的问题,因为某些原因标签高度在实际显示时会发生变化。我最终使用了免费的Sensible TableView框架,它实际上设法正确地调整大小(如果您选择使用多行UILabel,它甚至可以调整单元格的大小)。框架还自动从我的对象的属性中分配了标签的文本,这非常酷。
答案 4 :(得分:0)
尝试覆盖setFrame
类中的CustomInfoCell
,以包括在设置框架后调整单元格中元素的大小。我已经包含了用于完成此操作的代码,这与您的实现略有不同。另外,在您的标签上我将自动调整模板设置为UIViewAutoresizingFlexibleWidth
。
将此文件放在文件的顶部:
static void *kKVOContext; // See: http://www.dribin.org/dave/blog/archives/2008/09/24/proper_kvo_usage/
在viewDidLoad中包含:
[self.textLabel addObserver:self forKeyPath:@"text" options:NSKeyValueObservingOptionNew context:&kKVOContext];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
然后包括:
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];
//Resize elements to fit inside new frame
[self textChanged];
}
- (CGSize)textLabelSize
{
BOOL portrait = UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
CGFloat width = portrait ? [UIScreen mainScreen].bounds.size.width : [UIScreen mainScreen].bounds.size.height;
CGFloat maxWidth = width - 90 - TEXT_X_LEFT_PADDING;
CGSize maximumLabelSize = CGSizeMake(maxWidth, 10000);
return [self.textLabel.text sizeWithFont:self.textLabel.font
constrainedToSize:maximumLabelSize
lineBreakMode:self.textLabel.lineBreakMode];
}
- (CGFloat)cellHeight
{
CGSize expectedLabelSize = [self textLabelSize];
return (self.titleLabel.frame.origin.y+self.titleLabel.frame.size.height) + expectedLabelSize.height;
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"text"] && object == self.textLabel) {
[self textChanged];
}
if(context != &kKVOContext)
{
[super observeValueForKeyPath:keyPath
ofObject:object
change:change
context:context];
}
}
- (void)orientationChanged:(NSNotification *)note
{
//Resize text on orientation change
[self textChanged];
}
- (void)textChanged
{
CGRect newFrame = self.textLabel.frame;
newFrame.size = [self textLabelSize];
if(!CGRectEqualToRect(self.textLabel.frame, newFrame))
{
self.textLabel.frame = newFrame;
}
}
答案 5 :(得分:0)
发布基于@Paulo的简化方法,但现在适应故事板约束宽度更准确。
(SWIFT)
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier")!
// Use subclass of UITableViewCell if your cell is complex.
let label = cell.viewWithTag(3001) as! UILabel;
label.text = someStringArray[indexPath.row]
label.sizeToFit();
let y = label.frame.origin.y
let height = label.frame.size.height
let paddingBottom: CGFloat = 8
// add other controls/view height if any after the expand label
return y + height + paddingBottom
}