首页 文章

增加uitableviewcell高度同时增加内部UITextView

提问于
浏览
13

我根据要显示的内容类型创建了 UITableView ,其中包含不同类型的 UITableViewCell . 其中一个是 UITableViewCell ,内部以这种方式以编程方式创建 UITextView

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  if([current_field.tipo_campo isEqualToString:@"text_area"])
  { 
    NSString *string = current_field.valore;
    CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];
    CGFloat height = ([string isEqualToString:@""]) ? 30.0f : stringSize.height+10;
    UITextView *textView=[[UITextView alloc] initWithFrame:CGRectMake(5, 5, 290, height)];
    textView.font = [UIFont systemFontOfSize:15.0];
    textView.text = string;
    textView.autoresizingMask =  UIViewAutoresizingFlexibleWidth;
    textView.textColor=[UIColor blackColor];
    textView.delegate = self;
    textView.tag = indexPath.section;
    [cell.contentView addSubview:textView];
    [textView release];   
    return cell;
  }
  ...
}

由于文本视图是可编辑的,因此包含它的单元格应更改其高度以正确拟合文本视图大小 . 最初我通过调整方法 textViewDidChange 中的 UITextView 来实现这一点:这样:

- (void)textViewDidChange:(UITextView *)textView
{
  NSInteger index = textView.tag;
  Field* field = (Field*)[[self sortFields] objectAtIndex:index];
  field.valore = textView.text;
  [self.tableView beginUpdates];
  CGRect frame = textView.frame;
  frame.size.height = textView.contentSize.height;
  textView.frame = frame;
  newHeight = textView.contentSize.height;
  [self.tableView endUpdates];
}

我将文本视图的新高度保存在变量中,然后在调用 tableView:heightForRowAtIndexPath :方法时,我以这种方式调整单元格的大小:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  ...
  if ([current_field.tipo_campo isEqualToString:@"text_area"])
  {
      return newHeight +10.0f;
  }
  else
    return 44.0f;
 ...
}

通过这种方式,两者都被调整大小但不是同步完成,即首先调整 TextView 的大小,然后调整大小的高度,因此用户看到文本视图大于单元格 . 我该如何解决这种不良行为?

