Làm cách nào để tôi định cỡ UITextView cho nội dung của nó?


521

Có cách nào tốt để điều chỉnh kích thước của a UITextViewđể phù hợp với nội dung của nó không? Ví dụ, tôi có một UITextViewdòng chứa một dòng văn bản:

"Hello world"

Sau đó tôi thêm một dòng văn bản khác:

"Goodbye world"

Có một cách hay trong Cốc Cốc cảm ứng để có được recttất cả các dòng trong chế độ xem văn bản để tôi có thể điều chỉnh chế độ xem chính cho phù hợp?

Một ví dụ khác, hãy xem trường ghi chú cho các sự kiện trong ứng dụng Lịch - lưu ý cách ô (và ô UITextViewchứa) mở rộng để giữ tất cả các dòng văn bản trong chuỗi ghi chú.


vui lòng xem xét cập nhật câu trả lời chính xác, vì câu trả lời được chấp nhận dẫn đến các tính toán không cần thiết, bây giờ có thuộc tính contentSize cho vấn đề này.
Juan Boero

Câu trả lời:


610

Điều này hoạt động cho cả iOS 6.1 và iOS 7:

- (void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    textView.frame = newFrame;
}

Hoặc trong Swift (Hoạt động với Swift 4.1 trong iOS 11)

let fixedWidth = textView.frame.size.width
let newSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat.greatestFiniteMagnitude))
textView.frame.size = CGSize(width: max(newSize.width, fixedWidth), height: newSize.height)

Nếu bạn muốn hỗ trợ cho iOS 6.1 thì bạn cũng nên:

textview.scrollEnabled = NO;

1
Đã thử nghiệm trên iOS 7 để thay đổi kích thước UITextView thành UITableViewCell. Hoạt động thực sự tuyệt vời. Đây là câu trả lời duy nhất cuối cùng đã làm việc cho tôi. Cảm ơn!
Alex

37
Tôi cần textview.scrollEnabled = NO;để ngăn văn bản bị cắt ngay cả trong iOS 7.
Brian

19
Tôi khuyên bạn nên sử dụng CGFLOAT_MAXmacro thay vì MAXFLOAT. Đúng trên cả hai nền tảng 32/64 bit.
Eonil

