Bagaimana cara mengukur ukuran UITextView untuk kontennya?

521

Apakah ada cara yang baik untuk menyesuaikan ukuran UITextViewagar sesuai dengan kontennya? Katakan misalnya saya punya UITextViewyang berisi satu baris teks:

"Hello world"

Saya kemudian menambahkan baris teks lain:

"Goodbye world"

Apakah ada cara yang baik di Cocoa Touch untuk mendapatkan rect yang akan menampung semua baris dalam tampilan teks sehingga saya bisa menyesuaikan tampilan induk sesuai?

Sebagai contoh lain, lihat bidang catatan untuk acara di aplikasi Kalender - perhatikan bagaimana sel (dan UITextViewberisi) memperluas untuk menahan semua baris teks dalam string catatan.

drewh
sumber
harap pertimbangkan untuk memperbarui jawaban yang benar, karena jawaban yang diterima mengarah ke perhitungan yang tidak perlu, sekarang ada properti contentSize untuk masalah ini.
Juan Boero

Jawaban:

610

Ini berfungsi untuk iOS 6.1 dan 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;
}

Atau di Swift (Bekerja dengan Swift 4.1 di 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)

Jika Anda ingin dukungan untuk iOS 6.1 maka Anda juga harus:

textview.scrollEnabled = NO;
tumpangan
sumber
1
Diuji pada iOS 7 untuk mengubah ukuran UITextView menjadi UITableViewCell. Bekerja sangat bagus. Inilah satu-satunya jawaban yang akhirnya berhasil untuk saya. Terima kasih!
Alex
37
Saya membutuhkannya textview.scrollEnabled = NO;untuk mencegah agar teks tidak terpotong bahkan di iOS 7.
Brian
19
Saya merekomendasikan untuk menggunakan CGFLOAT_MAXmakro daripada MAXFLOAT. Tepat di kedua platform 32/64 bit.
Eonil
3
Orang yang menghadapi sedikit fluktuasi sebelum masuk pada baris berikutnya menambahkan `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa
4
Mengapa ada dua panggilan terpisah ke sizeThatFits (...) dalam versi Swift? Untuk apa baris pertama?
nekonari
576

Ini tidak lagi berfungsi di iOS 7 atau lebih tinggi

Sebenarnya ada cara yang sangat mudah untuk melakukan pengubahan ukuran dari UITextViewketinggian konten yang benar. Ini dapat dilakukan dengan menggunakan UITextView contentSize.

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

Satu hal yang perlu diperhatikan adalah bahwa yang benar contentSizehanya tersedia setelah itu UITextViewtelah ditambahkan ke tampilan dengan addSubview. Sebelum itu sama denganframe.size

Ini tidak akan berfungsi jika tata letak otomatis AKTIF. Dengan tata letak otomatis, pendekatan umum adalah menggunakan sizeThatFitsmetode dan memperbarui constantnilai pada batasan ketinggian.

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

heightConstraint adalah kendala tata letak yang biasanya Anda siapkan melalui IBOutlet dengan menautkan properti ke batasan ketinggian yang dibuat dalam storyboard.


Untuk menambah jawaban yang luar biasa ini, 2014, jika Anda:

[self.textView sizeToFit];

ada perbedaan perilaku hanya dengan iPhone6 ​​+ :

masukkan deskripsi gambar di sini

Dengan 6+ saja (bukan 5s atau 6) itu memang menambahkan "satu lagi baris kosong" ke UITextView. "Solusi RL" memperbaiki ini dengan sempurna:

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

Ini memperbaiki masalah "garis ekstra" pada 6+.

Ronnie Liew
sumber
2
Kamu menyelamatkan hariku. Saya sedang berjuang dengan ekstensi fungsi kelas selfCalculating lupa tentang ini. Terima kasih.
Lukasz
4
Aha! Saya sedang mengatur ketinggian tampilan teks dan kemudian menyesuaikan ketinggian tampilan yang mengandung. Rupanya ketika saya melakukan itu ketinggian tampilan teks sedang disesuaikan. Mengatur ketinggian tampilan yang memuat terlebih dahulu menjadikan segala sesuatunya berfungsi seperti yang diharapkan (atau, lebih baik, diharapkan).
Hot Licks
11
Menggunakan [_textView sizeToFit] menyegarkan properti contentSize, menghapus persyaratan untuk menambahkannya ke scrollView sebelumnya.
Rodrigo
1
Jika menggunakan pembayaran otomatis, hubungi superview layoutIfNeeded. Maka Anda dapat mengambil ketinggian dari contentSize.
phatmann
4
Ini tentang mengubah ukuran wadah luar. Perilaku itu telah berubah di iOS 7. Saya menunjukkan dalam pertanyaan terkait di mana menambahkan sizeToFit dan layoutIfNeeded.
Henrik Erlandsson
93

Untuk membuat ukuran secara dinamis UITextViewdi dalam a UITableViewCell, saya menemukan kombinasi berikut berfungsi di Xcode 6 dengan iOS 8 SDK:

  • Tambahkan UITextViewke UITableViewCelldan batasi ke samping
  • Mengatur UITextView's scrollEnabledproperti untuk NO. Dengan menggulir diaktifkan, bingkai UITextViewbebas dari ukuran kontennya, tetapi dengan menggulir dinonaktifkan, ada hubungan antara keduanya.
  • Jika tabel Anda menggunakan tinggi baris default asli 44 maka tabel akan secara otomatis menghitung ketinggian baris, tetapi jika Anda mengubah tinggi baris default ke yang lain, Anda mungkin perlu mengaktifkan penghitungan otomatis ketinggian baris secara manual di viewDidLoad:

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

Untuk ukuran read-only secara dinamis UITextView, itu saja. Jika Anda mengizinkan pengguna untuk mengedit teks di Anda UITextView, Anda juga perlu:

  • Terapkan textViewDidChange:metode UITextViewDelegateprotokol, dan beri tahu tableViewuntuk mengecat ulang sendiri setiap kali teks diedit:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • Dan jangan lupa mengatur UITextViewdelegasi di suatu tempat, baik di dalam Storyboardatau ditableView:cellForRowAtIndexPath:

Brett Donald
sumber
Jawaban terbaik untuk saya. Bekerja dengan sempurna dan UITableViewAutomaticDimension ditambahkan di iOS 5 sehingga kompatibel dengan mundur.
smmelzer
4
Tidak cukup bekerja untuk saya. Metode textViewDidChange menyebabkan tampilan tabel saya memantul setiap kali saya mengetik karakter. Apa yang saya sarankan adalah bahwa alih-alih menggunakan metode itu, dalam metode tableView: cellForRowAtIndexPath, untuk baris dengan textview di atasnya, jika Anda berada dalam mode read only atur .scrollEnabled menjadi NO, dan jika Anda berada dalam set tampilan pengeditan gulir diaktifkan ke YES. Dengan cara ini ketika hanya menampilkannya akan selalu menampilkan teks lengkap dan ketika mengeditnya akan mulai dengan teks lengkap dan ketika Anda menambahkan teks lebih lanjut akan tetap ukuran yang sama dengan teks sebelumnya bergulir dari atas
SimonTheDiver
3
selanjutnya saya menambahkan>> batasan ketinggian ke tampilan teks karena bidang teks kosong tidak memiliki ketinggian dan tidak dapat disadap untuk mulai mengedit.
SimonTheDiver
Solusi yang sangat baik. Bagi saya, tableView.rowHeight = UITableViewAutomaticDimensionitu tidak perlu.
Christopher Pickslay
Sekali lagi terima kasih, Brett Donald! Saya lupa bagaimana melakukan ini dan menemukan jawaban Anda sekali lagi lebih dari 1 tahun kemudian 😀.
Eric Conner
76

Solusi kerja yang sangat mudah menggunakan kode dan storyboard keduanya.

Dengan kode

textView.scrollEnabled = false

Oleh Storyboard

Hapus centang pada Scrolling Enable

masukkan deskripsi gambar di sini

Tidak perlu melakukan apa pun selain ini.

Alok
sumber
5
Jawaban ini benar. Di StoryBoard Anda memiliki TextView AutoSize seperti UILabel. Yang perlu kita lakukan adalah mengatur scrollEnabled = false.
pnavk
4
Pada dasarnya, ini benar: jika Anda menggunakan batasan Autolayout dan mematikan scrolling, semuanya berfungsi.
Dan Rosenstark
2
Terima kasih banyak. Sesederhana itu, cukup nonaktifkan pengguliran di storyboard atau kode, itu akan menjadi seperti UILabel dengan baris 0.
samir105
@Mansuu .... Ini bukan solusi yang dijamin, karena ada hal-hal yang dapat Anda lakukan untuk mengganti ukuran konten intrinsik, dan jika Anda mengubah teks setelah tampilan diletakkan, itu tidak akan diperbarui kecuali jika Anda menetapkan bahwa naik juga. Tetapi, hal-hal itu tetap berlaku untuk pengaturan numberOfLines = 0 pada bidang teks juga. Jika ini tidak berhasil, Anda mungkin memiliki kendala lain yang secara implisit akan menetapkan ketinggian.
Jake T.
2
@ IOS jika Anda menambahkan kendala ketinggian kemudian membuat prioritas kendala lebih rendah jika tidak maka tidak akan berhasil.
Alok
61

Cepat:

textView.sizeToFit()
Juan Boero
sumber
14
Selain itu, saya menemukan bahwa saya perlu mengatur pengguliran diaktifkan ke false agar ini berfungsi. textView.scrollEnabled = false
tmarkiewicz
1
Anda harus ingat untuk memanggil textView.layoutIfNeeded () setelah textView.sizeToFit ()
Daniel Kuta
5
@tmarkiewicz berfungsi saat teks pas di layar perangkat Anda, tetapi itu akan menjadi masalah ketika teks Anda lebih besar dari ruang yang ada di layar. Anda tidak akan dapat menggulirnya untuk melihat sisa teks.
Francisco Romero
Ini jawabannya !!! Tidak perlu solusi yang lebih rumit !!! @FranciscoRomero Mengapa tidak meletakkan tampilan teks dalam sel tampilan tabel atau colleciton maka Anda selalu dapat menggulir tampilan tabel atau colleciton ....
Ben Smith
23

Dalam pengalaman saya (terbatas),

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

tidak menghormati karakter baris baru, sehingga Anda bisa berakhir dengan jauh lebih pendek CGSizedaripada yang sebenarnya diperlukan.

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

tampaknya menghormati baris baru.

Selain itu, teks tidak benar-benar ditampilkan di bagian atas UITextView. Dalam kode saya, saya mengatur tinggi baru UITextViewmenjadi 24 piksel lebih besar dari tinggi yang dikembalikan oleh sizeOfFontmetode.

pengguna63934
sumber
3
Itu mendapatkan ukuran seolah-olah akan menggambar teks pada label UIL. Jika Anda mengatur ukuran itu ke bingkai uitextview, maka Anda masih perlu menggulirkannya.
Kevlar
22

Di iOS6, Anda dapat memeriksa contentSizeproperti UITextView tepat setelah Anda mengatur teks. Di iOS7, ini tidak akan berfungsi lagi. Jika Anda ingin memulihkan perilaku ini untuk iOS7, tempatkan kode berikut di subkelas 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;
    }
}
Phatmann
sumber
2
Di mana saya bisa membaca lebih lanjut tentang ini? Saya benar-benar kehilangan perilaku yang tampaknya baru di iOS 7 tentang ini.
Stian Høiland
Apa arti dari ukuran variabel CGSize?
Tchelow
Saya menghapus ukuran, itu seharusnya tidak ada di sana.
phatmann
18

Saya akan memposting solusi yang tepat di bagian bawah halaman jika seseorang berani (atau cukup putus asa) untuk membaca sampai titik ini.

Berikut adalah repo gitHub untuk mereka yang tidak ingin membaca semua teks itu: resizableTextView

Ini berfungsi dengan iOs7 (dan saya yakin itu akan bekerja dengan iOs8) dan dengan autolayout. Anda tidak perlu angka ajaib, nonaktifkan tata letak dan hal-hal seperti itu.Solusi singkat dan elegan.

Saya pikir, semua kode terkait kendala harus menuju ke updateConstraintsmetode. Jadi, mari kita buat sendiriResizableTextView .

Masalah pertama yang kami temui di sini adalah yang tidak tahu ukuran konten asli sebelum viewDidLoadmetode. Kita bisa mengambil jalan yang panjang dan buggy dan menghitungnya berdasarkan ukuran font, penghentian baris, dll. Tapi kita membutuhkan solusi yang kuat, jadi kita akan melakukan:

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

Jadi sekarang kita tahu sebenarnya contentSize di mana pun kita berada: sebelum atau sesudah viewDidLoad. Sekarang tambahkan batasan ketinggian pada textView (melalui storyboard atau kode, tidak peduli bagaimana). Kami akan menyesuaikan nilai itu dengan contentSize.height:

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

Hal terakhir yang harus dilakukan adalah memberi tahu superclass updateConstraints.

[super updateConstraints];

Sekarang kelas kita terlihat seperti:

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];
}

Cantik dan bersih, bukan? Dan Anda tidak harus berurusan dengan kode itu di controller Anda !

Tapi tunggu! Y TANPA ANIMASI!

Anda dapat dengan mudah menghidupkan perubahan untuk melakukan textViewperegangan dengan lancar. Berikut ini sebuah contoh:

    [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];
Nikita Took
sumber
4
Gunakan CGFLOAT_MAX, bukan FLT_MAX.
rob mayoff
Saya berharap saya bisa memberi Anda lebih dari satu suara untuk solusi yang luar biasa ini !!
Skuter
13

Apakah kamu sudah mencoba? [textView sizeThatFits:textView.bounds] ?

Sunting: sizeThatFits mengembalikan ukuran tetapi sebenarnya tidak mengubah ukuran komponen. Saya tidak yakin apakah itu yang Anda inginkan, atau apakah [textView sizeToFit]lebih dari yang Anda cari. Dalam kedua kasus, saya tidak tahu apakah itu akan cocok dengan konten yang Anda inginkan, tetapi ini adalah hal pertama yang harus dicoba.

Mike McMaster
sumber
2
sizetofit menghemat hari
michaelsnowden
9

Metode lain adalah menemukan ukuran string tertentu akan mengambil menggunakan NSStringmetode ini:

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

Ini mengembalikan ukuran kotak yang cocok dengan string yang diberikan dengan font yang diberikan. Masukkan ukuran dengan lebar yang diinginkan dan tinggi maksimum, dan kemudian Anda dapat melihat ketinggian yang dikembalikan agar sesuai dengan teks. Ada versi yang memungkinkan Anda menentukan mode jeda baris juga.

Anda kemudian dapat menggunakan ukuran yang dikembalikan untuk mengubah ukuran tampilan Anda agar sesuai.

Kecanduan Kode
sumber
8

Jika Anda tidak memiliki perangkat UITextViewpraktis (misalnya, Anda mengukur sel tampilan tabel), Anda harus menghitung ukuran dengan mengukur string, lalu menghitung 8 pt bantalan pada setiap sisi a UITextView. Misalnya, jika Anda mengetahui lebar tampilan teks yang diinginkan dan ingin mengetahui ketinggian yang sesuai:

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

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

Di sini, masing-masing 8 adalah akuntansi untuk salah satu dari empat tepi empuk, dan 100000 hanya berfungsi sebagai ukuran maksimum yang sangat besar.

Dalam praktiknya, Anda mungkin ingin menambahkan ekstra font.leadingpada ketinggian; ini menambahkan baris kosong di bawah teks Anda, yang mungkin terlihat lebih baik jika ada kontrol berat secara visual langsung di bawah tampilan teks.

Brent Royal-Gordon
sumber
hasil sempurna di iOS 8.1
Logic
Padding adalah kunci bagi saya
thibaut noah
8

Kita bisa melakukannya dengan kendala.

  1. Tetapkan batasan Ketinggian untuk UITextView. masukkan deskripsi gambar di sini

2.Buat IBOutlet untuk batasan ketinggian itu.

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

3. jangan lupa untuk mengatur delegasi untuk tampilan teks Anda.

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;
    }];

}

kemudian perbarui kendala Anda seperti ini :)

Kishore Kumar
sumber
itu nama panggilan FANTASTIS!
Fattie
Mengatur konstanta perlu diikuti oleh [textView layoutIfNeeded]; di blok animasi. (Animasi Autolayout melakukannya seperti itu.)
Will Larche
7

Hal-hal berikut sudah cukup:

  1. Ingatlah untuk mengatur pengguliran diaktifkan ke TIDAK untuk Anda UITextView:

masukkan deskripsi gambar di sini

  1. Atur Batasan Tata Letak Otomatis dengan benar.

Anda bahkan dapat menggunakan UITableViewAutomaticDimension.

Bartłomiej Semańczyk
sumber
6

Dikombinasikan dengan jawaban Mike McMaster, Anda mungkin ingin melakukan sesuatu seperti:

[myTextView setDelegate: self];

...

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

Saya menemukan cara untuk mengubah ukuran ketinggian bidang teks sesuai dengan teks di dalamnya dan juga mengatur label di bawahnya berdasarkan ketinggian bidang teks! Ini kodenya.

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];
dheeraj
sumber
Di sini '5' di y - koordinat UILabel adalah celah yang saya inginkan antara textView dan Label.
dheeraj
6

Cowok yang menggunakan autolayout dan sizetofit Anda tidak berfungsi, maka silakan periksa batasan lebar Anda satu kali. Jika Anda melewatkan batasan lebar maka ketinggiannya akan akurat.

Tidak perlu menggunakan API lainnya. hanya satu baris yang akan memperbaiki semua masalah.

[_textView sizeToFit];

Di sini, saya hanya mementingkan ketinggian, menjaga lebar tetap dan telah melewatkan batasan lebar TextView saya di storyboard.

Dan ini untuk menampilkan konten dinamis dari layanan.

Semoga ini bisa membantu ..

Swaroop S
sumber
6

Dimulai dengan iOS 8, dimungkinkan untuk menggunakan fitur tata letak otomatis dari UITableView untuk secara otomatis mengubah ukuran UITextView tanpa kode kustom sama sekali. Saya telah meletakkan sebuah proyek di github yang menunjukkan hal ini dalam tindakan, tetapi inilah kuncinya:

  1. UITextView harus memiliki scrolling yang dinonaktifkan, yang dapat Anda lakukan secara terprogram atau melalui pembuat antarmuka. Ini tidak akan mengubah ukuran jika menggulir diaktifkan karena menggulir memungkinkan Anda melihat konten yang lebih besar.
  2. Di viewDidLoad untuk UITableViewController, Anda harus menetapkan nilai untuk taksiranRowHeight dan kemudian mengatur rowHeightuntuk UITableViewAutomaticDimension.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. Target penyebaran proyek harus iOS 8 atau lebih besar.
Chuck Krutsinger
sumber
1
Jawaban semacam ini tidak disarankan. Anda harus memposting kode yang relevan di sini.
Antzi
5

Saya meninjau semua jawaban dan semuanya menjaga lebar tetap dan hanya menyesuaikan ketinggian. Jika Anda ingin menyesuaikan lebar juga, Anda dapat dengan mudah menggunakan metode ini:

jadi saat mengonfigurasi tampilan teks Anda, atur scroll dinonaktifkan

textView.isScrollEnabled = false

dan kemudian dalam metode delegasikan func textViewDidChange(_ textView: UITextView)tambahkan kode ini:

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

Output:

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Peter Stajger
sumber
metode delegasi tidak dipanggil @Peter Stajger
Mansuu ....
4

Ini berfungsi dengan baik ketika saya perlu membuat teks dalam UITextView area tertentu:

// Teks harus sudah ditambahkan ke subview, atau contentviewsize akan salah.

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

    while (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1.0;
        UIFont * newFont = [UIFont fontWithName: font.fontName size: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "font ke% .1f dari% .1f", pointSize, tv.font.pointSize);
}
Bill Cheswick
sumber
4

di sini adalah versi cepat dari @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
Fareed Alnamrouti
sumber
6
Pertanyaannya adalah agnostik bahasa. Apakah benar-benar perlu untuk kembali dan menulis port cepat untuk semua jawaban pada pertanyaan terkait UIKit? Sepertinya itu membuat percakapan menjadi berisik.
eremzeit
masalah yang sebagian besar pertanyaan ini tidak memiliki bahasa pemrograman khusus sehingga Anda akan menemukannya di google bahkan jika Anda mencari bahasa cepat
Fareed Alnamrouti
4

nonaktifkan scrolling

tambahkan kendala

dan tambahkan teks Anda

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

jika Anda menggunakan UIScrollViewAnda harus menambahkan ini juga;

[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;
}
alicanozkara
sumber
3

Untuk iOS 7.0, alih-alih mengatur frame.size.heightke contentSize.height(yang saat ini tidak melakukan apa-apa) digunakan [textView sizeToFit].

Lihat pertanyaan ini .

Stian Høiland
sumber
2

Menggunakan UITextViewDelegate adalah cara termudah:

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

Semoga ini membantu:

- (void)textViewDidChange:(UITextView *)textView {
  CGSize textSize = textview.contentSize;
  if (textSize != textView.frame.size)
      textView.frame.size = textSize;
}
Marty
sumber
Ini tidak berfungsi! Ini menyebabkan kesalahan: "nilai diperlukan sebagai operan penugasan yang tersisa"
leviathan
Anda hanya dapat menetapkan textView.frame.
jweyrich
1

jika ada yang lain dapatkan di sini, solusi ini berfungsi untuk saya, 1 "Ronnie Liew" +4 "user63934" (Teks saya tiba dari layanan web): perhatikan 1000 (tidak ada yang bisa sebesar ini "dalam kasus saya")

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;

Dan itu ... Ceria

Alejo JM
sumber
1

Cara terbaik yang saya temukan untuk mengukur ulang ketinggian UITextView sesuai dengan ukuran teks.

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

atau Anda bisa MENGGUNAKAN

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

Bagi mereka yang ingin tampilan teks benar-benar bergerak ke atas dan mempertahankan posisi garis bawah

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);
}
Gal Blank
sumber
1

Satu-satunya kode yang akan berfungsi adalah kode yang menggunakan 'SizeToFit' seperti pada jhibberd jawaban di atas tetapi sebenarnya tidak akan mengambil kecuali Anda memanggilnya di ViewDidAppear atau mengirimnya ke teks UITextView mengubah acara.

Mohammad Zekrallah
sumber
1

Berdasarkan jawaban Nikita Took, saya menemukan solusi berikut di Swift yang bekerja di iOS 8 dengan autolayout:

    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
            }
        }
    }
Apfelsaft
sumber
1

Jawaban cepat: Kode berikut menghitung ketinggian textView Anda.

                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)))

Sekarang Anda dapat mengatur ketinggian textView Anda myTextHeight

RawMean
sumber
Maaf, apa artinya: let attribute = [NSFontAttributeName: textView.text.font!] Apakah ini benar-benar kode Swift tanpa kesalahan?) Apakah maksud Anda let attribute = [NSFontAttributeName: textView.font!]
Massmaker