TextMediaMessageSizeCalculator.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. MIT License
  3. Copyright (c) 2017-2019 MessageKit
  4. Permission is hereby granted, free of charge, to any person obtaining a copy
  5. of this software and associated documentation files (the "Software"), to deal
  6. in the Software without restriction, including without limitation the rights
  7. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. copies of the Software, and to permit persons to whom the Software is
  9. furnished to do so, subject to the following conditions:
  10. The above copyright notice and this permission notice shall be included in all
  11. copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  18. SOFTWARE.
  19. */
  20. import Foundation
  21. import UIKit
  22. open class TextMediaMessageSizeCalculator: MessageSizeCalculator {
  23. public var incomingMessageLabelInsets = UIEdgeInsets(top: TextMediaMessageCell.insetTop,
  24. left: TextMediaMessageCell.insetHorizontalBig,
  25. bottom: TextMediaMessageCell.insetBottom,
  26. right: TextMediaMessageCell.insetHorizontalSmall)
  27. public var outgoingMessageLabelInsets = UIEdgeInsets(top: TextMediaMessageCell.insetTop,
  28. left: TextMediaMessageCell.insetHorizontalSmall,
  29. bottom: TextMediaMessageCell.insetBottom,
  30. right: TextMediaMessageCell.insetHorizontalBig)
  31. public var messageLabelFont = UIFont.preferredFont(forTextStyle: .body)
  32. internal func messageLabelInsets(for message: MessageType) -> UIEdgeInsets {
  33. let dataSource = messagesLayout.messagesDataSource
  34. let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
  35. return isFromCurrentSender ? outgoingMessageLabelInsets : incomingMessageLabelInsets
  36. }
  37. open override func messageContainerSize(for message: MessageType) -> CGSize {
  38. let maxImageWidth = messageContainerMaxWidth(for: message)
  39. let sizeForMediaItem = { (maxWidth: CGFloat, item: MediaItem) -> CGSize in
  40. let maxTextWidth = maxWidth - self.messageLabelInsets(for: message).horizontal
  41. var imageHeight = item.size.height
  42. var itemWidth = item.size.width
  43. if maxWidth < item.size.width {
  44. // Maintain the ratio if width is too great
  45. imageHeight = maxWidth * item.size.height / item.size.width
  46. itemWidth = maxWidth
  47. }
  48. var messageContainerSize = CGSize(width: itemWidth, height: imageHeight)
  49. switch message.kind {
  50. case .photoText(let mediaItem), .videoText(let mediaItem), .fileText(let mediaItem):
  51. if let text = mediaItem.text {
  52. let textHeight = text.height(withConstrainedWidth: maxTextWidth)
  53. messageContainerSize.height += textHeight
  54. messageContainerSize.height += self.messageLabelInsets(for: message).vertical
  55. }
  56. return messageContainerSize
  57. default:
  58. return messageContainerSize
  59. }
  60. }
  61. switch message.kind {
  62. case .photoText(let item), .videoText(let item), .fileText(let item):
  63. return sizeForMediaItem(maxImageWidth, item)
  64. default:
  65. fatalError("messageContainerSize received unhandled MessageDataType: \(message.kind)")
  66. }
  67. }
  68. open override func configure(attributes: UICollectionViewLayoutAttributes) {
  69. super.configure(attributes: attributes)
  70. guard let attributes = attributes as? MessagesCollectionViewLayoutAttributes else { return }
  71. let dataSource = messagesLayout.messagesDataSource
  72. let indexPath = attributes.indexPath
  73. let message = dataSource.messageForItem(at: indexPath, in: messagesLayout.messagesCollectionView)
  74. switch message.kind {
  75. case .photoText, .videoText, .fileText:
  76. attributes.messageLabelInsets = messageLabelInsets(for: message)
  77. attributes.messageLabelFont = messageLabelFont
  78. default:
  79. break
  80. }
  81. }
  82. }