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
동안 크기를 유지하고 커서를 가시 영역 안에 유지하고 첫 번째 응답 보장 계속 유지
정적 테이블 뷰로 작업 중이거나 장치 수만있는 경우 UITextView
2 단계를 간단하게 만들 수 있습니다.
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
(이 예제에서)를 추가하십시오 .textViews
UITableViewController
다음 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;
}
문서가 말했듯이 그 속성은 다음과 같습니다.
텍스트 뷰의 크기를 할당 할 때 경계가 경계 사각형의 높이를 제어합니다. 상관 : 아니
규격을 그대로두면 frame
의 someTextView
크기를 조정 한 후에는 의 크기 textContainer
가 변경되지 않은 크기를 조정하기 전에 해당-도메인에만 텍스트를-디스플레이 할 수 있습니다.
그리고 scrollEnabled = NO
둘 이상이있는 경우 를 설정 textContainer
해야 텍스트가 리플 로우 될 수 textContainer
있습니다.
간단하고 빠른 도구 타이핑 을 목표로 한 또 다른 솔루션이 있습니다 .
설정 :
- 타입 타입 셀이있는 테이블.
- 각 셀에는
UITextView
다른 내용이 포함 된 동적 크기가 포함 됩니다. - 전용 타입 셀은과 연관되어
TableCell.h
있습니다. 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
여기서
minLines
UIViewViewAutomaticDimension을 사용하여 AutoLayout으로 높이를 최소화하기 위해 textView의 최소 높이를 접근 할 수 있습니다.moveRowAtIndexPath:indexPath:
동일한 indexPath를 사용하여 tableViewCell 높이 다시 계산 및 다시 레이아웃을 시작합니다.performWithoutAnimation:
(타이핑하는 동안 새 줄을 시작할 때 tableView 컨텐츠를 제거합니다).현재 셀이 예기치 않은 방식으로 자동 레이아웃에 의해 변경 미적분 될 수 있기 전에 -cell 때문에 -cell 중에 업데이트 보존
relativeFrameOriginY
하지 않는 것이 중요합니다 (contentOffsetY
! 아님)contentSize
. 긴 단어를 입력하는 동안 시스템 하이픈에 대한 점프를 제거합니다.속성을 설정합니다
estimatedRowHeight
. 다음은 작동하지 않습니다.self.tableView.estimatedRowHeight = UITableViewAutomaticDimension;
tableViewDelegate 메소드 만 사용하십시오.
================================================ = ========================
tableView 와 tableViewCell 클래스는 약한 바인딩 과 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
- UILabel을 UITextView 추천하십시오.
- 이 답변을 사용하십시오 : https://stackoverflow.com/a/36054679/6681462 만든 UILabel
- 그들에게 같은 제약과 글꼴을 부여
- 동일한 텍스트를 설정하십시오.
셀 높이는 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 = UITableViewAutomaticDimension
과 tableView.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
'IT' 카테고리의 다른 글
Overflow-x : 숨김으로 인해 모바일 브라우저에서 컨텐츠가 넘치지 언어로 작성되었습니다. (0) | 2020.07.12 |
---|---|
MySQL에서 다음 / 이전 기록을 얻는 방법? (0) | 2020.07.12 |
신속한 배열-색인이 존재하는지 확인 (0) | 2020.07.12 |
jQuery에서 마우스 휠 이벤트를 보시겠습니까? (0) | 2020.07.12 |
getMinutes () 0-9- 두 자리 숫자를 표시하는 방법? (0) | 2020.07.12 |