Pill Performance Improvement part 3 (#1908)

* pill performance improvement

* code improvement

* better doc
This commit is contained in:
Mauro
2023-10-16 16:43:35 +02:00
committed by GitHub
parent 6898419211
commit 0d72554e6f
4 changed files with 15 additions and 2 deletions
@@ -73,6 +73,7 @@ final class PillAttachmentViewProvider: NSTextAttachmentViewProvider {
// This allows the text view to handle it as a link // This allows the text view to handle it as a link
controller.view.isUserInteractionEnabled = false controller.view.isUserInteractionEnabled = false
self.view = controller.view self.view = controller.view
textAttachment.view = controller.view
delegate?.registerPillView(controller.view) delegate?.registerPillView(controller.view)
} }
} }
@@ -24,4 +24,6 @@ enum PillConstants {
/// Used by the WYSIWYG as the urlString value to identify @room mentions /// Used by the WYSIWYG as the urlString value to identify @room mentions
static let composerAtRoomURLString = "#" static let composerAtRoomURLString = "#"
static let maxWidth: CGFloat = 235
} }
@@ -26,6 +26,7 @@ final class PillTextAttachment: NSTextAttachment {
} }
private(set) var pillData: PillTextAttachmentData! private(set) var pillData: PillTextAttachmentData!
weak var view: UIView?
private var lastBounds: CGRect? private var lastBounds: CGRect?
func invalidateLastBounds() { func invalidateLastBounds() {
@@ -33,14 +34,20 @@ final class PillTextAttachment: NSTextAttachment {
} }
override func attachmentBounds(for textContainer: NSTextContainer?, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect { override func attachmentBounds(for textContainer: NSTextContainer?, proposedLineFragment lineFrag: CGRect, glyphPosition position: CGPoint, characterIndex charIndex: Int) -> CGRect {
var rect: CGRect
if let lastBounds { if let lastBounds {
return lastBounds return lastBounds
} else if let view {
rect = CGRect(origin: .zero, size: view.sizeThatFits(UIView.layoutFittingExpandedSize))
} else {
rect = super.attachmentBounds(for: textContainer, proposedLineFragment: lineFrag, glyphPosition: position, characterIndex: charIndex)
} }
var rect = super.attachmentBounds(for: textContainer, proposedLineFragment: lineFrag, glyphPosition: position, characterIndex: charIndex)
let fontData = pillData.fontData let fontData = pillData.fontData
// Align the pill text vertically with the surrounding text. // Align the pill text vertically with the surrounding text.
rect.origin.y = fontData.descender + (fontData.lineHeight - rect.height) / 2.0 rect.origin.y = fontData.descender + (fontData.lineHeight - rect.height) / 2.0
// Set the max width of the pill
rect.size.width = min(rect.size.width, PillConstants.maxWidth)
lastBounds = rect lastBounds = rect
return rect return rect
} }
+4 -1
View File
@@ -34,7 +34,6 @@ struct PillView: View {
.padding(.vertical, 4) .padding(.vertical, 4)
// for now design has defined no color so we will just use gray // for now design has defined no color so we will just use gray
.background(Capsule().foregroundColor(context.viewState.isOwnMention ? .compound.bgCriticalPrimary : .gray)) .background(Capsule().foregroundColor(context.viewState.isOwnMention ? .compound.bgCriticalPrimary : .gray))
.frame(maxWidth: 235)
.onChange(of: context.viewState.displayText) { _ in .onChange(of: context.viewState.displayText) { _ in
didChangeText() didChangeText()
} }
@@ -53,9 +52,13 @@ struct PillView_Previews: PreviewProvider, TestablePreview {
.previewDisplayName("Loading Own") .previewDisplayName("Loading Own")
PillView(imageProvider: mockMediaProvider, PillView(imageProvider: mockMediaProvider,
context: PillContext.mock(type: .loadedUser(isOwn: false))) { } context: PillContext.mock(type: .loadedUser(isOwn: false))) { }
// To simulate the trimming that happens at UIKit level
.frame(maxWidth: PillConstants.maxWidth)
.previewDisplayName("Loaded Long") .previewDisplayName("Loaded Long")
PillView(imageProvider: mockMediaProvider, PillView(imageProvider: mockMediaProvider,
context: PillContext.mock(type: .loadedUser(isOwn: true))) { } context: PillContext.mock(type: .loadedUser(isOwn: true))) { }
// To simulate the trimming that happens at UIKit level
.frame(maxWidth: PillConstants.maxWidth)
.previewDisplayName("Loaded Long Own") .previewDisplayName("Loaded Long Own")
PillView(imageProvider: mockMediaProvider, PillView(imageProvider: mockMediaProvider,
context: PillContext.mock(type: .allUsers)) { } context: PillContext.mock(type: .allUsers)) { }