diff --git a/ElementX/Sources/Other/Pills/PillAttachmentViewProvider.swift b/ElementX/Sources/Other/Pills/PillAttachmentViewProvider.swift index 40c174a33..7ad0cb3b6 100644 --- a/ElementX/Sources/Other/Pills/PillAttachmentViewProvider.swift +++ b/ElementX/Sources/Other/Pills/PillAttachmentViewProvider.swift @@ -73,6 +73,7 @@ final class PillAttachmentViewProvider: NSTextAttachmentViewProvider { // This allows the text view to handle it as a link controller.view.isUserInteractionEnabled = false self.view = controller.view + textAttachment.view = controller.view delegate?.registerPillView(controller.view) } } diff --git a/ElementX/Sources/Other/Pills/PillConstants.swift b/ElementX/Sources/Other/Pills/PillConstants.swift index 9dbe25520..fb6e98e5a 100644 --- a/ElementX/Sources/Other/Pills/PillConstants.swift +++ b/ElementX/Sources/Other/Pills/PillConstants.swift @@ -24,4 +24,6 @@ enum PillConstants { /// Used by the WYSIWYG as the urlString value to identify @room mentions static let composerAtRoomURLString = "#" + + static let maxWidth: CGFloat = 235 } diff --git a/ElementX/Sources/Other/Pills/PillTextAttachment.swift b/ElementX/Sources/Other/Pills/PillTextAttachment.swift index a294e1919..42745b1ec 100644 --- a/ElementX/Sources/Other/Pills/PillTextAttachment.swift +++ b/ElementX/Sources/Other/Pills/PillTextAttachment.swift @@ -26,6 +26,7 @@ final class PillTextAttachment: NSTextAttachment { } private(set) var pillData: PillTextAttachmentData! + weak var view: UIView? private var lastBounds: CGRect? 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 { + var rect: CGRect if let 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 // Align the pill text vertically with the surrounding text. 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 return rect } diff --git a/ElementX/Sources/Other/Pills/PillView.swift b/ElementX/Sources/Other/Pills/PillView.swift index aa597d183..3d7509355 100644 --- a/ElementX/Sources/Other/Pills/PillView.swift +++ b/ElementX/Sources/Other/Pills/PillView.swift @@ -34,7 +34,6 @@ struct PillView: View { .padding(.vertical, 4) // for now design has defined no color so we will just use gray .background(Capsule().foregroundColor(context.viewState.isOwnMention ? .compound.bgCriticalPrimary : .gray)) - .frame(maxWidth: 235) .onChange(of: context.viewState.displayText) { _ in didChangeText() } @@ -53,9 +52,13 @@ struct PillView_Previews: PreviewProvider, TestablePreview { .previewDisplayName("Loading Own") PillView(imageProvider: mockMediaProvider, context: PillContext.mock(type: .loadedUser(isOwn: false))) { } + // To simulate the trimming that happens at UIKit level + .frame(maxWidth: PillConstants.maxWidth) .previewDisplayName("Loaded Long") PillView(imageProvider: mockMediaProvider, context: PillContext.mock(type: .loadedUser(isOwn: true))) { } + // To simulate the trimming that happens at UIKit level + .frame(maxWidth: PillConstants.maxWidth) .previewDisplayName("Loaded Long Own") PillView(imageProvider: mockMediaProvider, context: PillContext.mock(type: .allUsers)) { }