ฉันจะปรับขนาด UITextView เป็นเนื้อหาได้อย่างไร


521

มีวิธีที่ดีในการปรับขนาดของ a UITextViewเพื่อให้สอดคล้องกับเนื้อหาหรือไม่? พูดเช่นฉันมีUITextViewที่มีหนึ่งบรรทัดข้อความ:

"Hello world"

ฉันจะเพิ่มข้อความอีกบรรทัด:

"Goodbye world"

มีวิธีที่ดีใน Cocoa Touch ที่จะได้รับสิ่งrectนั้นซึ่งจะเก็บทุกบรรทัดในมุมมองข้อความเพื่อให้ฉันสามารถปรับมุมมองพาเรนต์ได้หรือไม่?

เป็นอีกตัวอย่างหนึ่งให้ดูที่ฟิลด์ 'บันทึกย่อของเหตุการณ์ในแอปพลิเคชันปฏิทิน - โปรดสังเกตว่าเซลล์ (และUITextViewมี) ขยายออกเพื่อเก็บข้อความทุกบรรทัดในสตริงของโน้ตได้อย่างไร


โปรดลองอัปเดตคำตอบที่ถูกต้องเนื่องจากคำตอบที่ยอมรับนำไปสู่การคำนวณที่ไม่จำเป็นตอนนี้มีคุณสมบัติขนาดเนื้อหาสำหรับปัญหานี้
Juan Boero

คำตอบ:


610

ใช้ได้ทั้ง iOS 6.1 และ 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;
}

หรือใน Swift (ใช้ได้กับ Swift 4.1 ใน 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)

ถ้าคุณต้องการการสนับสนุนสำหรับ iOS 6.1 คุณก็ควร:

textview.scrollEnabled = NO;

1
ทดสอบบน iOS 7 เพื่อปรับขนาด UITextView เป็น UITableViewCell ใช้งานได้ดีจริงๆ นี่เป็นคำตอบเดียวที่ในที่สุดก็ใช้งานได้สำหรับฉัน ขอบคุณ!
อเล็กซ์

37
ฉันต้องการtextview.scrollEnabled = NO;เพื่อป้องกันไม่ให้ข้อความถูกตัดแม้กระทั่งใน iOS 7
Brian

19
ผมแนะนำให้ใช้แมโครแทนCGFLOAT_MAX MAXFLOATเหมาะสมบนแพลตฟอร์มทั้ง 32/64 บิต
Eonil

2
ผู้ที่เผชิญความผันผวนเล็กน้อยก่อนที่จะเข้าสู่บรรทัดถัดไปให้เพิ่ม `NSRange bottom = NSMakeRange (textView.text.length -1, 1); [textView scrollRangeToVisible: bottom]; `
ajay_nasa

4
เหตุใดจึงมีการโทรไปยัง sizeThatFits (... ) ในรุ่น Swift สองสาย บรรทัดแรกมีไว้ทำอะไร?
nekonari

576

สิ่งนี้ไม่ทำงานบน iOS 7 หรือสูงกว่า

จริงๆแล้วมีวิธีที่ง่ายมากในการปรับขนาดของUITextViewความสูงที่ถูกต้องของเนื้อหา UITextView contentSizeก็สามารถทำได้โดยใช้

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

สิ่งหนึ่งที่ควรทราบก็คือว่าที่ถูกต้องcontentSizeจะใช้ได้เฉพาะหลังจากได้รับการเพิ่มมุมมองที่มีUITextView addSubviewก่อนหน้านั้นก็เท่ากับframe.size

สิ่งนี้จะไม่ทำงานหากเลย์เอาต์อัตโนมัติเปิดอยู่ ด้วยเลย์เอาต์อัตโนมัติวิธีการทั่วไปคือการใช้sizeThatFitsวิธีและอัปเดตconstantค่าตามข้อจำกัดความสูง

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

heightConstraint เป็นข้อ จำกัด โครงร่างที่คุณมักจะติดตั้งผ่าน IBOutlet โดยการเชื่อมโยงคุณสมบัติกับข้อจำกัดความสูงที่สร้างขึ้นในกระดานเรื่องราว


เพียงเพิ่มคำตอบที่น่าอัศจรรย์นี้ในปี 2014 ถ้าคุณ:

[self.textView sizeToFit];

มีความแตกต่างในพฤติกรรมกับiPhone6 ​​+เท่านั้น:

