about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift43
1 files changed, 24 insertions, 19 deletions
diff --git a/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift b/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift
index 4f3eda43c..5a462f6b6 100644
--- a/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift
+++ b/modules/react-native-ui-text-view/ios/RNUITextViewShadow.swift
@@ -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))
-
-    // Default to the text size
-    var neededSize: CGSize = textSize.size
+    var totalLines = Int(ceil(textSize.height / self.lineHeight))
 
-    // 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))
   }
 }