IT

iOS 7에서 UITextView 높이가있는 UITableViewCell?

lottoking 2020. 7. 12. 09:06
반응형

iOS 7에서 UITextView 높이가있는 UITableViewCell?


iOS 7에서 UITextView를 사용하여 UITableViewCell의 높이를 어떻게 계산할 수 있습니까?

모든 질문에 대한 많은 답변을 찾았지만 sizeWithFont:모든 솔루션에 참여하고 있으며 더 이상 사용되지 않습니다!

당신은 - (CGFloat)tableView:heightForRowAtIndexPath:어떻게 계산할 수 있습니까?


우선, 텍스트 방식에있어서 UITextView와 UILabel 사이에는 큰 차이가 있습니다. UITextView는 모든 레이아웃에 인셋이 있고 그 안의 텍스트 레이아웃도 있습니다.

따라서 sizeWithFont:UITextViews를 사용하는 나쁜 방법입니다.

대신에 UITextView자체에는 경계 상자 내부의 sizeThatFits:모든 내용을 표시하는 데 필요한 가장 작은 크기 UITextView있습니다.

다음은 iOS 7 및 이전 버전 모두에서 동일하게 작동하며 현재는 더 이상 사용하지 않는 메소드를 포함하지.


간단한 솔루션

- (CGFloat)textViewHeightForAttributedText: (NSAttributedString*)text andWidth: (CGFloat)width {
    UITextView *calculationView = [[UITextView alloc] init];
    [calculationView setAttributedText:text];
    CGSize size = [calculationView sizeThatFits:CGSizeMake(width, FLT_MAX)];
    return size.height;
}

이 함수 NSAttributedString는 원하는 너비를 가져와 CGFloat필요한 높이를 반환합니다.


자세한 솔루션

최근에 작업을 수행 한 결과, 공유 할 문제에 대한 솔루션도 공유 할 문제에 대해 생각했습니다. 누군가에게 도움이되기를 바랍니다.

훨씬 더 깊이 있고 다음을 다룰 것입니다.

  • 물론 : 포함 내용물 UITableViewCell의 전체 내용을-display하는 데 필요한 크기를 기준으로 높이를 설정하십시오.UITextView
  • 텍스트 변경에 응답하고 행의 높이 변경에 애니메이션을 적용합니다.
  • 편집 UITextView하는 UITableViewCell동안 크기를 유지하고 커서를 가시 영역 안에 유지하고 첫 번째 응답 보장 계속 유지

정적 테이블 뷰로 작업 중이거나 장치 수만있는 경우 UITextView2 단계를 간단하게 만들 수 있습니다.

1. 먼저 heightForRowAtIndexPath를 사용하십시오.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    // check here, if it is one of the cells, that needs to be resized
    // to the size of the contained UITextView
    if (  )             
        return [self textViewHeightForRowAtIndexPath:indexPath];
    else
    // return your normal height here:
            return 100.0;           
}

2. 필요한 높이를 계산하는 기능을 정의하십시오.

sub- 클래스에 인스턴스 변수로 NSMutableDictionary(이 예제에서)를 추가하십시오 .textViewsUITableViewController

다음 UITextViews과 같이 개인에 대한 참조를 저장 비용이 사전을 사용하십시오 .

(예, indexPaths는 사전에 유효한 키입니다 )

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Do you cell configuring ...

    [textViews setObject:cell.textView forKey:indexPath];
    [cell.textView setDelegate: self]; // Needed for step 3

    return cell;
}

이 함수는 이제 실제 높이를 계산합니다.

- (CGFloat)textViewHeightForRowAtIndexPath: (NSIndexPath*)indexPath {
    UITextView *calculationView = [textViews objectForKey: indexPath];
    CGFloat textViewWidth = calculationView.frame.size.width;
    if (!calculationView.attributedText) {
        // This will be needed on load, when the text view is not inited yet

        calculationView = [[UITextView alloc] init];
        calculationView.attributedText = // get the text from your datasource add attributes and insert here
        textViewWidth = 290.0; // Insert the width of your UITextViews or include calculations to set it accordingly
    }
    CGSize size = [calculationView sizeThatFits:CGSizeMake(textViewWidth, FLT_MAX)];
    return size.height;
}