ป้อนคำอธิบายรูปภาพที่นี่

ด้วย 6+ เท่านั้น (ไม่ใช่ 5s หรือ 6) จะเพิ่ม "บรรทัดว่างอีกหนึ่งบรรทัด" ให้กับ UITextView "โซลูชัน RL" แก้ไขสิ่งนี้ได้อย่างสมบูรณ์แบบ:

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

จะแก้ไขปัญหา "บรรทัดพิเศษ" ในวันที่ 6+


2
คุณบันทึกวันของฉัน ฉันกำลังดิ้นรนกับการขยายฟังก์ชันคลาส selfCalculating ที่ลืมเกี่ยวกับเรื่องนี้ ขอบคุณ.
Lukasz

4
Aha! ฉันกำลังตั้งค่าความสูงมุมมองข้อความและจากนั้นปรับความสูงของมุมมองที่มี เห็นได้ชัดว่าเมื่อฉันทำเช่นนั้นความสูงของมุมมองข้อความจะถูกปรับ การตั้งค่าความสูงของมุมมองที่มีก่อนทำสิ่งต่าง ๆ ให้เป็นไปตามที่คาดไว้ (หรือดีกว่าคาดหวังไว้)
เลียน่าสนใจ

11
การใช้ [_textView sizeToFit] รีเฟรชคุณสมบัติ contentSize ลบข้อกำหนดเพื่อเพิ่มลงใน scrollView ก่อน
Rodrigo

1
หากใช้การชำระอัตโนมัติให้โทรlayoutIfNeededบนผู้ดูแล contentSizeจากนั้นคุณสามารถคว้าความสูงจาก
phatmann

4
มันเกี่ยวกับการปรับขนาดคอนเทนเนอร์ภายนอก พฤติกรรมนั้นเปลี่ยนไปใน iOS 7 ฉันแสดงในคำถามที่เชื่อมโยงว่าจะเพิ่ม sizeToFit และเค้าโครงได้อย่างไรหากจำเป็น
Henrik Erlandsson

93

เพื่อทำการปรับขนาดUITextViewภายใน a UITableViewCellฉันพบว่าชุดต่อไปนี้ทำงานใน Xcode 6 กับ iOS 8 SDK:

  • เพิ่ม a และUITextViewa UITableViewCellจำกัด ด้านข้าง
  • การตั้งค่าUITextViewของคุณสมบัติการscrollEnabled NOเมื่อเปิดใช้งานการเลื่อนเฟรมของUITextViewจะไม่ขึ้นกับขนาดเนื้อหา แต่เมื่อปิดการใช้งานการเลื่อนจะมีความสัมพันธ์ระหว่างทั้งสอง
  • หากตารางของคุณใช้ความสูงของแถวเริ่มต้นดั้งเดิมเป็น 44 ตารางจะคำนวณความสูงของแถวโดยอัตโนมัติ แต่หากคุณเปลี่ยนความสูงของแถวเริ่มต้นเป็นอย่างอื่นคุณอาจต้องเปิดการคำนวณความสูงของแถวโดยอัตโนมัติในviewDidLoad:

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

สำหรับการปรับขนาดUITextViews แบบอ่านอย่างเดียวนั่นก็คือ หากคุณอนุญาตให้ผู้ใช้แก้ไขข้อความในของUITextViewคุณคุณต้อง:

  • ใช้textViewDidChange:วิธีการของUITextViewDelegateโปรโตคอลและบอกtableViewให้ทาสีใหม่ทุกครั้งที่มีการแก้ไขข้อความ:

    - (void)textViewDidChange:(UITextView *)textView;
    {
        [tableView beginUpdates];
        [tableView endUpdates];
    }
  • และอย่าลืมตั้งUITextViewผู้แทนจากที่ใดที่หนึ่งไม่ว่าจะในStoryboardหรือในtableView:cellForRowAtIndexPath:


คำตอบที่ดีที่สุดสำหรับฉัน ทำงานอย่างสมบูรณ์แบบและเพิ่ม UITableViewAutomaticDimension ใน iOS 5 ดังนั้นจึงเข้ากันได้ย้อนหลัง
smmelzer