8 回答

  • 1

    我已经为您的问题创建了一个演示,希望对您有所帮助 .

    我对解决方案的想法是使用 AutoResizingMaskUITextView .

    我的.h文件

    #import <UIKit/UIKit.h>
    
    @interface ViewController : UIViewController<UITabBarDelegate, UITableViewDataSource, UITextViewDelegate>{
        IBOutlet UITableView *tlbView;
        float height;
    }
    
    @end
    

    我的.m文件(仅包含必需的方法)

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        // Do any additional setup after loading the view, typically from a nib.
        height = 44.0;
    }
    
    - (void)textViewDidChange:(UITextView *)textView{
        [tlbView beginUpdates];
        height = textView.contentSize.height;
        [tlbView endUpdates];
    }
    
    #pragma mark - TableView datasource & delegates
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
        return 1;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
        if (indexPath.row==0) {
            if (height>44.0) {
                return height + 4.0;
            }
        }
        return 44.0;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"CellIdentifier"];
    
        UITextView *txtView = [[UITextView alloc] initWithFrame:CGRectMake(0.0, 2.0, 320.0, 40.0)];
        [txtView setDelegate:self];
        [txtView setAutoresizingMask:UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight]; // It will automatically resize TextView as cell resizes.
        txtView.backgroundColor = [UIColor yellowColor]; // Just because it is my favourite
        [cell.contentView addSubview:txtView];
    
        return cell;
    }
    

    希望它会帮助你 .

  • 4

    要调整单元格的大小,您可以使用与此类似的代码

    - (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
        NSString *newText = [textView.text stringByReplacingCharactersInRange:range withString:text];
        CGSize size = // calculate size of new text
    CGRect frame = textView.frame;
    frame.size.height = textView.contentSize.height;
    textView.frame = frame;
    
        if ((NSInteger)size.height != (NSInteger)[self tableView:nil heightForRowAtIndexPath:nil]) {
    
            // if new size is different to old size resize cells. 
    
    
            [self.tableView beginUpdates];
            [self.tableView endUpdates];
        }
        return YES;
    }
    
  • 19

    使用动画设置TextView框架..so它与单元格的扩展高度动画同步

  • 1

    看看这个:UIView Contentmode - 玩以下值:

    cell.contentMode = //...//
    
  • 1
    - (void)textViewDidChange:(UITextView *)textView
    {
        UITableViewCell *cell = (UITableViewCell*)textView.superview.superview;
    
        if (cell.frame.size.height < textView.contentSize.height) {
            [self.tableView beginUpdates];
            CGRect frame = textView.frame;
            frame.size.height = textView.contentSize.height;
            textView.frame = frame;
            CGRect cellFrame = cell.frame;
            cellFrame.size.height = textView.frame.size.height;
            cell.frame = cellFrame;
            [self.tableView endUpdates];
        }
    
    }
    
  • 1

    Siba Prasad Hota的代码可能会做到这一点(你需要从单元级别引用表视图),但我有另一种更长的方法 . 我总是这样做,因为我喜欢将所有东西分开(MVC模式) . 如果我是你,我会这样做(来自头部的代码):

    Cell parent protocol:

    @protocol CellParent <NSObject>
    @required
    @property (nonatomic, strong) UITableView *tableView;
    @end
    

    Cell model:

    @interface CellModel
    @property (nonatomic, assign) BOOL hasTextView;
    @property (nonatomic, strong) NSString *textViewContent;
    -(float)getCurrentHeightForCell;//implement calculating current height of cell. probably     2 * SOME_MARGIN + height of temporary textView with textViewContent variable
    

    Cell

    @interface MyCell
    @property (nonatomic, strong) CellModel *dataModel;
    @property (nonatomic, weak) id<CellParent> parent;
    @property (nonatomic, strong) UITextView *textView;
    - (id)initWithStyle:(UITableViewCellStyle)style andModel:(CellModel*) model;
    

    使用这样的实现:

    (id)initWithStyle:(UITableViewCellStyle)style andModel:(CellModel*) model
    {
        self = [super initWithStyle:style reuseIdentifier:@"MyCell"];
        if (self) 
        {
            [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
            self.dataModel = model;
        }
        return self;
    }
    
    
    -(void) setDataModel:(CellModel *)dataModel
    {
        _dataModel = dataModel;
        if(_dataModel.hasTextView)
        {
            //show text view
        }
        else
        {
            //hide text view
        }
        //do other cell modifications
    }
    
    -(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text 
    {
        self.dataModel.textViewContent = textView.text;
        [self.parent.tableView beginUpdates];
        [self.parent.tableView endUpdates];
        return YES;
    }
    

    Controller with table view

    -(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {  
        MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyCell"];
        if (cell == nil) 
        {
            cell = [[MyCell alloc] initWithStyle:UITableViewCellStyleDefault andModel:          [self.cellsModels objectAtIndex:indexPath.row]];
        }
        cell.dataModel = [self.cellsModels objectAtIndex:indexPath.row];
        cell.parent = self;
        return cell;
    }
    
    -(CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath     *)indexPath
    {
        return [((CellModel*)[self.tableContentArray objectAtIndex:indexPath.row]) getCurrentHeightForCell];
    }
    
  • 1

    您应该在加载单元格之前计算单元格的newHeight . 而不是在textViewDidChange中计算newHeight,在heightForRowAtIndexPath中计算它并返回相同的

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
      if ([current_field.tipo_campo isEqualToString:@"text_area"])
      {
          NSString *string = current_field.valore;
          CGSize stringSize = [string sizeWithFont:[UIFont boldSystemFontOfSize:15] constrainedToSize:CGSizeMake(320, 9999) lineBreakMode:UILineBreakModeWordWrap];
          CGFloat height = ([string isEqualToString:@""]) ? 30.0f : stringSize.height+10;
    
          return height + 10.0f;
      }
      else
      {
          return 44.0f;
      }
    }
    
  • 2

    我不打算用细胞高度使用方法

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

    而是使您的视图文本字段委托并以下面显示的方式处理以下事件:

    - (void) textFieldDidResize:(id)sender
    {
              [self.tableView beginUpdates];
              [self.tableView endUpdates];
    }
    

    还要确保您执行了以下操作:

    yourInputField.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    

    然后,您需要的唯一一件事就是调整文本字段的大小 . tableview中的单元格将采用内部文本字段的大小 . 只需将其作为子视图添加到cell.contentView即可 .

相关问题