调整UILabel的大小以适应不同宽度的自定义UITableViewCell中的文本

我试图让一个单元格中的标签成为正确的尺寸,而不pipe设备或方向如何。 我能够正确地获得行高度的大小。 我也能够在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>> 

正如你所看到的,通过显示,标签被resize。 我假设高度是以某种方式重新计算,基于如果单元格是320磅宽,这是在UITableViewCell宽度内置。

我怎样才能让标签尺寸正确?

你有没有试图取消select自动布局? 这将删除不必要的(主要是无益的)约束。

这是使用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; } 

上面的代码基本上改变了UITableViewCell的大小,基于我的UILabel +填充数的大小,在我的例子中我定义为40。

在此之后,我不得不添加一些约束,如下所示,以便使UILabel像UITableViewCell一样“拉伸”

在这里输入图像说明

运行后:

在这里输入图像说明

注意:我从SO中的多个线程获取了不同的代码片段来提出这个解决scheme。 我希望我能记住所有这些在这里提到

希望它适合你们。

干杯

在我看来,界面构build器/故事板可以是有用的,但往往增加了另一个不必要的复杂层。 我只是简单地inheritanceUITableViewCell(就像你是纯粹的编程),并使用layoutSubviews设置customDetailLabel的框架。

我曾经有过完全相同的问题,由于某种原因,标签高度在实际显示时会发生变化。 我最终使用了免费的Sensible TableView框架,它实际上可以正确地resize(如果您select使用多行UILabel,甚至可以调整单元格的大小)。 该框架还从我的对象的属性中自动分配标签的文本,这非常酷。

尝试覆盖CustomInfoCell类中的setFrame ,以在设置框架后包括调整元素在单元格中的大小。 我已经包含了我用来完成这个的代码,这与你的实现有点不同。 另外,在你的标签上,我设置了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; } } 

只要发布我自己的基于@Paulo的简化方法,但现在适应故事板约束宽度和更准确。

(迅速)

 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 }