4
ไม่ค่อยได้ผลสำหรับฉัน วิธีการ textViewDidChange ทำให้ tableview ของฉันเด้งทุกครั้งที่ฉันพิมพ์อักขระ สิ่งที่ฉันแนะนำคือแทนที่จะใช้วิธีนั้นในวิธี tableView: cellForRowAtIndexPath สำหรับแถวที่มี textview อยู่หากคุณอยู่ในชุดโหมดอ่านอย่างเดียว. scrollEnabled เป็น NO และถ้าคุณอยู่ในชุดมุมมองการแก้ไข เลื่อนใช้งานเป็น YES วิธีนี้เมื่อแสดงมันจะแสดงข้อความแบบเต็มเสมอและเมื่อแก้ไขมันจะเริ่มต้นด้วยข้อความแบบเต็มและเมื่อคุณเพิ่มข้อความเพิ่มเติมจะยังคงขนาดเดิมโดยข้อความก่อนหน้าจะเลื่อนออกจากด้านบน
SimonTheDiver

3
นอกจากนี้ฉันได้เพิ่มข้อ จำกัด > = height ให้กับ textview เนื่องจาก textfield ว่างเปล่าไม่มีความสูงและไม่สามารถแตะเพื่อเริ่มแก้ไขได้
SimonTheDiver

ทางออกที่ดีเยี่ยม สำหรับฉันtableView.rowHeight = UITableViewAutomaticDimensionมันไม่จำเป็น
Christopher Pickslay

ขอบคุณอีกครั้ง Brett Donald! ฉันลืมวิธีการนี้และพบคำตอบของคุณอีกครั้งในอีก 1 ปีต่อมา😀
Eric Conner

74

วิธีแก้ปัญหาการทำงานที่ง่ายมากโดยใช้รหัสและกระดานเรื่องราวทั้งสอง

ตามรหัส

textView.scrollEnabled = false

โดย Storyboard

ยกเลิกการเลือกEnable Scrolling

ป้อนคำอธิบายรูปภาพที่นี่

ไม่จำเป็นต้องทำอะไรนอกเหนือจากนี้


5
คำตอบนี้ถูกต้อง ในกระดานเรื่องราวคุณมี TextView AutoSize เหมือน UILabel สิ่งที่เราต้องทำคือตั้งค่า scrollEnabled = false
pnavk

4
โดยพื้นฐานแล้วสิ่งนี้ถูกต้อง: หากคุณใช้ข้อ จำกัด Autolayout และปิดการเลื่อนการทำงานทั้งหมดจะทำงาน
Dan Rosenstark

2
ขอบคุณมาก. มันง่ายมากเพียงแค่ปิดการใช้งานการเลื่อนในสตอรี่บอร์ดหรือโค้ดมันจะเหมือนกับ UILabel ที่มีบรรทัด 0
samir105

@Mansuu .... นี่ไม่ใช่วิธีแก้ปัญหาที่รับประกันเนื่องจากมีหลายสิ่งที่คุณสามารถทำได้เพื่อแทนที่ขนาดเนื้อหาที่แท้จริงและถ้าคุณเปลี่ยนข้อความหลังจากวางมุมมองมันจะไม่อัปเดตจนกว่าคุณจะตั้งค่านั้น ขึ้นเช่นกัน แต่สิ่งเหล่านั้นยังคงเป็นจริงสำหรับการตั้งค่า numberOfLines = 0 บน textfield เช่นกัน หากสิ่งนี้ไม่ได้ผลคุณอาจมีข้อ จำกัด อื่น ๆ ที่จะตั้งค่าความสูงโดยปริยาย
Jake T.

2
@iOS หากคุณเพิ่มข้อจำกัดความสูงจากนั้นทำให้ข้อ จำกัด มีความสำคัญต่ำลงมิฉะนั้นจะไม่ทำงาน
Alok

61

รวดเร็ว:

textView.sizeToFit()

14
นอกจากนี้ฉันพบว่าฉันต้องตั้งค่าการเลื่อนเปิดใช้งานเป็นเท็จเพื่อให้การทำงานนี้ textView.scrollEnabled = false
tmarkiewicz

1
คุณควรจำไว้ว่าให้เรียกใช้ textView.layoutIfNeeded () หลัง textView.sizeToFit ()
Daniel Kuta

5
@tmarkiewicz มันทำงานเมื่อข้อความพอดีกับหน้าจอของอุปกรณ์ของคุณ แต่มันจะมีปัญหาเมื่อข้อความของคุณมีขนาดใหญ่กว่าพื้นที่ที่มีอยู่บนหน้าจอ คุณจะไม่สามารถเลื่อนเพื่อดูส่วนที่เหลือของข้อความ
Francisco Romero