3. 편집 중 크기 조정 활성화

다음 두 함수의 경우 대리자 UITextViews가 귀하의로 설정되어 있어야합니다 UITableViewController. 대리인으로 다른 것이 필요한 경우 관련 전화를 걸거나 적절한 NSNotificationCenter 후크를 사용하여 문제를 해결할 수 있습니다.

- (void)textViewDidChange:(UITextView *)textView {

    [self.tableView beginUpdates]; // This will cause an animated update of
    [self.tableView endUpdates];   // the height of your UITableViewCell

    // If the UITextView is not automatically resized (e.g. through autolayout 
    // constraints), resize it here

    [self scrollToCursorForTextView:textView]; // OPTIONAL: Follow cursor
}

4. 편집하는 동안 커서를 따라

- (void)textViewDidBeginEditing:(UITextView *)textView {
    [self scrollToCursorForTextView:textView];
}

을 구석으로 이는 UITableView은 내부 jQuery를과의 보이는 사각형이 아닌 경우, 커서의 위치로 스크롤 :

- (void)scrollToCursorForTextView: (UITextView*)textView {

    CGRect cursorRect = [textView caretRectForPosition:textView.selectedTextRange.start];

    cursorRect = [self.tableView convertRect:cursorRect fromView:textView];

    if (![self rectVisible:cursorRect]) {
        cursorRect.size.height += 8; // To add some space underneath the cursor
        [self.tableView scrollRectToVisible:cursorRect animated:YES];
    }
}

5. 삽입을 설정하여 보이는 rect를 조정하십시오.

편집하는 동안 UITableView키보드 일부 가 사용자의 일부를 덮을 수 있습니다. 테이블 뷰 삽입이 조정 scrollToCursorForTextView:되지 않은 경우 테이블 뷰의 맨 아래에 커서로 스크롤 할 수 없습니다.

- (void)keyboardWillShow:(NSNotification*)aNotification {
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, kbSize.height, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
}

- (void)keyboardWillHide:(NSNotification*)aNotification {
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.35];
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(self.tableView.contentInset.top, 0.0, 0.0, 0.0);
    self.tableView.contentInset = contentInsets;
    self.tableView.scrollIndicatorInsets = contentInsets;
    [UIView commitAnimations];
}

그리고 마지막 부분 :

뷰가로드 된 후 NSNotificationCenter다음을 통해 키보드 변경 알림에 가입하십시오 .

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

이 답변을 너무 만들어서 화 내지는. 이 질문에 모두 답할 필요는 없지만 다른 직접 관련된 문제가 도움이 될 사람들이해야한다고 생각합니다.


최신 정보 :

Dave Haupert가 지적했듯이 rectVisible함수 를 포함하는 것을 잊었습니다 .

- (BOOL)rectVisible: (CGRect)rect {
    CGRect visibleRect;
    visibleRect.origin = self.tableView.contentOffset;
    visibleRect.origin.y += self.tableView.contentInset.top;
    visibleRect.size = self.tableView.bounds.size;
    visibleRect.size.height -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;

    return CGRectContainsRect(visibleRect, rect);
}

또한 scrollToCursorForTextView:내 프로젝트의 TextField 중 하나에 대한 직접 참조 여전히 포함되어 있음을 알았습니다 . bodyTextView없는 찾을 수 문제가 있으면 업데이트 된 기능 현관 현관 버전을 확인하십시오.


boundWithRectWithSize 인 sizeWithFont를 대체하는 새로운 기능이 있습니다.

프로젝트에 다음 기능을 추가하여 iOS7의 새로운 기능과 iOS의 이전 기능을 7보다 낮은 기능을 사용합니다. 기본적으로 sizeWithFont와 구문이 맞춰집니다.

    -(CGSize)text:(NSString*)text sizeWithFont:(UIFont*)font constrainedToSize:(CGSize)size{
        if(IOS_NEWER_OR_EQUAL_TO_7){
            NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                              font, NSFontAttributeName,
                                              nil];

            CGRect frame = [text boundingRectWithSize:size
                                              options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                           attributes:attributesDictionary
                                              context:nil];

            return frame.size;
        }else{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
            return [text sizeWithFont:font constrainedToSize:size];
#pragma clang diagnostic pop
        }
    }

프로젝트의 prefix.pch 파일에서 IOS_NEWER_OR_EQUAL_TO_7을 다음과 같이 추가 할 수 있습니다.

#define IOS_NEWER_OR_EQUAL_TO_7 ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= 7.0 )

UITableViewAutomaticDimension을 사용하는 경우 정말 간단합니다 (iOS 8 전용) 솔루션이 있습니다. 제 경우에는 정적 테이블 뷰이지만 동적 준비에 적합합니다 ...

텍스트 뷰의 높이에 대한 구속력이 다음과 같은 방법을 구현했습니다.

// Outlets

@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *textViewHeight;


// Implementation

#pragma mark - Private Methods

- (void)updateTextViewHeight {
    self.textViewHeight.constant = self.textView.contentSize.height + self.textView.contentInset.top + self.textView.contentInset.bottom;
}

#pragma mark - View Controller Overrides

- (void)viewDidLoad {
    [super viewDidLoad];
    [self updateTextViewHeight];
}

#pragma mark - TableView Delegate & Datasource

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 80;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

#pragma mark - TextViewDelegate

- (void)textViewDidChange:(UITextView *)textView {
    [self.tableView beginUpdates];
    [self updateTextViewHeight];
    [self.tableView endUpdates];
}

그러나 텍스트 뷰는 스크롤 가능해야하며 자동 치수에 대해 작동하도록 구속 조건을 설정해야합니다.

  • 고정 된 높이 (프로그래밍 방식으로 표현 텍스트 뷰 높이 포함)를 사용하여 셀의 모든 뷰를 서로 관련하여 설정
  • 맨 위보기는 맨 위 간격을 맨 아래보기는 맨 위 간격을 슈퍼보기로 표시합니다.

가장 기본적인 셀 예는 다음과 가변적입니다.

  • 텍스트보기를 제외하고 셀에 다른보기가 없습니다.
  • 텍스트보기의 모든면 주위에 여백이없고 텍스트보기에 대해 사전 정의 된 높이 제한이 있습니다.

Tim Bodeit의 답변은 훌륭합니다. 텍스트 솔루션의 높이를 가져 오기 오기 오기 위해 Simple Solution 코드를 사용하고에 해당 높이를 사용했습니다 heightForRowAtIndexPath. 그러나 텍스트 뷰의 크기를 조정하기 위해 나머지 답변을 사용하지 않습니다. 대신, frame텍스트보기 를 변경하는 코드를 작성합니다 cellForRowAtIndexPath.

iOS 6 이하에서는 모든 것이 작동하지만 iOS 7에서는 frame텍스트보기의 크기가 실제로 조정 되어 있어도 텍스트보기가 완전히 표시 됩니다. (사용하지 않음 Auto Layout). 아이폰 OS 7 이유해야 우리 우리 있다는가 TextKit하고 텍스트의 위치에 의해 제어됩니다 NSTextContainer에서 UITextView. 그래서 제 경우 someTextView에는 iOS 7에서 작동하기 위해 라인을 추가합니다 .

    if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
        someTextView.textContainer.heightTracksTextView = YES;
    }

문서가 말했듯이 그 속성은 다음과 같습니다.

텍스트 뷰의 크기를 할당 할 때 경계가 경계 사각형의 높이를 제어합니다. 상관 : 아니

규격을 그대로두면 framesomeTextView크기를 조정 한 후에는 크기 textContainer가 변경되지 않은 크기를 조정하기 전에 해당-도메인에만 텍스트를-디스플레이 할 수 있습니다.

그리고 scrollEnabled = NO둘 이상이있는 경우 를 설정 textContainer해야 텍스트가 리플 로우 될 수 textContainer있습니다.


간단하고 빠른 도구 타이핑 을 목표로 한 또 다른 솔루션이 있습니다 .

설정 :

  1. 타입 타입 셀이있는 테이블.
  2. 각 셀에는 UITextView다른 내용이 포함 된 동적 크기가 포함 됩니다.
  3. 전용 타입 셀은과 연관되어 TableCell.h있습니다.
  4. UITableView와 (과) 연결되어 TableViewController.h있습니다.

해결책 :

(1) 추가 TableViewController.m:

 // This is the method that determines the height of each cell.  
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{
    // I am using a helper method here to get the text at a given cell.
    NSString *text = [self getTextAtIndex:indexPath];

    // Getting the height needed by the dynamic text view.
    CGSize size = [self frameForText:text sizeWithFont:nil constrainedToSize:CGSizeMake(300.f, CGFLOAT_MAX)];

    // Return the size of the current row.
    // 80 is the minimum height! Update accordingly - or else, cells are going to be too thin.
    return size.height + 80; 
}

// Think of this as some utility function that given text, calculates how much 
// space would be needed to fit that text.
- (CGSize)frameForText:(NSString *)text sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size
{
    NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                          font, NSFontAttributeName,
                                          nil];
    CGRect frame = [text boundingRectWithSize:size
                                      options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading)
                                   attributes:attributesDictionary
                                      context:nil];

    // This contains both height and width, but we really care about height.
    return frame.size;
}

// Think of this as a source for the text to be rendered in the text view. 
// I used a dictionary to map indexPath to some dynamically fetched text.
- (NSString *) getTextAtIndex: (NSIndexPath *) indexPath
{
    return @"This is stubbed text - update it to return the text of the text view.";
}

(2) 추가 TableCell.m:

// This method will be called when the cell is initialized from the storyboard
// prototype. 
- (void)awakeFromNib
{
    // Assuming TextView here is the text view in the cell. 
    TextView.scrollEnabled = YES;
}

설명 :

여기서 일어나는 일은 이것입니다. 각 텍스트 뷰는 수직 및 수평 제약 조건에 의해 테이블 ​​셀의 높이에 바인딩됩니다. 즉, 테이블 셀 높이가 증가하면 텍스트 뷰의 크기도 증가합니다. 수정 된 @manecosta 코드 버전을 사용하여 주어진 텍스트를 셀에 맞추기 위해 필요한 텍스트 뷰 높이를 계산했습니다. 따라서 X 개의 문자가있는 텍스트가 주어지면 텍스트보기의 필요한 높이와 일치 frameForText:하는 속성이있는 크기를 반환합니다 size.height.

이제 남아있는 것이 필요한 텍스트 뷰의 높이와 일치하도록 셀의 높이를 업데이트하는 것입니다. 그리고 이것은 달성 heightForRowAtIndexPath:됩니다. 에서 언급했듯이 주석 size.height전체-셀이 아닌 텍스트보기의 높이 이기 때문에 추가되어야합니다. 예제의 경우이 값은 80입니다.


자동 레이아웃을 사용하는 경우 한 가지 방법은 자동 레이아웃 엔진이 크기를 계산하도록하는 것입니다. 이것은 가장 좋은 방법입니다 (그리고 가장 편리합니다). 셀 레이아웃의 포장이 생성됩니다. 예를 들어 셀에 텍스트 뷰 / 필드가 두 개 이상 있습니다.

자동 레이아웃을 사용하여 테이블 뷰 셀 크기를 조정하는 완전한 샘플로 질문에 대답했습니다.

자동 레이아웃으로 모든 하위보기에 맞게 수퍼 뷰 크기를 조정하는 방법은 무엇입니까?


