ทันสมัยสำหรับปี 2562
มันเป็นหนึ่งในข้อบกพร่องที่ร้ายแรงที่สุดใน iOS
คลาสที่ให้ที่นี่UITextViewFixed
เป็นวิธีการแก้ปัญหาที่เหมาะสมที่สุดโดยรวม
นี่คือคลาส:
@IBDesignable class UITextViewFixed: UITextView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
}
}
อย่าลืมปิด scrollEnabled ใน Inspector!
วิธีการแก้ปัญหาทำงานอย่างถูกต้องในกระดานเรื่องราว
วิธีการแก้ปัญหาทำงานอย่างถูกต้องที่รันไทม์
เสร็จแล้ว
โดยทั่วไปที่ควรจะเป็นสิ่งที่คุณต้องการในกรณีส่วนใหญ่
แม้ว่าคุณจะมีการเปลี่ยนแปลงความสูงของมุมมองข้อความที่เกี่ยวกับการบิน , UITextViewFixed
มักจะไม่สิ่งที่คุณต้องการ
(ตัวอย่างทั่วไปของการเปลี่ยนความสูงได้ทันทีคือเปลี่ยนเป็นประเภทผู้ใช้)
นี่คือ UITextView ที่หักจาก Apple ...
นี่คือUITextViewFixed
:
ทราบว่าแน่นอนคุณต้อง
ปิด scrollEnabled ในตัวตรวจสอบ!
อย่าลืมปิด scrollEnabled! :)
บางประเด็นเพิ่มเติม
(1) ในบางกรณีที่ผิดปกติ - ตัวอย่างเช่นบางกรณีของตารางที่มีความยืดหยุ่นของเซลล์ที่เปลี่ยนแปลงสูงแบบไดนามิก - Apple ทำสิ่งที่แปลกประหลาด: พวกเขาเพิ่มพื้นที่พิเศษที่ด้านล่างพวกเขาเพิ่มพื้นที่พิเศษที่ด้านล่างไม่มีจริงๆ! สิ่งนี้จะต้องเป็นหนึ่งในสิ่งที่ทำให้โกรธที่สุดใน iOS
นี่คือ "การแก้ไขด่วน" เพื่อเพิ่มไปด้านบนซึ่งมักจะช่วยด้วยความบ้าที่
...
textContainerInset = UIEdgeInsets.zero
textContainer.lineFragmentPadding = 0
// this is not ideal, but you can sometimes use this
// to fix the "extra space at the bottom" insanity
var b = bounds
let h = sizeThatFits(CGSize(
width: bounds.size.width,
height: CGFloat.greatestFiniteMagnitude)
).height
b.size.height = h
bounds = b
...
(2) บางครั้งในการแก้ไข Apple mess-up อื่นที่บอบบางคุณต้องเพิ่มสิ่งนี้:
override func setContentOffset(_ contentOffset: CGPoint, animated: Bool) {
super.setContentOffset(contentOffset, animated: false)
}
(3) เราควรจะเพิ่ม:
contentInset = UIEdgeInsets.zero
หลังจากที่ใน.lineFragmentPadding = 0
UITextViewFixed
อย่างไรก็ตาม ... เชื่อหรือไม่ ... มันใช้ไม่ได้กับ iOS ปัจจุบัน! (ตรวจสอบในปี 2562) อาจจำเป็นต้องเพิ่มบรรทัดนั้นอีกในอนาคต
ความจริงที่ว่าUITextView
แตกใน iOS เป็นหนึ่งในสิ่งที่แปลกประหลาดที่สุดในคอมพิวเตอร์มือถือทั้งหมด ครบรอบสิบปีของคำถามนี้ แต่ก็ยังไม่ได้รับการแก้ไข!
สุดท้ายนี่คือเคล็ดลับที่คล้ายกันสำหรับ Text Field : https://stackoverflow.com/a/43099816/294884
เคล็ดลับแบบสุ่มสมบูรณ์: วิธีเพิ่ม "... " ในตอนท้าย
บ่อยครั้งที่คุณใช้ UITextView "like UILabel" คุณต้องการตัดทอนข้อความโดยใช้เครื่องหมายจุดไข่ปลา "... "
ถ้าเป็นเช่นนั้นเพิ่มรหัสบรรทัดที่สามใน "ตั้งค่า":
textContainer.lineBreakMode = .byTruncatingTail
เคล็ดลับที่มีประโยชน์ถ้าคุณต้องการความสูงเป็นศูนย์เมื่อไม่มีข้อความเลย
บ่อยครั้งที่คุณใช้มุมมองข้อความเพื่อแสดงข้อความเท่านั้น ดังนั้นผู้ใช้ไม่สามารถแก้ไขอะไรได้จริง คุณใช้บรรทัด "0" เพื่อหมายถึงมุมมองข้อความจะเปลี่ยนความสูงโดยอัตโนมัติขึ้นอยู่กับจำนวนบรรทัดของข้อความ
เยี่ยมมาก แต่ถ้าไม่มีข้อความเลยน่าเสียดายที่คุณมีความสูงเท่ากับข้อความหนึ่งบรรทัด !! มุมมองข้อความไม่เคย "หายไป"
หากคุณต้องการให้ "หายไป" เพียงเพิ่มสิ่งนี้
override var intrinsicContentSize: CGSize {
var i = super.intrinsicContentSize
print("for \(text) size will be \(i)")
if text == "" { i.height = 1.0 }
print(" but we changed it to \(i)")
return i
}
(ฉันทำให้มันเป็น '1' ดังนั้นจึงเป็นที่ชัดเจนว่าเกิดอะไรขึ้น '0' ไม่เป็นไร)
แล้ว UILabel ล่ะ
เมื่อแสดงข้อความ UILabel มีข้อดีกว่า UITextView มากมาย UILabel ไม่ประสบปัญหาที่อธิบายไว้ในหน้า QA นี้ เหตุผลที่เรามักจะ "ยอมแพ้" และเพียงแค่ใช้ UITextView ก็คือ UILabel นั้นยากที่จะทำงานด้วย โดยเฉพาะอย่างยิ่งมันเป็นเรื่องยากที่จะเพิ่มการเติมpaddingอย่างถูกต้องลงใน UILabel ในความเป็นจริงที่นี่คือการสนทนาเต็มรูปแบบเกี่ยวกับวิธี "ในที่สุด" อย่างถูกต้องเพิ่มการขยายไปยัง UILabel อย่างถูกต้อง: https://stackoverflow.com/a/58876988/294884 ในบางกรณีถ้าคุณทำเค้าโครงยากด้วยเซลล์ความสูงแบบไดนามิกบางครั้งก็เป็น ดีกว่าที่จะทำมันอย่างหนักกับ UILabel