Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Using NSLayoutManager to calculate size
  • Loading branch information
zhongwuzw committed Sep 7, 2018
commit 99c9e3f26749cb40869303450c20b155fbd32417
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa

### Fixed

- Fixed `boundingRect(with:options:)` miscalculation of `MessageLabel` , like text `Ꮚ˘̴͈́ꈊ˘̴͈̀Ꮚ⋆✩`、`Tomorrow is the day`.
- Fixed `boundingRect(with:options:)` miscalculation of `MessageLabel` by using `NSLayoutManager`, like text `Ꮚ˘̴͈́ꈊ˘̴͈̀Ꮚ⋆✩`、`Tomorrow is the day`.
[#824](https://github.com/MessageKit/MessageKit/pull/824) by [@zhongwuzw](https://github.com/zhongwuzw).

### Changed
Expand Down
29 changes: 24 additions & 5 deletions Sources/Layout/MessageSizeCalculator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@

import Foundation

private let additionalWidthForBoundingRectCalculation: CGFloat = 5.0

open class MessageSizeCalculator: CellSizeCalculator {

public init(layout: MessagesCollectionViewFlowLayout? = nil) {
Expand All @@ -51,6 +49,23 @@ open class MessageSizeCalculator: CellSizeCalculator {

public var incomingMessageBottomLabelAlignment = LabelAlignment(textAlignment: .left, textInsets: UIEdgeInsets(left: 42))
public var outgoingMessageBottomLabelAlignment = LabelAlignment(textAlignment: .right, textInsets: UIEdgeInsets(right: 42))

private lazy var textContainer: NSTextContainer = {
let textContainer = NSTextContainer()
textContainer.maximumNumberOfLines = 0
textContainer.lineFragmentPadding = 0
return textContainer
}()
private lazy var layoutManager: NSLayoutManager = {
let layoutManager = NSLayoutManager()
layoutManager.addTextContainer(textContainer)
return layoutManager
}()
private lazy var textStorage: NSTextStorage = {
let textStorage = NSTextStorage()
textStorage.addLayoutManager(layoutManager)
return textStorage
}()

open override func configure(attributes: UICollectionViewLayoutAttributes) {
guard let attributes = attributes as? MessagesCollectionViewLayoutAttributes else { return }
Expand Down Expand Up @@ -217,10 +232,14 @@ open class MessageSizeCalculator: CellSizeCalculator {

internal func labelSize(for attributedText: NSAttributedString, considering maxWidth: CGFloat) -> CGSize {
let constraintBox = CGSize(width: maxWidth, height: .greatestFiniteMagnitude)
let rect = attributedText.boundingRect(with: constraintBox, options: [.usesLineFragmentOrigin, .usesFontLeading], context: nil).integral

// `boundingRect` method maybe not calculate correctly, like `Ꮚ˘̴͈́ꈊ˘̴͈̀Ꮚ⋆✩`, so we add 5 points to fix them temporary.
return CGSize(width: rect.width + additionalWidthForBoundingRectCalculation, height: rect.height)
textContainer.size = constraintBox
textStorage.replaceCharacters(in: NSRange(location: 0, length: textStorage.length), with: attributedText)
layoutManager.ensureLayout(for: textContainer)

let size = layoutManager.usedRect(for: textContainer).size

return CGSize(width: size.width.rounded(.up), height: size.height.rounded(.up))
}
}

Expand Down
2 changes: 1 addition & 1 deletion Sources/Views/MessageLabel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ open class MessageLabel: UILabel {
open override func drawText(in rect: CGRect) {

let insetRect = UIEdgeInsetsInsetRect(rect, textInsets)
textContainer.size = CGSize(width: insetRect.width, height: rect.height)
textContainer.size = CGSize(width: insetRect.width, height: insetRect.height)

let origin = insetRect.origin
let range = layoutManager.glyphRange(for: textContainer)
Expand Down