완벽한 부드러운 솔루션은 다음과 유연합니다.

먼저 textView가있는 셀 클래스가 필요합니다.

@protocol TextInputTableViewCellDelegate <NSObject>
@optional
- (void)textInputTableViewCellTextWillChange:(TextInputTableViewCell *)cell;
- (void)textInputTableViewCellTextDidChange:(TextInputTableViewCell *)cell;
@end

@interface TextInputTableViewCell : UITableViewCell
@property (nonatomic, weak) id<TextInputTableViewCellDelegate> delegate;
@property (nonatomic, readonly) UITextView *textView;
@property (nonatomic) NSInteger minLines;
@property (nonatomic) CGFloat lastRelativeFrameOriginY;
@end


#import "TextInputTableViewCell.h"

@interface TextInputTableViewCell () <UITextViewDelegate> {
    NSLayoutConstraint *_heightConstraint;
}
@property (nonatomic) UITextView *textView;
@end

@implementation TextInputTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;

        _textView = [UITextView new];
        _textView.translatesAutoresizingMaskIntoConstraints = NO;
        _textView.delegate = self;
        _textView.scrollEnabled = NO;
        _textView.font = CELL_REG_FONT;
        _textView.textContainer.lineFragmentPadding = 0.0;
        _textView.textContainerInset = UIEdgeInsetsZero;
        [self.contentView addSubview:_textView];

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[view]-|" options:nil metrics:nil views:@{@"view": _textView}]];
        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[view]-|" options:nil metrics:nil views:@{@"view": _textView}]];

        _heightConstraint = [NSLayoutConstraint constraintWithItem: _textView
                         attribute: NSLayoutAttributeHeight
                         relatedBy: NSLayoutRelationGreaterThanOrEqual
                         toItem: nil
                         attribute: NSLayoutAttributeNotAnAttribute
                         multiplier: 0.0
                         constant: (_textView.font.lineHeight + 15)];
        _heightConstraint.priority = UILayoutPriorityRequired - 1;
        [_textView addConstraint:_heightConstraint];
    }
    return self;
}

- (void)prepareForReuse {
    [super prepareForReuse];    
    self.minLines = 1;
}

- (void)setMinLines:(NSInteger)minLines {
    _heightConstraint.constant = minLines * _textView.font.lineHeight + 15;
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    if ([self.delegate respondsToSelector:@selector(textInputTableViewCellTextWillChange:)]) {
        [self.delegate textInputTableViewCellTextWillChange:self];
    }
    return YES;
}

- (void)textViewDidChange:(UITextView *)textView {
    if ([self.delegate respondsToSelector:@selector(textInputTableViewCellTextDidChange:)]) {
        [self.delegate textInputTableViewCellTextDidChange:self];
    }
}

다음으로 TableViewController에서 사용합니다.

@interface SomeTableViewController () <TextInputTableViewCellDelegate>
@end

@implementation SomeTableViewController

. . . . . . . . . . . . . . . . . . . .

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    TextInputTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: TextInputTableViewCellIdentifier forIndexPath:indexPath];
    cell.delegate = self;
    cell.minLines = 3;
    . . . . . . . . . .  
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

- (void)textInputTableViewCellWillChange:(TextInputTableViewCell *)cell {
    cell.lastRelativeFrameOriginY = cell.frame.origin.y - self.tableView.contentOffset.y;
}

