stop unnecessary layouts, resize container before setting text
This commit is contained in:
@@ -4,7 +4,9 @@ class ExpoUITextView: ExpoView {
|
|||||||
var textView: UITextView
|
var textView: UITextView
|
||||||
var textChildren: [ExpoUITextViewChild] = [] {
|
var textChildren: [ExpoUITextViewChild] = [] {
|
||||||
didSet {
|
didSet {
|
||||||
self.setText()
|
if textChildren != oldValue {
|
||||||
|
self.setText()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,8 +29,14 @@ class ExpoUITextView: ExpoView {
|
|||||||
textView.textContainerInset = UIEdgeInsets.zero
|
textView.textContainerInset = UIEdgeInsets.zero
|
||||||
textView.textContainer.lineFragmentPadding = 0
|
textView.textContainer.lineFragmentPadding = 0
|
||||||
|
|
||||||
super.init(appContext: appContext)
|
// Restrain to bounds
|
||||||
|
textView.clipsToBounds = true
|
||||||
|
|
||||||
|
super.init(appContext: appContext)
|
||||||
|
// Keep this view also within bounds
|
||||||
|
self.clipsToBounds = true
|
||||||
|
|
||||||
|
// Add the textview
|
||||||
addSubview(textView)
|
addSubview(textView)
|
||||||
|
|
||||||
// Configure the tap gesture recognizer
|
// Configure the tap gesture recognizer
|
||||||
@@ -58,7 +66,7 @@ class ExpoUITextView: ExpoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func didSetProps(_ changedProps: [String]!) {
|
override func didSetProps(_ changedProps: [String]!) {
|
||||||
self.getTextChildren()
|
self.setText()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just return the subviews
|
// Just return the subviews
|
||||||
@@ -68,7 +76,12 @@ class ExpoUITextView: ExpoView {
|
|||||||
|
|
||||||
// Get children on update
|
// Get children on update
|
||||||
override func didUpdateReactSubviews() {
|
override func didUpdateReactSubviews() {
|
||||||
self.getTextChildren()
|
self.updateChildren()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the text whenever the DynamicType size changes
|
||||||
|
@objc func preferredContentSizeChanged(_ notification: Notification) {
|
||||||
|
self.setText()
|
||||||
}
|
}
|
||||||
|
|
||||||
// For animation issues
|
// For animation issues
|
||||||
@@ -80,14 +93,11 @@ class ExpoUITextView: ExpoView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
// Get the width from the bounds
|
// Get the right size
|
||||||
let maxWidth = bounds.width
|
let height = textView.sizeThatFits(CGSize(width: bounds.width, height: CGFloat(MAXFLOAT))).height
|
||||||
// Calculate the size of the text
|
let size = CGSize(width: bounds.width, height: height)
|
||||||
let sizeThatFits = textView.sizeThatFits(CGSize(width: maxWidth, height: CGFloat(MAXFLOAT)))
|
|
||||||
let size = CGSize(width: maxWidth, height: sizeThatFits.height)
|
|
||||||
|
|
||||||
// Set the textview's frame
|
|
||||||
textView.frame.size = size
|
textView.frame.size = size
|
||||||
|
// Set the textview's frame
|
||||||
self.appContext?.reactBridge?.uiManager.setSize(size, for: self)
|
self.appContext?.reactBridge?.uiManager.setSize(size, for: self)
|
||||||
|
|
||||||
// Get each line and call onTextLayout
|
// Get each line and call onTextLayout
|
||||||
@@ -105,10 +115,6 @@ class ExpoUITextView: ExpoView {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func preferredContentSizeChanged(_ notification: Notification) {
|
|
||||||
self.setText()
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func callOnPress(_ sender: UITapGestureRecognizer) -> Void {
|
@IBAction func callOnPress(_ sender: UITapGestureRecognizer) -> Void {
|
||||||
// If we find a child, then call onPress
|
// If we find a child, then call onPress
|
||||||
if let child = getPressed(sender) {
|
if let child = getPressed(sender) {
|
||||||
@@ -121,6 +127,16 @@ class ExpoUITextView: ExpoView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the children. Always use getTextChildren() so that we ensure the correct order of views
|
||||||
|
func updateChildren() -> Void {
|
||||||
|
self.textChildren = self.reactSubviews().filter { view in
|
||||||
|
if view.isKind(of: ExpoUITextViewChild.self) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
} as! [ExpoUITextViewChild]
|
||||||
|
}
|
||||||
|
|
||||||
// Try to get the pressed segment
|
// Try to get the pressed segment
|
||||||
func getPressed(_ sender: UITapGestureRecognizer) -> ExpoUITextViewChild? {
|
func getPressed(_ sender: UITapGestureRecognizer) -> ExpoUITextViewChild? {
|
||||||
let layoutManager = textView.layoutManager
|
let layoutManager = textView.layoutManager
|
||||||
@@ -152,20 +168,6 @@ class ExpoUITextView: ExpoView {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the children. Always use getTextChildren() so that we ensure the correct order of views
|
|
||||||
func getTextChildren() -> Void {
|
|
||||||
var children: [ExpoUITextViewChild] = []
|
|
||||||
|
|
||||||
self.reactSubviews().forEach { view in
|
|
||||||
if view.isKind(of: ExpoUITextViewChild.self) {
|
|
||||||
children.append(view as! ExpoUITextViewChild)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the children for our onPress handler
|
|
||||||
self.textChildren = children
|
|
||||||
}
|
|
||||||
|
|
||||||
func setText() -> Void {
|
func setText() -> Void {
|
||||||
// Create an attributed string to store each of the segments
|
// Create an attributed string to store each of the segments
|
||||||
let finalAttributedString = NSMutableAttributedString()
|
let finalAttributedString = NSMutableAttributedString()
|
||||||
@@ -227,7 +229,6 @@ class ExpoUITextView: ExpoView {
|
|||||||
|
|
||||||
textView.attributedText = finalAttributedString
|
textView.attributedText = finalAttributedString
|
||||||
textView.selectedTextRange = nil
|
textView.selectedTextRange = nil
|
||||||
|
|
||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user