2013-03-25 37 views
4

我試圖讓單元中的標籤成爲正確的大小,而不管設備或方向如何。我能夠正確地確定行高的大小。我也可以在cellForRowAtIndexPath中正確設置標籤高度,並可以在我的日誌中檢查。但是,當它達到willDisplayRowAtIndexPath時,標籤高度已經改變,但只有當單元不是320點寬時。調整UILabel以適應不同寬度的自定義UITableViewCell中的文本

這裏是我的代碼 -

- (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>> 

正如您所看到的,通過顯示,標籤被調整大小。我假設高度是以某種方式重新計算的,基於單元是否寬320 pt,這是內置在UITableViewCell寬度。

我怎樣才能讓標籤尺寸正確?

+1

您是否嘗試過取消選中自動佈局? – Angelo 2013-03-26 03:45:22

+0

安傑洛,它看起來像你是贏家。將它作爲答案發布,我會仔細檢查它是否適用於所有設備和方向。謝謝。 – James 2013-03-26 11:25:20

+1

很高興我能幫到你。 :) – Angelo 2013-03-26 16:56:43

回答

3

您是否嘗試過取消選中自動佈局?這將刪除不必要的(主要是無益的)約束。

+3

在我眼裏約束是最有用的開發工具之一,蘋果公司已經建成......我強烈建議學習他們。 – mirkokiefer 2013-11-02 11:52:03

+0

@mirkokiefer在發佈時,我不認爲自動佈局是必要的。現在,是的。我總是使用自動佈局。 – Angelo 2016-03-23 03:53:22

1

我曾經有過完全相同的問題,出於某種原因,標籤高度在實際顯示時會發生變化。我最終使用了免費的Sensible TableView框架,它實際上可以正確地進行大小調整(如果您選擇使用多行UILabel,它甚至會調整單元格的大小)。該框架還從我的對象的屬性中自動分配標籤的文本,這非常酷。

+0

謝謝,我希望不需要一個定製的框架理論上應該是一個簡單的修復,但它絕對看起來像一個方便的框架。 – James 2013-03-25 02:04:36

+0

我會嘗試檢查他們的源代碼並獲得你需要的部分。 – Matt 2013-03-25 02:26:42

+0

看起來他們是預編譯的,至少在免費版本: -/ – James 2013-03-25 11:37:15

0

在您的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; 
    } 
} 
2

在我看來,界面生成器/分鏡可以是有用的,但往往會增加另一層不必要的複雜性。我只是簡單地繼承UITableViewCell的子類(就像你一樣,但是純粹以編程方式)並使用layoutSubviews設置customDetailLabel的框架。

19

這就是我用最小代碼儘可能使用AutoLayout

在我的視圖控制器我添加下列方法

-(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的尺寸+這在我的情況下,我定義爲40的填充數的UITableViewCell的大小。

在此之後,我不得不添加一些限制,如爲了使的UILabel爲「拉伸」的定義UITableViewCell確實

enter image description here

它運行後顯示如下:

enter image description here

說明:我從SO中的多個線程中提取了不同的代碼片段來提出此解決方案。我希望我能記住所有他們在這裏提到

希望它適用於你們。

乾杯

+1

謝謝,這真是棒極了(我剛在左側添加約束以及) – gberginc 2014-07-07 20:28:05

+1

美麗的一段代碼!你救了我的夜晚我的朋友! – Septronic 2015-10-11 22:45:14

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 
} 
相關問題