- (void)textInputTableViewCellTextDidChange:(TextInputTableViewCell *)cell {
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

    [UIView performWithoutAnimation:^{
        [self.tableView moveRowAtIndexPath:indexPath toIndexPath:indexPath];
    }];

    CGFloat contentOffsetY = cell.frame.origin.y - cell.lastRelativeFrameOriginY;
    self.tableView.contentOffset = CGPointMake(self.tableView.contentOffset.x, contentOffsetY);

    CGRect caretRect = [cell.textView caretRectForPosition:cell.textView.selectedTextRange.start];
    caretRect = [self.tableView convertRect:caretRect fromView:cell.textView];

    CGRect visibleRect = self.tableView.bounds;
    visibleRect.origin.y += self.tableView.contentInset.top;
    visibleRect.size.height -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;
    BOOL res = CGRectContainsRect(visibleRect, caretRect);
    if (!res) {
        caretRect.size.height += 5;
        [self.tableView scrollRectToVisible:caretRect animated:NO];
    }
}
@end
  • 여기서 minLinesUIViewViewAutomaticDimension을 사용하여 AutoLayout으로 높이를 최소화하기 위해 textView의 최소 높이를 접근 할 수 있습니다.

  • moveRowAtIndexPath:indexPath: 동일한 indexPath를 사용하여 tableViewCell 높이 다시 계산 및 다시 레이아웃을 시작합니다.

  • performWithoutAnimation: (타이핑하는 동안 새 줄을 시작할 때 tableView 컨텐츠를 제거합니다).

  • 현재 셀이 예기치 않은 방식으로 자동 레이아웃에 의해 변경 미적분 될 수 있기 전에 -cell 때문에 -cell 중에 업데이트 보존 relativeFrameOriginY하지 않는 것이 중요합니다 ( contentOffsetY! 아님) contentSize. 긴 단어를 입력하는 동안 시스템 하이픈에 대한 점프를 제거합니다.

  • 속성을 설정합니다 estimatedRowHeight . 다음은 작동하지 않습니다.

    self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
    

    tableViewDelegate 메소드 만 사용하십시오.

================================================ = ========================

tableViewtableViewCell 클래스는 약한 바인딩 tableViewCell에서 있는 tableView의 지오메트리 업데이트신경 쓰지 TextInputTableViewCell위의 클래스 를 업그레이드 할 수 있습니다 .

@interface TextInputTableViewCell : UITableViewCell
@property (nonatomic, weak) id<TextInputTableViewCellDelegate> delegate;
@property (nonatomic, weak) UITableView *tableView;
@property (nonatomic, readonly) UITextView *textView;
@property (nonatomic) NSInteger minLines;
@end


#import "TextInputTableViewCell.h"

@interface TextInputTableViewCell () <UITextViewDelegate> {
    NSLayoutConstraint *_heightConstraint;
    CGFloat _lastRelativeFrameOriginY;
}
@property (nonatomic) UITextView *textView;
@end

@implementation TextInputTableViewCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        self.selectionStyle = UITableViewCellSelectionStyleNone;

        _textView = [UITextView new];
        _textView.translatesAutoresizingMaskIntoConstraints = NO;
        _textView.delegate = self;
        _textView.scrollEnabled = NO;
        _textView.font = CELL_REG_FONT;
        _textView.textContainer.lineFragmentPadding = 0.0;
        _textView.textContainerInset = UIEdgeInsetsZero;
        [self.contentView addSubview:_textView];

        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[view]-|" options:nil metrics:nil views:@{@"view": _textView}]];
        [self.contentView addConstraints: [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[view]-|" options:nil metrics:nil views:@{@"view": _textView}]];

        _heightConstraint = [NSLayoutConstraint constraintWithItem: _textView
                         attribute: NSLayoutAttributeHeight
                         relatedBy: NSLayoutRelationGreaterThanOrEqual
                         toItem: nil
                         attribute: NSLayoutAttributeNotAnAttribute
                         multiplier: 0.0
                         constant: (_textView.font.lineHeight + 15)];
        _heightConstraint.priority = UILayoutPriorityRequired - 1;
        [_textView addConstraint:_heightConstraint];
    }
    return self;
}

- (void)prepareForReuse {
    [super prepareForReuse];    
    self.minLines = 1;
    self.tableView = nil;
}

- (void)setMinLines:(NSInteger)minLines {
    _heightConstraint.constant = minLines * _textView.font.lineHeight + 15;
}

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {

    _lastRelativeFrameOriginY = self.frame.origin.y - self.tableView.contentOffset.y;
    return YES;
}