นี่คือคำตอบ !!! ไม่จำเป็นต้องแก้ปัญหาที่ซับซ้อนมากขึ้น !!! @ FranciscoRomero ทำไมไม่ใส่ textview ลงในเซลล์ table หรือเซลล์มุมมอง colleciton คุณสามารถเลื่อนดู table หรือมุมมอง
Ben Smith

23

จากประสบการณ์ (จำกัด ) ของฉัน

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

ไม่เคารพอักขระขึ้นบรรทัดใหม่ดังนั้นคุณสามารถจบลงด้วยการที่สั้นCGSizeกว่าที่จำเป็นจริงๆ

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

ดูเหมือนจะเคารพบรรทัดใหม่

UITextViewนอกจากนี้ยังมีข้อความที่ไม่ได้แสดงจริงที่ด้านบนของ ในรหัสของฉันฉันตั้งความสูงใหม่ของUITextViewเป็น 24 พิกเซลที่สูงกว่าความสูงที่กลับมาโดยsizeOfFontวิธีการ


3
ที่ได้รับขนาดราวกับว่ามันจะวาดข้อความบน UILabel หากคุณตั้งค่าขนาดนั้นเป็นเฟรมของ uitextview คุณจะยังจำเป็นต้องเลื่อนบางอย่าง
Kevlar

22

ใน iOS6 คุณสามารถตรวจสอบcontentSizeคุณสมบัติของ UITextView ได้ทันทีหลังจากที่คุณตั้งค่าข้อความ ใน iOS7 นี้จะไม่ทำงานอีกต่อไป หากคุณต้องการคืนค่าลักษณะการทำงานนี้สำหรับ iOS7 ให้วางรหัสต่อไปนี้ในคลาสย่อยของ 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
ฉันจะอ่านเพิ่มเติมเกี่ยวกับเรื่องนี้ได้ที่ไหน ฉันหลงทางโดยสิ้นเชิงกับพฤติกรรมที่ดูเหมือนใหม่ใน iOS 7 เกี่ยวกับเรื่องนี้
Stian Høiland

ความหมายของขนาด CGSize ตัวแปรคืออะไร
Tchelow

ฉันลบขนาดมันไม่ควรจะอยู่ตรงนั้น
phatmann

18

ฉันจะโพสต์ทางออกที่ถูกต้องที่ด้านล่างของหน้าในกรณีที่มีผู้กล้า (หรือสิ้นหวังมากพอ) ที่จะอ่านจนถึงจุดนี้

นี่คือ gitHub repo สำหรับผู้ที่ไม่ต้องการอ่านข้อความทั้งหมด: resizableTextView

สิ่งนี้ใช้ได้กับ iOs7 (และฉันเชื่อว่ามันจะใช้งานได้กับ iOs8) และ autolayout คุณไม่จำเป็นต้องมีหมายเลขมายากลปิดการใช้งานเลย์เอาต์และสิ่งต่างๆเช่นนั้นในระยะสั้นและทางออกที่สวยงาม

ผมคิดว่าทุกรหัสข้อ จำกัด ที่เกี่ยวข้องควรจะไปที่updateConstraintsวิธีการ ดังนั้นขอให้เราเองResizableTextViewดังนั้นขอให้เราเอง

ปัญหาแรกที่เราพบที่นี่คือไม่ทราบขนาดเนื้อหาจริงก่อนviewDidLoadวิธีการ เราสามารถใช้ถนนที่ยาวและบั๊กกี้และคำนวณตามขนาดตัวอักษรการขึ้นบรรทัดใหม่และอื่น ๆ แต่เราต้องการโซลูชันที่มีประสิทธิภาพดังนั้นเราจะทำดังนี้

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

ดังนั้นตอนนี้เรารู้จริง contentSize ไม่ว่าเราอยู่ที่ไหน: viewDidLoadก่อนหรือหลัง ตอนนี้เพิ่มข้อจำกัดความสูงของ textView (ผ่านกระดานเรื่องราวหรือรหัสไม่ว่าจะเป็นอย่างไร) เราจะปรับมูลค่านั้นด้วยcontentSize.height:

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

สิ่งสุดท้ายที่จะทำคือการบอก superclass updateConstraintsไป

