Fix UITextView line height adjustment for DynamicType, always use the max width for the view (#2916)
* fix text being cut off * adjust line height for dynamictypezio/stable
parent
43206d9f57
commit
d2e5f83cd2
|
@ -40,19 +40,19 @@ class RNUITextViewShadow: RCTShadowView {
|
|||
self.setAttributedText()
|
||||
}
|
||||
|
||||
// Tell yoga not to use flexbox
|
||||
// Returning true here will tell Yoga to not use flexbox and instead use our custom measure func.
|
||||
override func isYogaLeafNode() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// We only need to insert text children
|
||||
// We should only insert children that are UITextView shadows
|
||||
override func insertReactSubview(_ subview: RCTShadowView!, at atIndex: Int) {
|
||||
if subview.isKind(of: RNUITextViewChildShadow.self) {
|
||||
super.insertReactSubview(subview, at: atIndex)
|
||||
}
|
||||
}
|
||||
|
||||
// Whenever the subvies update, set the text
|
||||
// Every time the subviews change, we need to reformat and render the text.
|
||||
override func didUpdateReactSubviews() {
|
||||
self.setAttributedText()
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ class RNUITextViewShadow: RCTShadowView {
|
|||
return
|
||||
}
|
||||
|
||||
// Update the text
|
||||
// Since we are inside the shadow view here, we have to find the real view and update the text.
|
||||
self.bridge.uiManager.addUIBlock { uiManager, viewRegistry in
|
||||
guard let textView = viewRegistry?[self.reactTag] as? RNUITextView else {
|
||||
return
|
||||
|
@ -100,18 +100,25 @@ class RNUITextViewShadow: RCTShadowView {
|
|||
// Create the attributed string with the generic attributes
|
||||
let string = NSMutableAttributedString(string: child.text, attributes: attributes)
|
||||
|
||||
// Set the paragraph style attributes if necessary
|
||||
// Set the paragraph style attributes if necessary. We can check this by seeing if the provided
|
||||
// line height is not 0.0.
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
if child.lineHeight != 0.0 {
|
||||
paragraphStyle.minimumLineHeight = child.lineHeight
|
||||
paragraphStyle.maximumLineHeight = child.lineHeight
|
||||
// Whenever we change the line height for the text, we are also removing the DynamicType
|
||||
// adjustment for line height. We need to get the multiplier and apply that to the
|
||||
// line height.
|
||||
let scaleMultiplier = scaledFontSize / child.fontSize
|
||||
paragraphStyle.minimumLineHeight = child.lineHeight * scaleMultiplier
|
||||
paragraphStyle.maximumLineHeight = child.lineHeight * scaleMultiplier
|
||||
|
||||
string.addAttribute(
|
||||
NSAttributedString.Key.paragraphStyle,
|
||||
value: paragraphStyle,
|
||||
range: NSMakeRange(0, string.length)
|
||||
)
|
||||
|
||||
// Store that height
|
||||
// To calcualte the size of the text without creating a new UILabel or UITextView, we have
|
||||
// to store this line height for later.
|
||||
self.lineHeight = child.lineHeight
|
||||
} else {
|
||||
self.lineHeight = font.lineHeight
|
||||
|
@ -124,24 +131,22 @@ class RNUITextViewShadow: RCTShadowView {
|
|||
self.dirtyLayout()
|
||||
}
|
||||
|
||||
// Create a YGSize based on the max width
|
||||
// To create the needed size we need to:
|
||||
// 1. Get the max size that we can use for the view
|
||||
// 2. Calculate the height of the text based on that max size
|
||||
// 3. Determine how many lines the text is, and limit that number if it exceeds the max
|
||||
// 4. Set the frame size and return the YGSize. YGSize requires Float values while CGSize needs CGFloat
|
||||
func getNeededSize(maxWidth: Float) -> YGSize {
|
||||
// Create the max size and figure out the size of the entire text
|
||||
let maxSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(MAXFLOAT))
|
||||
let textSize = self.attributedText.boundingRect(with: maxSize, options: .usesLineFragmentOrigin, context: nil)
|
||||
|
||||
// Figure out how many total lines there are
|
||||
let totalLines = Int(ceil(textSize.height / self.lineHeight))
|
||||
var totalLines = Int(ceil(textSize.height / self.lineHeight))
|
||||
|
||||
// Default to the text size
|
||||
var neededSize: CGSize = textSize.size
|
||||
|
||||
// If the total lines > max number, return size with the max
|
||||
if self.numberOfLines != 0, totalLines > self.numberOfLines {
|
||||
neededSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(CGFloat(self.numberOfLines) * self.lineHeight))
|
||||
totalLines = self.numberOfLines
|
||||
}
|
||||
|
||||
self.frameSize = neededSize
|
||||
return YGSize(width: Float(neededSize.width), height: Float(neededSize.height))
|
||||
self.frameSize = CGSize(width: CGFloat(maxWidth), height: CGFloat(CGFloat(totalLines) * self.lineHeight))
|
||||
return YGSize(width: Float(self.frameSize.width), height: Float(self.frameSize.height))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue