巢狀UITextView的UITableViewCell高度自適應

lmg4819發表於2018-05-28

前一陣子,遇到了這樣的需求,在網上花了一番力氣搜尋、總結,總算是完成了這個任務,現在系統性的總結一下,分享給大家,跟著流程走,我不保證你能理解整個過程,但可以保證你能實現這個需求。本文主要以程式碼為主,需要解釋的東西我會以註釋的形式展示。複製程式碼

1.使用AutoLayout為自定義cell新增約束

巢狀UITextView的UITableViewCell高度自適應

設定cell的過程需要注意一下幾個點:

  • height的約束必須是大於等於某個值
  • UITextView的Scrolling Enabled屬性要設定為NO
  • UITextView的delegate為TextViewTVCell

2.自定義cell檔案內容:

//.h檔案內容

#import <UIKit/UIKit.h>


@class TextViewTVCell;


@protocol TextViewTVCellDelegate <NSObject>


- (void)textViewTVCell:(TextViewTVCell *)cell didChangeText:(NSString *)text;


@end


@interface TextViewTVCell : UITableViewCell<UITextViewDelegate>
@property(nonatomic,assign) id<TextViewTVCellDelegate> delegate;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UITextView *contentTextView;


@end


//.m檔案內容

#import "TextViewTVCell.h"


@implementation TextViewTVCell


- (void)awakeFromNib {
    [super awakeFromNib];
    // Initialization code
    self.contentTextView.contentInset = UIEdgeInsetsMake(-5, 0, 5, 0);
}


#pragma mark -UITextViewDelegate
-(void)textViewDidChange:(UITextView *)textView
{
    if (self.delegate && [self.delegate respondsToSelector:@selector(textViewTVCell:didChangeText:)]) {
        [self.delegate textViewTVCell:self didChangeText:textView.text];
    }
    
    CGRect bounds = textView.bounds;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(bounds.size.width, CGFLOAT_MAX)];
    bounds.size = newSize;
    textView.bounds = bounds;
    
    UITableView *tableView = [self tableView];
    [tableView beginUpdates];
    [tableView endUpdates];
    
}
-(UITableView *)tableView
{
    UIView *tableView = self.superview;
    while (tableView && ![tableView isKindOfClass:[UITableView class]]) {
        tableView = tableView.superview;
    }
    return (UITableView *)tableView;
}
-(BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if ([text isEqualToString:@"\n"]) {
        [textView resignFirstResponder];
        return NO;
    }
    return YES;
}
@end
複製程式碼

3.ViewController檔案內容

//.h檔案無更改,.m檔案內容如下

#import "ViewController.h"
#import "TextViewTVCell.h"






@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,TextViewTVCellDelegate>
@property(nonatomic,strong) UITableView *tableView;
@property(nonatomic,copy) NSArray *dataList;
@property(nonatomic,strong) NSMutableArray *detailDataList;
@end




@implementation ViewController
static NSString *ID = @"TextViewCell";
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //[self performSelector:@selector(layoutUI)];
    self.dataList = @[@"hello",@"hello",@"hello",@"hello",@"hello",@"hello",@"hello",@"hello",@"hello",@"hello"];
    
    self.detailDataList =[ @[@"執行迴圈",@"執行迴圈模式是對輸入源和計時器的集合進行監視,並將通知一個執行迴圈觀察器集合",@"執行迴圈",@"執行迴圈",@"執行迴圈",@"執行迴圈",@"執行迴圈",@"執行迴圈",@"執行迴圈",@"執行迴圈"] mutableCopy];
    
    
    [self.view addSubview:self.tableView];
}


#pragma mark -UITableViewDelegate,UITableViewDataSource
-(UITableView *)tableView
{
    if (!_tableView) {
        _tableView = [[UITableView alloc]initWithFrame:self.view.bounds];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        _tableView.tableFooterView = [UIView new];
         _tableView.estimatedRowHeight = 80;//先估計一個高度
        _tableView.rowHeight = UITableViewAutomaticDimension;// 自適應單元格高度
        [_tableView registerNib:[UINib nibWithNibName:@"TextViewTVCell" bundle:nil] forCellReuseIdentifier:ID];
    }
    return _tableView;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.dataList.count;
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    TextViewTVCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[TextViewTVCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.delegate = self;
    }
    cell.nameLabel.text = self.dataList[indexPath.row];
    cell.contentTextView.text = self.detailDataList[indexPath.row];
    return cell;
}
#pragma mark -TextViewTVCellDelegate
-(void)textViewTVCell:(TextViewTVCell *)cell didChangeText:(NSString *)text
{
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
    self.detailDataList[indexPath.row] = text;
}


@end複製程式碼


相關文章