[super updateConstraints];

ตอนนี้ชั้นเรียนของเราดูเหมือนว่า:

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

สวยและสะอาดใช่มั้ย และคุณไม่จำเป็นต้องจัดการกับรหัสนั้นในคอนโทรลเลอร์ของคุณ!

แต่เดี๋ยวก่อน! ไม่มีภาพเคลื่อนไหว!

คุณสามารถเปลี่ยนแปลงการเคลื่อนไหวได้อย่างง่ายดายเพื่อให้textViewยืดได้อย่างราบรื่น นี่คือตัวอย่าง:

    [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
ใช้ไม่ได้CGFLOAT_MAX FLT_MAX
rob mayoff

ฉันหวังว่าฉันจะให้คุณมากกว่าหนึ่งคะแนนสำหรับโซลูชันที่ยอดเยี่ยมนี้ !!
สกูตเตอร์

13

คุณลอง[textView sizeThatFits:textView.bounds]ไหม

แก้ไข: sizeThatFits ส่งคืนขนาด แต่ไม่ได้ปรับขนาดองค์ประกอบจริง ฉันไม่แน่ใจว่านั่นคือสิ่งที่คุณต้องการหรือ[textView sizeToFit]มากกว่านั้นคือสิ่งที่คุณกำลังมองหา ไม่ว่าในกรณีใดฉันไม่ทราบว่าจะลงตัวเนื้อหาอย่างที่คุณต้องการหรือไม่ แต่เป็นสิ่งแรกที่ต้องลอง


2
sizetofit ช่วยวัน
michaelsnowden

9

วิธีอื่นคือหาขนาดที่สตริงเฉพาะจะใช้โดยใช้NSStringวิธี:

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

ส่งคืนขนาดของสี่เหลี่ยมที่เหมาะสมกับสตริงที่กำหนดด้วยแบบอักษรที่กำหนด ส่งผ่านขนาดที่มีความกว้างที่ต้องการและความสูงสูงสุดจากนั้นคุณสามารถดูความสูงที่ถูกส่งคืนเพื่อให้พอดีกับข้อความ มีรุ่นที่ให้คุณระบุโหมดการแบ่งบรรทัดด้วย

จากนั้นคุณสามารถใช้ขนาดที่ส่งคืนเพื่อเปลี่ยนขนาดมุมมองของคุณให้พอดี


8

หากคุณไม่ได้มีUITextViewประโยชน์ (เช่นคุณขนาดมุมมองตารางเซลล์), คุณจะต้องคำนวณขนาดโดยการวัดสตริงแล้วคิดเป็น 8 UITextViewจุดของการขยายในแต่ละด้านของ ตัวอย่างเช่นหากคุณทราบความกว้างที่ต้องการของมุมมองข้อความของคุณและต้องการทราบความสูงที่สอดคล้องกัน:

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

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

ในที่นี้แต่ละ 8 มีสัดส่วนหนึ่งในสี่ของขอบเบาะและ 100000 เป็นขนาดสูงสุดที่ใหญ่มาก

ในทางปฏิบัติคุณอาจต้องการเพิ่มfont.leadingความสูงพิเศษ สิ่งนี้จะเพิ่มบรรทัดว่างด้านล่างข้อความของคุณซึ่งอาจดูดีขึ้นหากมีการควบคุมอย่างหนักที่มองเห็นได้ภายใต้มุมมองข้อความ


ผลลัพธ์ที่สมบูรณ์แบบใน iOS 8.1
ลอจิก

การแพ็ดดิ้งเป็นกุญแจสำคัญสำหรับฉัน
thibaut noah

8

เราสามารถทำได้โดยการ จำกัด

  1. ตั้งค่าข้อจำกัดความสูงสำหรับ UITextView ป้อนคำอธิบายรูปภาพที่นี่

2. สร้าง IBOutlet สำหรับข้อจำกัดความสูงนั้น

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

3. อย่าลืมตั้งผู้รับมอบสิทธิ์สำหรับมุมมองข้อความของคุณ

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

}

จากนั้นอัปเดตข้อ จำกัด ของคุณเช่นนี้ :)


นั่นคือชื่อเล่นที่ยอดเยี่ยม!
Fattie

การตั้งค่าคงที่จะต้องตามด้วย [textView layoutIfNeeded]; ในบล็อกแอนิเมชัน (ภาพเคลื่อนไหวอัตโนมัติทำอย่างนั้น)
Will Larche