- (void)textViewDidChange:(UITextView *)textView {

    NSIndexPath *indexPath = [self.tableView indexPathForCell:self];
    if (indexPath == nil) return;

    [UIView performWithoutAnimation:^{
        [self.tableView moveRowAtIndexPath:indexPath toIndexPath:indexPath];
    }];

    CGFloat contentOffsetY = self.frame.origin.y - _lastRelativeFrameOriginY;
    self.tableView.contentOffset = CGPointMake(self.tableView.contentOffset.x, contentOffsetY);

    CGRect caretRect = [self.textView caretRectForPosition:self.textView.selectedTextRange.start];
    caretRect = [self.tableView convertRect:caretRect fromView:self.textView];

    CGRect visibleRect = self.tableView.bounds;
    visibleRect.origin.y += self.tableView.contentInset.top;
    visibleRect.size.height -= self.tableView.contentInset.top + self.tableView.contentInset.bottom;

    BOOL res = CGRectContainsRect(visibleRect, caretRect);
    if (!res) {
        caretRect.size.height += 5;
        [self.tableView scrollRectToVisible:caretRect animated:NO];
    }
}
@end

  1. UILabel을 UITextView 추천하십시오.
  2. 이 답변을 사용하십시오 : https://stackoverflow.com/a/36054679/6681462 만든 UILabel
  3. 그들에게 같은 제약과 글꼴을 부여
  4. 동일한 텍스트를 설정하십시오.

셀 높이는 UILabel의 내용으로 계산되는 모든 텍스트는 TextField로 표시됩니다.


UITextView *txtDescLandscape=[[UITextView alloc] initWithFrame:CGRectMake(2,20,310,2)];

    txtDescLandscape.editable =NO;
    txtDescLandscape.textAlignment =UITextAlignmentLeft;
    [txtDescLandscape setFont:[UIFont fontWithName:@"ArialMT" size:15]];
    txtDescLandscape.text =[objImage valueForKey:@"imgdescription"];
    txtDescLandscape.text =[txtDescLandscape.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    [txtDescLandscape sizeToFit];
    [headerView addSubview:txtDescLandscape];

    CGRect txtViewlandscpframe = txtDescLandscape.frame;
    txtViewlandscpframe.size.height = txtDescLandscape.contentSize.height;
    txtDescLandscape.frame = txtViewlandscpframe;

이 방법으로 텍스트보기의 높이를 세고 그 높이에 따라 테이블 뷰 셀의 크기를 조정하여 전체 텍스트를 표시 할 수 있습니다.


스위프트 버전

func textViewHeightForAttributedText(text: NSAttributedString, andWidth width: CGFloat) -> CGFloat {
    let calculationView = UITextView()
    calculationView.attributedText = text
    let size = calculationView.sizeThatFits(CGSize(width: width, height: CGFloat.max))
    return size.height
}

UITableViewCell내부 높이의 높이를 기준으로의 높이 를 자동으로 조정하려는 경우 UITextView. 내 답변보기 : https : //.com/a/45890087/1245231

이 솔루션은 매우 간단하고 7 개의 존재 여부를 확인하는 것이 아이폰 OS 작동합니다 Scrolling Enabled옵션이 전원 오프 에 대한 UITextView내에서 UITableViewCell스토리 보드에 있습니다.

그런 다음있는 UITableViewController의 viewDidLoad에 ()의 설정 tableView.rowHeight = UITableViewAutomaticDimensiontableView.estimatedRowHeight > 0같은를 :

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 44.0
}

그게 다야. UITableViewCell의 높이는 내부 UITextView높이를 기준으로 자동 조정 합니다.


iOS 8 이상에서는 사용할 수 있습니다.

your_tablview.estimatedrowheight= minheight 너는 원해

your_tableview.rowheight=UItableviewautomaticDimension

참고 URL : https://stackoverflow.com/questions/18368567/uitableviewcell-with-uitextview-height-in-ios-7

반응형