3
Người phải đối mặt với ít biến động trước khi nhập vào dòng tiếp theo, hãy thêm `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa

4
Tại sao có hai lệnh gọi riêng biệt tới sizeThatFits (...) trong phiên bản Swift? Dòng đầu tiên để làm gì?
nekonari

576

Điều này không còn hoạt động trên iOS 7 trở lên

Thực sự có một cách rất dễ dàng để thay đổi kích thước UITextViewchiều cao chính xác của nội dung. Nó có thể được thực hiện bằng cách sử dụng UITextView contentSize.

CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

Một điều cần lưu ý là đúng contentSizelà chỉ có sẵn sau khi các UITextViewđã được thêm vào vùng đang xem với addSubview. Trước đó, nó bằngframe.size

Điều này sẽ không hoạt động nếu bố trí tự động được BẬT. Với bố cục tự động, cách tiếp cận chung là sử dụng sizeThatFitsphương thức và cập nhật constantgiá trị theo giới hạn chiều cao.

CGSize sizeThatShouldFitTheContent = [_textView sizeThatFits:_textView.frame.size];
heightConstraint.constant = sizeThatShouldFitTheContent.height;

heightConstraint là một ràng buộc bố cục mà bạn thường thiết lập thông qua IBOutlet bằng cách liên kết thuộc tính với ràng buộc chiều cao được tạo trong bảng phân cảnh.


Chỉ để thêm vào câu trả lời tuyệt vời này, 2014, nếu bạn:

[self.textView sizeToFit];

chỉ có một sự khác biệt trong hành vi với iPhone6 ​​+ :

nhập mô tả hình ảnh ở đây

Chỉ với 6+ (không phải 5s hoặc 6), nó sẽ thêm "một dòng trống nữa" vào UITextView. "Giải pháp RL" khắc phục điều này một cách hoàn hảo:

CGRect _f = self.mainPostText.frame;
_f.size.height = self.mainPostText.contentSize.height;
self.mainPostText.frame = _f;

Nó khắc phục vấn đề "dòng phụ" trên 6+.


2
Bạn đã cứu ngày của tôi. Tôi đã vật lộn với phần mở rộng chức năng lớp tự học mà quên mất điều này. Cảm ơn bạn.
Lukasz

4
Aha! Tôi đã thiết lập chiều cao của chế độ xem văn bản và sau đó điều chỉnh chiều cao của chế độ xem chứa. Rõ ràng khi tôi đã làm điều đó chiều cao xem văn bản đã được điều chỉnh. Đặt chiều cao của khung nhìn chứa trước tiên sẽ khiến mọi thứ hoạt động như mong đợi (hoặc, tốt hơn, hy vọng).
Licks nóng

11
Sử dụng [_textView sizeToFit] làm mới thuộc tính contentSize, loại bỏ yêu cầu thêm nó vào scrollView trước.
Rodrigo

1
Nếu sử dụng tính năng tự động thanh toán, hãy gọi layoutIfNeededcho giám sát. Sau đó, bạn có thể lấy chiều cao từ contentSize.
phatmann

4
Đó là về việc thay đổi kích thước của container bên ngoài. Hành vi đó đã thay đổi trong iOS 7. Tôi hiển thị trong câu hỏi được liên kết, nơi thêm sizeToFit và layout IfNeeded.
Henrik Erlandsson

93

Để tạo kích thước linh hoạt UITextViewbên trong a UITableViewCell, tôi đã tìm thấy sự kết hợp sau hoạt động trong Xcode 6 với SDK iOS 8:

  • Thêm a UITextViewvào a UITableViewCellvà giới hạn nó sang hai bên
  • Đặt UITextView's scrollEnabledtài sản để NO. Khi bật tính năng cuộn, khung của UITextViewđộc lập với kích thước nội dung của nó, nhưng với việc cuộn bị vô hiệu hóa, có một mối quan hệ giữa hai.
  • Nếu bảng của bạn đang sử dụng chiều cao hàng mặc định ban đầu là 44 thì nó sẽ tự động tính chiều cao của hàng, nhưng nếu bạn thay đổi chiều cao hàng mặc định thành một thứ khác, bạn có thể cần phải tự động bật tính năng tự động tính chiều cao của hàng trong viewDidLoad:

    tableView.estimatedRowHeight = 150;
    tableView.rowHeight = UITableViewAutomaticDimension;

Đối với kích thước chỉ đọc động UITextView, đó là nó. Nếu bạn cho phép người dùng chỉnh sửa văn bản trong bạn UITextView, bạn cũng cần phải:

  • Thực hiện textViewDidChange:phương thức của UITextViewDelegategiao thức và yêu tableViewcầu tự sơn lại mỗi khi văn bản được chỉnh sửa:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • Và đừng quên đặt UITextViewđại biểu ở đâu đó, trong Storyboardhoặc trongtableView:cellForRowAtIndexPath:


Câu trả lời tốt nhất cho tôi. Hoạt động hoàn hảo và UITableViewAutomaticDimension đã được thêm vào iOS 5 để nó tương thích ngược.
smmelzer

4
Không làm việc cho tôi. Phương thức textViewDidChange khiến cho chế độ xem bảng của tôi bị trả lại mỗi khi tôi nhập một ký tự. Điều tôi đề nghị là thay vì sử dụng phương thức đó, trong phương thức tableView: cellForRowAtIndexPath, cho hàng có chế độ xem văn bản trên đó, nếu bạn ở chế độ chỉ đọc được đặt .scrollEnables thành NO và nếu bạn đang ở chế độ xem chỉnh sửa cuộn được bật thành CÓ. Cách này khi chỉ hiển thị, nó sẽ luôn hiển thị toàn văn và khi chỉnh sửa, nó sẽ bắt đầu với toàn văn và khi bạn thêm văn bản khác sẽ giữ nguyên kích thước với văn bản trước đó cuộn từ trên xuống
SimonTheDiver

3
hơn nữa tôi đã thêm một> = ràng buộc về chiều cao cho textview vì một trường văn bản trống không có chiều cao và không thể gõ vào để bắt đầu chỉnh sửa.
SimonTheDiver

Giải pháp tuyệt vời. Đối với tôi, điều đó tableView.rowHeight = UITableViewAutomaticDimensionlà không cần thiết.
Christopher Pickslay

Cảm ơn bạn một lần nữa Brett Donald! Tôi quên cách làm điều này và tìm thấy câu trả lời của bạn một lần nữa sau hơn 1 năm.
Eric Conner

76

Giải pháp làm việc rất dễ dàng bằng cách sử dụng mã và bảng phân cảnh.

Theo mã

textView.scrollEnabled = false

Theo bảng phân cảnh

Bỏ chọn Kích hoạt cuộn

nhập mô tả hình ảnh ở đây

Không cần phải làm gì ngoài việc này.


5
Câu trả lời này là chính xác. Trong StoryBoard, bạn có TextView AutoSize giống như một UILabel. Tất cả những gì chúng ta cần làm là đặt scrollEnables = false.
pnavk

4
Về cơ bản, điều này là chính xác: nếu bạn đang sử dụng các ràng buộc Autolayout và tắt cuộn, toàn bộ hoạt động.
Dan Rosenstark

2
Cảm ơn rất nhiều. Thật đơn giản, chỉ cần vô hiệu hóa cuộn trong bảng phân cảnh hoặc mã, nó sẽ giống như UILabel với các dòng 0.
samir105

@Mansuu .... Đây không phải là một giải pháp được đảm bảo, vì có những điều bạn có thể làm để ghi đè kích thước nội dung bên trong và nếu bạn thay đổi văn bản sau khi chế độ xem được đưa ra, nó sẽ không cập nhật trừ khi bạn đặt lên, quá Nhưng, những điều đó vẫn đúng khi đặt numberOfLines = 0 trên trường văn bản. Nếu điều này không hiệu quả, bạn có thể có các ràng buộc khác sẽ ngầm định đặt chiều cao.
Jake T.

2
@iOS nếu bạn đang thêm ràng buộc về chiều cao thì hãy ưu tiên các ràng buộc thấp hơn nếu không nó sẽ không hoạt động.
Alok

61

Swift:

textView.sizeToFit()

14
Ngoài ra, tôi thấy rằng tôi cần phải bật tính năng cuộn thành false để điều này hoạt động. textView.scrollEnabled = false
tmarkiewicz

1
Bạn nên nhớ gọi textView.layout IfNeeded () sau textView.sizeToFit ()
Daniel Kuta

5
@tmarkiewicz Nó hoạt động khi văn bản vừa với màn hình của thiết bị nhưng sẽ gặp vấn đề khi văn bản của bạn lớn hơn không gian trên màn hình. Bạn sẽ không thể cuộn nó để xem phần còn lại của văn bản.
Francisco Romero

Đây là câu trả lời!!! Không cần giải pháp phức tạp hơn !!! @FranciscoRomero Tại sao không đặt textview trong một ô của bảng hoặc ô xem colleciton thì bạn luôn có thể cuộn bảng hoặc xem colleciton ....
Ben Smith

23

Theo kinh nghiệm (có giới hạn) của tôi,

- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode

không tôn trọng các ký tự dòng mới, vì vậy bạn có thể kết thúc với thời gian ngắn hơn rất nhiều CGSizeso với yêu cầu thực sự.

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

dường như không tôn trọng các dòng mới.

Ngoài ra, văn bản không thực sự được hiển thị ở đầu UITextView . Trong mã của tôi, tôi đặt chiều cao mới của UITextView24 pixel lớn hơn chiều cao được trả về bởi các sizeOfFontphương thức.


3
Điều đó có kích thước như thể nó sẽ vẽ văn bản trên một UILabel. Nếu bạn đặt kích thước đó thành khung của uitextview thì bạn vẫn sẽ có một số cuộn cần thiết trong đó.
Kevlar

22

Trong iOS6, bạn có thể kiểm tra thuộc contentSizetính của UITextView ngay sau khi bạn đặt văn bản. Trong iOS7, điều này sẽ không còn hoạt động. Nếu bạn muốn khôi phục hành vi này cho iOS7, hãy đặt đoạn mã sau vào một lớp con của UITextView.

- (void)setText:(NSString *)text
{
    [super setText:text];

    if (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1) {
        CGRect rect = [self.textContainer.layoutManager usedRectForTextContainer:self.textContainer];
        UIEdgeInsets inset = self.textContainerInset;
        self.contentSize = UIEdgeInsetsInsetRect(rect, inset).size;
    }
}

2
Tôi có thể đọc thêm về điều này ở đâu? Tôi hoàn toàn lạc lõng với hành vi dường như mới trong iOS 7 liên quan đến vấn đề này.
Stian Høiland

Ý nghĩa của kích thước CGSize là gì?
Tchelow

Tôi loại bỏ kích thước, nó không phải là ở đó.
phatmann

18

Tôi sẽ đăng giải pháp đúng ở cuối trang trong trường hợp ai đó đủ can đảm (hoặc đủ tuyệt vọng) để đọc đến thời điểm này.

Đây là repo gitHub cho những người không muốn đọc tất cả văn bản đó: resizableTextView

Điều này hoạt động với iOs7 (và tôi tin rằng nó sẽ hoạt động với iOs8) và với tính năng tự động thanh toán. Bạn không cần số ma thuật, vô hiệu hóa bố cục và những thứ như thế. Giải pháp ngắn gọn và thanh lịch.

Tôi nghĩ rằng, tất cả các mã liên quan đến ràng buộc nên đi đến updateConstraintsphương thức. Vì vậy, hãy làm cho riêng mình ResizableTextView.

Vấn đề đầu tiên chúng tôi gặp ở đây là không biết kích thước nội dung thực trước viewDidLoadphương thức. Chúng tôi có thể đi đường dài và lỗi và tính toán dựa trên kích thước phông chữ, ngắt dòng, v.v. Nhưng chúng tôi cần giải pháp mạnh mẽ, vì vậy chúng tôi sẽ làm:

CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

Vì vậy, bây giờ chúng tôi biết nội dung thực sự Kích thước bất kể chúng tôi đang ở đâu: trước hoặc sau viewDidLoad. Bây giờ thêm ràng buộc chiều cao trên textView (thông qua bảng phân cảnh hoặc mã, bất kể như thế nào). Chúng tôi sẽ điều chỉnh giá trị đó với contentSize.height:

[self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
    if (constraint.firstAttribute == NSLayoutAttributeHeight) {
        constraint.constant = contentSize.height;
        *stop = YES;
    }
}];

Điều cuối cùng cần làm là nói với siêu lớp updateConstraints.

[super updateConstraints];

Bây giờ lớp chúng tôi trông như:

ResizableTextView.m

- (void) updateConstraints {
    CGSize contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

    [self.constraints enumerateObjectsUsingBlock:^(NSLayoutConstraint *constraint, NSUInteger idx, BOOL *stop) {
        if (constraint.firstAttribute == NSLayoutAttributeHeight) {
            constraint.constant = contentSize.height;
            *stop = YES;
        }
    }];

    [super updateConstraints];
}

Đẹp và sạch sẽ đúng không? Và bạn không phải đối phó với mã đó trong bộ điều khiển của bạn !

Nhưng chờ đã! Y KHÔNG CÓ ĐỘNG VẬT!

Bạn có thể dễ dàng tạo hiệu ứng thay đổi để làm cho textViewkéo dài trơn tru. Đây là một ví dụ:

    [self.view layoutIfNeeded];
    // do your own text change here.
    self.infoTextView.text = [NSString stringWithFormat:@"%@, %@", self.infoTextView.text, self.infoTextView.text];
    [self.infoTextView setNeedsUpdateConstraints];
    [self.infoTextView updateConstraintsIfNeeded];
    [UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionLayoutSubviews animations:^{
        [self.view layoutIfNeeded];
    } completion:nil];

4
Sử dụng CGFLOAT_MAX, không FLT_MAX.
cướp mayoff

Tôi ước tôi có thể cho bạn nhiều hơn một phiếu bầu cho giải pháp tuyệt vời này !!
Xe tay ga

13

Bạn đã thử [textView sizeThatFits:textView.bounds]chưa

Chỉnh sửa: sizeThatFits trả về kích thước nhưng không thực sự thay đổi kích thước thành phần. Tôi không chắc đó là những gì bạn muốn, hoặc nếu [textView sizeToFit]nhiều hơn những gì bạn đang tìm kiếm. Trong cả hai trường hợp, tôi không biết liệu nó có hoàn toàn phù hợp với nội dung như bạn muốn không, nhưng đó là điều đầu tiên để thử.


2
sizetofit tiết kiệm trong ngày
michaelsnowden

9

Một phương pháp khác là tìm kích thước mà một chuỗi cụ thể sẽ sử dụng NSStringphương thức:

-(CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size

Điều này trả về kích thước của hình chữ nhật phù hợp với chuỗi đã cho với phông chữ đã cho. Vượt qua một kích thước với chiều rộng mong muốn và chiều cao tối đa, và sau đó bạn có thể nhìn vào chiều cao được trả về để phù hợp với văn bản. Có một phiên bản cho phép bạn chỉ định chế độ ngắt dòng.

Sau đó, bạn có thể sử dụng kích thước được trả về để thay đổi kích thước của chế độ xem cho phù hợp.


8

Nếu bạn không có UITextViewtiện dụng (ví dụ: bạn đang định cỡ các ô xem bảng), bạn sẽ phải tính toán kích thước bằng cách đo chuỗi, sau đó chiếm 8 pt phần đệm ở mỗi bên của a UITextView. Ví dụ: nếu bạn biết chiều rộng mong muốn của chế độ xem văn bản của mình và muốn tìm ra chiều cao tương ứng:

NSString * string = ...;
CGFloat textViewWidth = ...;
UIFont * font = ...;

CGSize size = CGSizeMake(textViewWidth - 8 - 8, 100000);
size.height = [string sizeWithFont:font constrainedToSize:size].height + 8 + 8;

Ở đây, mỗi số 8 chiếm một trong bốn cạnh được đệm và 100000 chỉ đóng vai trò là kích thước tối đa rất lớn.

Trong thực tế, bạn có thể muốn thêm một font.leadingchiều cao; điều này thêm một dòng trống bên dưới văn bản của bạn, có thể trông tốt hơn nếu có các điều khiển trực quan nặng ngay bên dưới chế độ xem văn bản.


kết quả hoàn hảo trong iOS 8.1
Logic

Đệm là chìa khóa cho tôi
thibaut noah

8

Chúng tôi có thể làm điều đó bằng các ràng buộc.

  1. Đặt các ràng buộc về Chiều cao cho UITextView. nhập mô tả hình ảnh ở đây

2. Tạo IBOutlet cho hạn chế chiều cao đó.

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *txtheightconstraints;

3. đừng quên thiết lập đại biểu cho chế độ xem văn bản của bạn.

4.

-(void)textViewDidChange:(UITextView *)textView
{
    CGFloat fixedWidth = textView.frame.size.width;
    CGSize newSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)];
    CGRect newFrame = textView.frame;
    newFrame.size = CGSizeMake(fmaxf(newSize.width, fixedWidth), newSize.height);
    NSLog(@"this is updating height%@",NSStringFromCGSize(newFrame.size));
    [UIView animateWithDuration:0.2 animations:^{
                  _txtheightconstraints.constant=newFrame.size.height;
    }];

}

sau đó cập nhật các ràng buộc của bạn như thế này :)


đó là một biệt danh FANTASTIC!
Fattie

Đặt hằng số cần được theo sau bởi [textView layout IfNeeded]; trong khối hoạt hình. (Hoạt hình tự động thực hiện như thế.)
Will Larche

7

Những điều sau đây là đủ:

  1. Chỉ cần nhớ đặt chế độ cuộn được bật thành KHÔNG cho bạn UITextView:

nhập mô tả hình ảnh ở đây

  1. Đặt đúng các ràng buộc bố trí tự động.

Bạn thậm chí có thể sử dụng UITableViewAutomaticDimension.


6

Kết hợp với câu trả lời của Mike McMaster, bạn có thể muốn làm một cái gì đó như:

[myTextView setDelegate: self];

...

- (void)textViewDidChange:(UITextView *)textView {
  if (myTextView == textView) {
     // it changed.  Do resizing here.
  }
}

6

Tôi đã tìm ra một cách để thay đổi kích thước chiều cao của một trường văn bản theo văn bản bên trong nó và cũng sắp xếp một nhãn bên dưới nó dựa trên chiều cao của trường văn bản! Đây là mã.

UITextView *_textView = [[UITextView alloc] initWithFrame:CGRectMake(10, 10, 300, 10)];
NSString *str = @"This is a test text view to check the auto increment of height of a text view. This is only a test. The real data is something different.";
_textView.text = str;

[self.view addSubview:_textView];
CGRect frame = _textView.frame;
frame.size.height = _textView.contentSize.height;
_textView.frame = frame;

UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 5 + frame.origin.y + frame.size.height, 300, 20)];
lbl.text = @"Hello!";
[self.view addSubview:lbl];

Ở đây, tọa độ '5' trong y - của UILabel là khoảng cách mà tôi muốn giữa textView và Label.
dheeraj

6

Các bạn sử dụng tính năng tự động thanh toán và sizetofit của bạn không hoạt động, sau đó vui lòng kiểm tra ràng buộc về chiều rộng của bạn một lần. Nếu bạn đã bỏ lỡ các ràng buộc về chiều rộng thì chiều cao sẽ chính xác.

Không cần sử dụng bất kỳ API nào khác. chỉ cần một dòng sẽ khắc phục tất cả các vấn đề.

[_textView sizeToFit];

Ở đây, tôi chỉ quan tâm đến chiều cao, giữ chiều rộng cố định và đã bỏ lỡ ràng buộc về chiều rộng của TextView của tôi trong bảng phân cảnh.

Và điều này là để hiển thị nội dung động từ các dịch vụ.

Hy vọng điều này có thể giúp ..


6

Bắt đầu với iOS 8, có thể sử dụng các tính năng bố trí tự động của UITableView để tự động thay đổi kích thước UITextView mà không có mã tùy chỉnh nào cả. Tôi đã đặt một dự án trong github để chứng minh điều này bằng hành động, nhưng đây là chìa khóa:

  1. UITextView phải bị vô hiệu hóa cuộn, bạn có thể lập trình hoặc thông qua trình xây dựng giao diện. Nó sẽ không thay đổi kích thước nếu cuộn được bật vì cuộn cho phép bạn xem nội dung lớn hơn.
  2. Trong viewDidLoad cho UITableViewController, bạn phải thiết lập giá trị cho estimatedRowHeight và sau đó đặt rowHeightđể UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Mục tiêu triển khai dự án phải là iOS 8 trở lên.

1
Loại câu trả lời này không được khuyến khích. Bạn nên đăng mã có liên quan ở đây.
Antzi

5

Tôi đã xem xét tất cả các câu trả lời và tất cả đều giữ chiều rộng cố định và chỉ điều chỉnh chiều cao. Nếu bạn muốn điều chỉnh độ rộng, bạn có thể dễ dàng sử dụng phương pháp này:

Vì vậy, khi định cấu hình chế độ xem văn bản của bạn, hãy tắt cuộn

textView.isScrollEnabled = false

và sau đó trong phương thức ủy nhiệm func textViewDidChange(_ textView: UITextView)thêm mã này:

func textViewDidChange(_ textView: UITextView) {
    let newSize = textView.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
    textView.frame = CGRect(origin: textView.frame.origin, size: newSize)
}

Đầu ra:

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


phương thức ủy nhiệm không được gọi là @Peter Stajger
Mansuu ....

4

Điều này hoạt động tốt khi tôi cần làm cho văn bản UITextViewphù hợp với một khu vực cụ thể:

// Văn bản phải được thêm vào chế độ xem phụ, hoặc nội dung xem xét sẽ sai.

- (void) giảmFontToFit: (UITextView *) tv {
    UIFont * font = tv.font;
    double pointSize = font.pointSize;

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        kích thước điểm - = 1.0;
        UIFont * newFont = [UIFont fontWithName: font.fontName kích thước: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "phông chữ xuống% .1f từ% .1f", pointSize, tv.font.pointSize);
}

4

đây là phiên bản nhanh chóng của @jhibberd

    let cell:MsgTableViewCell! = self.tableView.dequeueReusableCellWithIdentifier("MsgTableViewCell", forIndexPath: indexPath) as? MsgTableViewCell
    cell.msgText.text = self.items[indexPath.row]
    var fixedWidth:CGFloat = cell.msgText.frame.size.width
    var size:CGSize = CGSize(width: fixedWidth,height: CGFloat.max)
    var newSize:CGSize = cell.msgText.sizeThatFits(size)
    var newFrame:CGRect = cell.msgText.frame;
    newFrame.size = CGSizeMake(CGFloat(fmaxf(Float(newSize.width), Float(fixedWidth))), newSize.height);
    cell.msgText.frame = newFrame
    cell.msgText.frame.size = newSize        
    return cell

6
Câu hỏi thực sự là ngôn ngữ bất khả tri. Có thực sự cần thiết phải quay lại và viết các cổng nhanh cho tất cả các câu trả lời cho các câu hỏi liên quan đến UIKit không? Có vẻ như điều đó làm cho một cuộc trò chuyện ồn ào.
eremzeit

vấn đề mà hầu hết các câu hỏi này không có ngôn ngữ lập trình cụ thể, vì vậy bạn sẽ tìm thấy nó trong google ngay cả khi bạn tìm kiếm ngôn ngữ nhanh chóng
Fareed Alnamrouti

4

vô hiệu hóa cuộn

thêm chòm sao

và thêm văn bản của bạn

[yourTextView setText:@"your text"];
[yourTextView layoutIfNeeded];

nếu bạn sử dụng UIScrollViewbạn cũng nên thêm cái này;

[yourScrollView layoutIfNeeded];

-(void)viewDidAppear:(BOOL)animated{
    CGRect contentRect = CGRectZero;

    for (UIView *view in self.yourScrollView.subviews) {
         contentRect = CGRectUnion(contentRect, view.frame);
    }
    self.yourScrollView.contentSize = contentRect.size;
}

3

Đối với iOS 7.0, thay vì thiết lập frame.size.heightđến contentSize.height(hiện không có gì) sử dụng [textView sizeToFit].

Xem câu hỏi này .


2

Sử dụng UITextViewDelegate là cách dễ nhất:

func textViewDidChange(_ textView: UITextView) {
    textView.sizeToFit()
    textviewHeight.constant = textView.contentSize.height
}

1

Hi vọng điêu nay co ich:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}

Điều này không hiệu quả! Nó gây ra lỗi: "giá trị bắt buộc là toán hạng trái của phép gán"
leviathan

Bạn chỉ có thể gán cho textView.frame.
jweyrich

1

nếu có bất kỳ ai khác đến đây, giải pháp này hoạt động với tôi, 1 "Ronnie Liew" +4 "user63934" (Văn bản của tôi đến từ dịch vụ web): lưu ý 1000 (không có gì có thể lớn như vậy "trong trường hợp của tôi")

UIFont *fontNormal = [UIFont fontWithName:FONTNAME size:FONTSIZE];

NSString *dealDescription = [client objectForKey:@"description"];

//4
CGSize textSize = [dealDescription sizeWithFont:fontNormal constrainedToSize:CGSizeMake(containerUIView.frame.size.width, 1000)];

CGRect dealDescRect = CGRectMake(10, 300, containerUIView.frame.size.width, textSize.height);

UITextView *dealDesc = [[[UITextView alloc] initWithFrame:dealDescRect] autorelease];

dealDesc.text = dealDescription;
//add the subview to the container
[containerUIView addSubview:dealDesc];

//1) after adding the view
CGRect frame = dealDesc.frame;
frame.size.height = dealDesc.contentSize.height;
dealDesc.frame = frame;

Và đó là ... Chúc mừng


1

Cách tốt nhất mà tôi đã tìm ra để thay đổi kích thước chiều cao của UITextView theo kích thước của văn bản.

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX)];

hoặc bạn có thể sử dụng

CGSize textViewSize = [YOURTEXTVIEW.text sizeWithFont:[UIFont fontWithName:@"SAMPLE_FONT" size:14.0]
                       constrainedToSize:CGSizeMake(YOURTEXTVIEW.frame.size.width, FLT_MAX) lineBreakMode:NSLineBreakByTruncatingTail];

1

Đối với những người muốn textview thực sự di chuyển lên và duy trì vị trí dòng dưới cùng

CGRect frame = textView.frame;
frame.size.height = textView.contentSize.height;

if(frame.size.height > textView.frame.size.height){
    CGFloat diff = frame.size.height - textView.frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y - diff, textView.frame.size.width, frame.size.height);
}
else if(frame.size.height < textView.frame.size.height){
    CGFloat diff = textView.frame.size.height - frame.size.height;
    textView.frame = CGRectMake(0, textView.frame.origin.y + diff, textView.frame.size.width, frame.size.height);
}

1

Mã duy nhất sẽ hoạt động là mã sử dụng 'SizeToFit' như trong câu trả lời bị cấm ở trên nhưng thực tế nó sẽ không nhận được trừ khi bạn gọi nó trong ViewDidAppear hoặc chuyển nó sang sự kiện thay đổi văn bản UITextView.


1

Dựa trên câu trả lời của Nikita Took, tôi đã tìm đến giải pháp sau trong Swift hoạt động trên iOS 8 với tính năng tự động thanh toán:

    descriptionTxt.scrollEnabled = false
    descriptionTxt.text = yourText

    var contentSize = descriptionTxt.sizeThatFits(CGSizeMake(descriptionTxt.frame.size.width, CGFloat.max))
    for c in descriptionTxt.constraints() {
        if c.isKindOfClass(NSLayoutConstraint) {
            var constraint = c as! NSLayoutConstraint
            if constraint.firstAttribute == NSLayoutAttribute.Height {
                constraint.constant = contentSize.height
                break
            }
        }
    }

1

Câu trả lời nhanh: Đoạn mã sau sẽ tính chiều cao của textView của bạn.

                let maximumLabelSize = CGSize(width: Double(textView.frame.size.width-100.0), height: DBL_MAX)
                let options = NSStringDrawingOptions.TruncatesLastVisibleLine | NSStringDrawingOptions.UsesLineFragmentOrigin
                let attribute = [NSFontAttributeName: textView.font!]
                let str = NSString(string: message)
                let labelBounds = str.boundingRectWithSize(maximumLabelSize,
                    options: NSStringDrawingOptions.UsesLineFragmentOrigin,
                    attributes: attribute,
                    context: nil)
                let myTextHeight = CGFloat(ceilf(Float(labelBounds.height)))

Bây giờ bạn có thể đặt chiều cao của textView của bạn thành myTextHeight


Xin lỗi, điều đó có nghĩa là gì: let attribute = [NSFontAttributeName: textView.text.font!] Đây có phải là mã Swift thực sự không có lỗi không?) Ý bạn là let attribute = [NSFontAttributeName: textView.font!]
Massmaker
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.