7

สิ่งต่อไปนี้เพียงพอ:

  1. เพียงจำไว้ว่าให้เปิดใช้งานการเลื่อนเป็นNOสำหรับUITextView:

ป้อนคำอธิบายรูปภาพที่นี่

  1. ตั้งค่าข้อ จำกัด เค้าโครงอัตโนมัติอย่างถูกต้อง

UITableViewAutomaticDimensionคุณยังอาจจะใช้


6

เมื่อรวมกับคำตอบของ Mike McMaster คุณอาจต้องการทำสิ่งต่อไปนี้

[myTextView setDelegate: self];

...

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

6

ฉันพบวิธีปรับขนาดความสูงของฟิลด์ข้อความตามข้อความที่อยู่ภายในและจัดเรียงป้ายด้านล่างตามความสูงของฟิลด์ข้อความ! นี่คือรหัส

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

นี่คือ '5' ในพิกัด y ของ UILabel คือช่องว่างที่ฉันต้องการระหว่าง textView และ Label
dheeraj

6

คนที่ใช้การชำระอัตโนมัติและ sizetofit ของคุณไม่ทำงานโปรดตรวจสอบข้อ จำกัด ความกว้างของคุณหนึ่งครั้ง หากคุณพลาดการ จำกัด ความกว้างความสูงนั้นจะถูกต้อง

ไม่จำเป็นต้องใช้ API อื่น ๆ เพียงหนึ่งบรรทัดจะแก้ไขปัญหาทั้งหมด

[_textView sizeToFit];

ที่นี่ฉันเกี่ยวข้องกับความสูงเท่านั้นรักษาความกว้างคงที่และพลาดข้อ จำกัด ความกว้างของ TextView ของฉันในกระดานเรื่องราว

และนี่คือการแสดงเนื้อหาแบบไดนามิกจากบริการ

หวังว่านี่จะช่วยได้ ..


6

เริ่มต้นด้วย iOS 8 เป็นไปได้ที่จะใช้คุณสมบัติเลย์เอาต์อัตโนมัติของ UITableView เพื่อปรับขนาด UITextView โดยอัตโนมัติโดยไม่มีรหัสที่กำหนดเองเลย ฉันได้วางโครงการในGitHubที่แสดงให้เห็นในการดำเนินการ แต่นี่คือกุญแจสำคัญ:

  1. UITextView ต้องปิดใช้งานการเลื่อนซึ่งคุณสามารถทำแบบโปรแกรมหรือผ่านตัวสร้างส่วนต่อประสาน จะไม่ปรับขนาดหากเปิดใช้งานการเลื่อนเนื่องจากการเลื่อนช่วยให้คุณดูเนื้อหาที่มีขนาดใหญ่ขึ้น
  2. ใน viewDidLoad สำหรับ UITableViewController คุณต้องตั้งค่าสำหรับ estimatedRowHeight จากนั้นตั้งค่าไปrowHeightUITableViewAutomaticDimension

- (void)viewDidLoad {
    [super viewDidLoad];
    self.tableView.estimatedRowHeight = self.tableView.rowHeight;
    self.tableView.rowHeight = UITableViewAutomaticDimension;
}
  1. เป้าหมายการปรับใช้โครงการจะต้องเป็น iOS 8 หรือสูงกว่า

1
คำตอบแบบนี้หมดกำลังใจ คุณควรโพสต์รหัสที่เกี่ยวข้องที่นี่
Antzi

5

ฉันตรวจสอบคำตอบทั้งหมดและทุกคนรักษาความกว้างคงที่และปรับความสูงเท่านั้น หากคุณต้องการปรับความกว้างคุณสามารถใช้วิธีนี้ได้อย่างง่ายดาย:

ดังนั้นเมื่อกำหนดค่ามุมมองข้อความของคุณให้ตั้งค่าการเลื่อนปิดใช้งาน

textView.isScrollEnabled = false

และจากนั้นในวิธีการมอบหมายfunc textViewDidChange(_ textView: UITextView)เพิ่มรหัสนี้:

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

ขาออก:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่


วิธีการมอบหมายไม่ได้รับการเรียก @Peter Stajger
Mansuu ....

4

สิ่งนี้ทำงานได้ดีเมื่อฉันต้องการสร้างข้อความในพื้นที่ที่UITextViewพอดี:

