2013-06-24 76 views
2

我試圖根據其中包含的UITextView的高度動態調整一些UITableViewCell的大小。 通過保持指向UITextView的指針並在heightForRowAtIndexPath中獲取它的內容大小,存在大量的解決方案,但是當整個表是動態創建的,行數未知並且行數未知的行包含UITextView的這僅僅是'可能。 如果我可以在heightForRowAtIndexPath期間調用有問題的單元格,那很容易,但是會導致無限循環和崩潰,因爲在創建任何單元格之前調用此方法。 任何其他解決方案?基於文本輸入動態調整UITableViewCell的大小

我使用的是UITableViewCell子類我的手機是這樣的:

- (void)initalizeInputView { 
    // Initialization code 
    self.selectionStyle = UITableViewCellSelectionStyleNone; 
    self.textView = [[UITextView alloc] initWithFrame:CGRectZero]; 
    self.textView.autocorrectionType = UITextAutocorrectionTypeDefault; 
    self.textView.autocapitalizationType = UITextAutocapitalizationTypeNone; 
    self.textView.textAlignment = NSTextAlignmentRight; 
    self.textView.textColor = [UIColor lightBlueColor]; 
    self.textView.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:17]; 
    self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth; 
    self.textView.keyboardType = UIKeyboardTypeDefault; 
    [self addSubview:self.textView]; 

    self.textView.delegate = self; 
} 

- (BOOL)resignFirstResponder { 
    if (_delegate && [_delegate respondsToSelector:@selector(tableViewCell:didEndEditingWithLongString:)]) { 
     [_delegate tableViewCell:self didEndEditingWithLongString:self.stringValue]; 
    } 
    return [super resignFirstResponder]; 
} 

- (void)setKeyboardType:(UIKeyboardType)keyboardType 
{ 
    self.textView.keyboardType = keyboardType; 
} 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) { 
     [self initalizeInputView]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     [self initalizeInputView]; 
    } 
    return self; 
} 

- (void)setSelected:(BOOL)selected { 
    [super setSelected:selected]; 
    if (selected) { 
     [self.textView becomeFirstResponder]; 
    } 
} 

- (void)setSelected:(BOOL)selected animated:(BOOL)animated { 
    [super setSelected:selected animated:animated]; 
    if (selected) { 
     [self.textView becomeFirstResponder]; 
    } 
} 

- (void)setStringValue:(NSString *)value { 
    self.textView.text = value; 
} 

- (NSString *)stringValue { 
    return self.textView.text; 
} 

- (void)textViewDidBeginEditing:(UITextView *)textView 
{ 
    // For keyboard scroll 
    UITableView *tableView = (UITableView *)self.superview; 
    AppSetupViewController *parent = (AppSetupViewController *)_delegate; 
    parent.activeCellIndexPath = [tableView indexPathForCell:self]; 
} 

- (void)textViewDidChange:(UITextView *)textView 
{ 
    if (textView.contentSize.height > contentRowHeight) { 

     contentRowHeight = textView.contentSize.height; 

     UITableView *tableView = (UITableView *)self.superview; 
     [tableView beginUpdates]; 
     [tableView endUpdates]; 

     [textView setFrame:CGRectMake(0, 0, 300.0, textView.contentSize.height)]; 
    } 
} 

- (void)textViewDidEndEditing:(UITextView *)textView 
{ 
    if (_delegate && [_delegate respondsToSelector:@selector(tableViewCell:didEndEditingWithLongString:)]) { 
     [_delegate tableViewCell:self didEndEditingWithLongString:self.stringValue]; 
    } 
    UITableView *tableView = (UITableView *)self.superview; 
    [tableView deselectRowAtIndexPath:[tableView indexPathForCell:self] animated:YES]; 
} 

- (void)layoutSubviews { 
    [super layoutSubviews]; 
    CGRect editFrame = CGRectInset(self.contentView.frame, 10, 10); 

    if (self.textLabel.text && [self.textLabel.text length] != 0) { 
     CGSize textSize = [self.textLabel sizeThatFits:CGSizeZero]; 
     editFrame.origin.x += textSize.width + 10; 
     editFrame.size.width -= textSize.width + 10; 
     self.textView.textAlignment = NSTextAlignmentRight; 
    } else { 
     self.textView.textAlignment = NSTextAlignmentLeft; 
    } 

    self.textView.frame = editFrame; 
} 

這是cellForRowAtIndexPath創建這樣的:

else if ([paramType isEqualToString:@"longString"]) { 
      MyIdentifier = @"AppActionLongString"; 

      LongStringInputTableViewCell *cell = (LongStringInputTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 
      cell.textLabel.text = [[[_selectedAction objectForKey:@"parameters"] objectAtIndex:indexPath.row] objectForKey:@"name"]; 
      cell.params = [[_selectedAction objectForKey:@"parameters"] objectAtIndex:indexPath.row]; 

      cell.textView.text = [results objectAtIndex:indexPath.row]; 

      return cell; 
     } 

高度只是傳遞迴變量在我ViewController是不好,因爲就像我說的那樣,表格中可能有幾個這樣的單元格。

謝謝

+0

從哪裏獲得TextView文本? – Rox

+0

這是用戶輸入。目前我在完成後使用委託方法將其發送回ViewController並將其存儲在Array中。當我調整大小時,我會在每次按鍵輸入後調用委託方法來檢查調整大小。 – Darren

回答

1

使用此方法來動態調整您的tableviewCell的大小。首先將用戶輸入存儲在NSMutable Array中,然後重新加載表。希望它能幫助你。

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ 

    NSString *msg =[self.messages objectAtIndex:indexPath.row]; 
    CGSize textSize = { 120, 10000.0 }; 
    CGSize size = [msg sizeWithFont:[UIFont systemFontOfSize:15] 
        constrainedToSize:textSize 
         lineBreakMode:UILineBreakModeWordWrap]; 


return size.height+20; 

}

+0

謝謝。我早些時候嘗試過這樣的事情。這裏的問題是,你已經將寬度設置爲120.我的寬度是動態的,因爲TextView首先用'UIViewAutoresizingFlexibleWidth'設置爲'CGRectZero',因此它填充了標題剩餘的空間。我無法獲得單元格的參考來獲取寬度。 – Darren

+0

你的身高應該是靈活的,但你可以修復你的寬度尺寸。它可能是320 – Rox

+0

單元格左側有標題標籤,右側有textView。 textView的寬度取決於標題標籤的寬度。 – Darren

-2

只是評論

if (cell == nil) 

希望,這將幫助你。

0

我需要一個動態表格視圖單元格的高度根據該單元格中顯示的文本的數量。我解決它以這樣的方式

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     if (!isLoading) 
     { 

      if ([self.conditionsDataArray count]>0) 
      { 
       Conditions *condition =[self.conditionsDataArray objectAtIndex:indexPath.row]; 

       int height; 

       UITextView *textview = [[UITextView alloc] initWithFrame:CGRectMake(0, 0, 236, 0)]; //you can set your frame according to your need 

       textview.text = condition.comment; 

       textview.autoresizingMask = UIViewAutoresizingFlexibleHeight; 

       [tableView addSubview:textview]; 

       textview.hidden = YES; 

       height = textview.contentSize.height; 

       NSLog(@"TEXT VIEW HEIGHT %f", textview.contentSize.height); 

       [textview removeFromSuperview]; 

       [textview release]; 

       return height; 
     } 

     return 55; //Default height, if data is in loading state 
} 

注意,文本查看已被添加爲子視圖,然後做隱藏,所以一定要添加爲子視圖,否則它的高度將不被考慮。

0

如果我可以在heightForRowAtIndexPath期間調用有問題的單元格,但會導致無限循環並崩潰,因爲在創建任何單元格之前調用此方法會很容易。其他解決方案?

你可以。我想你會試圖撥打cellForRowAtIndexPath,這會導致無限循環。但您應該直接通過調用dequeueReusableCellWithIdentifier來使單元脫隊。

查看TLIndexPathToolstable view delegate implementation。該heightForRowAtIndexPath方法是這樣的:

編輯最初忘了,包括實際會轉移到細胞的方法prototypeForCellIdentifier。)

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    id item = [self.dataModel itemAtIndexPath:indexPath]; 
    NSString *cellId = [self cellIdentifierAtIndexPath:indexPath]; 
    if (cellId) { 
     UITableViewCell *cell = [self prototypeForCellIdentifier:cellId]; 
     if ([cell conformsToProtocol:@protocol(TLDynamicSizeView)]) { 
      id<TLDynamicSizeView> v = (id<TLDynamicSizeView>)cell; 
      id data; 
      if ([item isKindOfClass:[TLIndexPathItem class]]) { 
       TLIndexPathItem *i = (TLIndexPathItem *)item; 
       data = i.data; 
      } else { 
       data = item; 
      } 
      CGSize computedSize = [v sizeWithData:data]; 
      return computedSize.height; 
     } else { 
      return cell.bounds.size.height; 
     } 
    } 

    return 44.0; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView prototypeForCellIdentifier:(NSString *)cellIdentifier 
{ 
    UITableViewCell *cell; 
    if (cellIdentifier) { 
     cell = [self.prototypeCells objectForKey:cellIdentifier]; 
     if (!cell) { 
      if (!self.prototypeCells) { 
       self.prototypeCells = [[NSMutableDictionary alloc] init]; 
      } 
      cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 
      //TODO this will fail if multiple tables are being used and they have 
      //overlapping identifiers. The key needs to be unique to the table 
      [self.prototypeCells setObject:cell forKey:cellIdentifier]; 
     } 
    } 
    return cell; 
} 

這使用的協議TLDynamicSizeView,任何細胞可以實現爲具有它的自動計算高度。這是一個工作example project。該協議的單元實現如下所示:

@implementation DynamicHeightCell 

- (void)awakeFromNib 
{ 
    [super awakeFromNib]; 
    self.originalSize = self.bounds.size; 
    self.originalLabelSize = self.label.bounds.size; 
} 

- (void)configureWithText:(NSString *)text 
{ 
    self.label.text = text; 
    [self.label sizeToFit]; 
} 

#pragma mark - TLDynamicSizeView 

- (CGSize)sizeWithData:(id)data 
{ 
    [self configureWithText:data]; 
    //the dynamic size is calculated by taking the original size and incrementing 
    //by the change in the label's size after configuring 
    CGSize labelSize = self.label.bounds.size; 
    CGSize size = self.originalSize; 
    size.width += labelSize.width - self.originalLabelSize.width; 
    size.height += labelSize.height - self.originalLabelSize.height; 
    return size; 
} 

@end 
相關問題