// ข้อความต้องถูกเพิ่มลงในมุมมองย่อยมิฉะนั้น contentviewsize จะผิด

- (เป็นโมฆะ) reducFontToFit: (UITextView *) ทีวี {
    UIFont * font = tv.font;
    double pointSize = font.pointSize;

    ในขณะที่ (tv.contentSize.height> tv.frame.size.height && pointSize> 7.0) {
        pointSize - = 1.0;
        UIFont * newFont = [UIFont fontWithName: font.fontName ขนาด: pointSize];
        tv.font = newFont;
    }
    if (pointSize! = font.pointSize)
        NSLog (@ "แบบอักษรลงไปที่% .1f จาก% .1f", pointSize, tv.font.pointSize);
}

4

นี่คือเวอร์ชั่นที่รวดเร็วของ @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
คำถามนี้ไม่เชื่อเรื่องภาษาเลย จำเป็นหรือไม่ที่จะต้องกลับไปเขียนพอร์ตที่รวดเร็วสำหรับคำตอบทั้งหมดสำหรับคำถามที่เกี่ยวข้องกับ UIKit ดูเหมือนว่าจะเป็นการสนทนาที่มีเสียงดัง
eremzeit

ปัญหาที่คำถามเหล่านี้ส่วนใหญ่ไม่มีภาษาการเขียนโปรแกรมเฉพาะดังนั้นคุณจะพบมันใน google แม้ว่าคุณจะค้นหาภาษาที่รวดเร็ว
Fareed Alnamrouti

4

ปิดการใช้งานการเลื่อน

เพิ่มค่าคงที่

และเพิ่มข้อความของคุณ

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

ถ้าคุณใช้UIScrollViewคุณควรเพิ่มสิ่งนี้ด้วย

[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

สำหรับ iOS 7.0 แทนการตั้งค่าframe.size.heightไปcontentSize.height(ซึ่งขณะนี้ไม่ทำอะไรเลย) [textView sizeToFit]การใช้งาน

ดูคำถามนี้


2

การใช้ UITextViewDelegate เป็นวิธีที่ง่ายที่สุด:

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

1

หวังว่านี่จะช่วย:

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

มันใช้งานไม่ได้! มันทำให้เกิดข้อผิดพลาด: "lvalue ต้องเป็นตัวถูกดำเนินการทางด้านซ้ายของการกำหนด"
Leviathan

คุณสามารถมอบหมายให้textView.frameเท่านั้น
jweyrich

1

ถ้ามีใครมาที่นี่วิธีนี้ใช้ได้ผลกับฉัน 1 "Ronnie Liew" +4 "user63934" (ข้อความของฉันมาจากบริการเว็บ): บันทึก 1,000 (ไม่มีอะไรจะใหญ่มาก "ในกรณีของฉัน")

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;

และนั่นคือ ... ไชโย


1

วิธีที่ดีที่สุดที่ฉันพบเพื่อปรับขนาดความสูงของ UITextView อีกครั้งตามขนาดของข้อความ

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

หรือคุณสามารถใช้

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

1

สำหรับผู้ที่ต้องการให้มุมมองข้อความเลื่อนขึ้นและรักษาตำแหน่งบรรทัดล่าง

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

รหัสเดียวที่จะทำงานคือรหัสที่ใช้ 'SizeToFit' ในคำตอบ jhibberd ด้านบน แต่จริงๆแล้วมันจะไม่รับจนกว่าคุณจะเรียกมันว่าในViewDidAppearหรือเชื่อมโยงกับการเปลี่ยนแปลงข้อความ UITextView


1

จากคำตอบของ Nikita Took ฉันมาถึงวิธีแก้ปัญหาต่อไปนี้ใน Swift ที่ทำงานบน iOS 8 พร้อมการชำระอัตโนมัติ:

    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

Swift answer: โค้ดต่อไปนี้คำนวณความสูงของ textView ของคุณ

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

ตอนนี้คุณสามารถตั้งค่าความสูงของ textView ของคุณเป็น myTextHeight


ขออภัยความหมาย: let attribute = [NSFontAttributeName: textView.text.font!] รหัสนี้เป็น Swift โดยไม่มีข้อผิดพลาดหรือไม่) คุณหมายถึง let attribute = [NSFontAttributeName: textView.font!]
Massmaker
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.