Skip to content

Commit 56418d2

Browse files
committed
Add cellTopLabel and rename topLabel to messageTopLabel
1 parent b1314ec commit 56418d2

12 files changed

Lines changed: 161 additions & 138 deletions

Example/Sources/ConversationViewController.swift

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ internal class ConversationViewController: MessagesViewController {
3333
var messageList: [MockMessage] = []
3434

3535
var isTyping = false
36+
37+
lazy var formatter: DateFormatter = {
38+
let formatter = DateFormatter()
39+
formatter.dateStyle = .medium
40+
return formatter
41+
}()
3642

3743
override func viewDidLoad() {
3844
super.viewDidLoad()
@@ -266,18 +272,19 @@ extension ConversationViewController: MessagesDataSource {
266272
}
267273

268274
func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
275+
if indexPath.section % 3 == 0 {
276+
return NSAttributedString(string: MessageKitDateFormatter.shared.string(from: message.sentDate), attributes: [NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 10), NSAttributedStringKey.foregroundColor: UIColor.darkGray])
277+
}
278+
return nil
279+
}
280+
281+
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
269282
let name = message.sender.displayName
270283
return NSAttributedString(string: name, attributes: [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: .caption1)])
271284
}
272285

273286
func cellBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
274287

275-
let formatter: DateFormatter = {
276-
let formatter = DateFormatter()
277-
formatter.dateStyle = .medium
278-
return formatter
279-
}()
280-
281288
let dateString = formatter.string(from: message.sentDate)
282289
return NSAttributedString(string: dateString, attributes: [NSAttributedStringKey.font: UIFont.preferredFont(forTextStyle: .caption2)])
283290
}
@@ -352,16 +359,20 @@ extension ConversationViewController: MessagesDisplayDelegate {
352359
extension ConversationViewController: MessagesLayoutDelegate {
353360

354361
func cellTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
362+
if indexPath.section % 3 == 0 {
363+
return 10
364+
}
365+
return 0
366+
}
367+
368+
func messageTopLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
355369
return 16
356370
}
357371

358372
func cellBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
359373
return 16
360374
}
361375

362-
private func footerViewSize(for indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGSize {
363-
return CGSize(width: messagesCollectionView.bounds.width, height: 10)
364-
}
365376
}
366377

367378
// MARK: - MessageCellDelegate
@@ -376,8 +387,12 @@ extension ConversationViewController: MessageCellDelegate {
376387
print("Message tapped")
377388
}
378389

379-
func didTapTopLabel(in cell: MessageCollectionViewCell) {
380-
print("Top label tapped")
390+
func didTapCellTopLabel(in cell: MessageCollectionViewCell) {
391+
print("Top cell label tapped")
392+
}
393+
394+
func didTapMessageTopLabel(in cell: MessageCollectionViewCell) {
395+
print("Top message label tapped")
381396
}
382397

383398
func didTapBottomLabel(in cell: MessageCollectionViewCell) {

MessageKit.xcodeproj/project.pbxproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@
6060
B7A03F2C1F866895006AEF79 /* DetectorType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F211F866895006AEF79 /* DetectorType.swift */; };
6161
B7A03F2D1F866895006AEF79 /* LabelAlignment.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F221F866895006AEF79 /* LabelAlignment.swift */; };
6262
B7A03F2E1F866895006AEF79 /* MessageKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F231F866895006AEF79 /* MessageKind.swift */; };
63-
B7A03F331F866940006AEF79 /* MessageDateHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F301F866940006AEF79 /* MessageDateHeaderView.swift */; };
6463
B7A03F3A1F866946006AEF79 /* TextMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F361F866946006AEF79 /* TextMessageCell.swift */; };
6564
B7A03F3C1F866946006AEF79 /* LocationMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F381F866946006AEF79 /* LocationMessageCell.swift */; };
6665
B7A03F3D1F866946006AEF79 /* MediaMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B7A03F391F866946006AEF79 /* MediaMessageCell.swift */; };
@@ -168,7 +167,6 @@
168167
B7A03F211F866895006AEF79 /* DetectorType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetectorType.swift; sourceTree = "<group>"; };
169168
B7A03F221F866895006AEF79 /* LabelAlignment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelAlignment.swift; sourceTree = "<group>"; };
170169
B7A03F231F866895006AEF79 /* MessageKind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageKind.swift; sourceTree = "<group>"; };
171-
B7A03F301F866940006AEF79 /* MessageDateHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageDateHeaderView.swift; sourceTree = "<group>"; };
172170
B7A03F361F866946006AEF79 /* TextMessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextMessageCell.swift; sourceTree = "<group>"; };
173171
B7A03F381F866946006AEF79 /* LocationMessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationMessageCell.swift; sourceTree = "<group>"; };
174172
B7A03F391F866946006AEF79 /* MediaMessageCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MediaMessageCell.swift; sourceTree = "<group>"; };
@@ -244,7 +242,6 @@
244242
2EB618F11F846899007FBA0E /* Headers & Footers */ = {
245243
isa = PBXGroup;
246244
children = (
247-
B7A03F301F866940006AEF79 /* MessageDateHeaderView.swift */,
248245
1F6C040D206A2AF4007BDE44 /* MessageReusableView.swift */,
249246
);
250247
path = "Headers & Footers";
@@ -618,7 +615,6 @@
618615
1FCA6D30201C1CC900BC3480 /* UIEdgeInsets+Extensions.swift in Sources */,
619616
B7A03F3D1F866946006AEF79 /* MediaMessageCell.swift in Sources */,
620617
1FE783A220662905007FA024 /* TextMessageSizeCalculator.swift in Sources */,
621-
B7A03F331F866940006AEF79 /* MessageDateHeaderView.swift in Sources */,
622618
B7A03F2E1F866895006AEF79 /* MessageKind.swift in Sources */,
623619
B7A03F7B1F866B85006AEF79 /* MessageCollectionViewCell.swift in Sources */,
624620
B7A03F6B1F8669EB006AEF79 /* UIColor+Extensions.swift in Sources */,

Sources/Controllers/MessagesViewController.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
7777
setupDefaults()
7878
setupSubviews()
7979
setupConstraints()
80-
registerReusableViews()
8180
setupDelegates()
8281
addMenuControllerObservers()
8382
addObservers()
@@ -121,15 +120,6 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
121120
view.addSubview(messagesCollectionView)
122121
}
123122

124-
private func registerReusableViews() {
125-
messagesCollectionView.register(TextMessageCell.self)
126-
messagesCollectionView.register(MediaMessageCell.self)
127-
messagesCollectionView.register(LocationMessageCell.self)
128-
129-
messagesCollectionView.register(MessageReusableView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader)
130-
messagesCollectionView.register(MessageDateHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader)
131-
}
132-
133123
private func setupConstraints() {
134124
messagesCollectionView.translatesAutoresizingMaskIntoConstraints = false
135125

Sources/Layout/MessageSizeCalculator.swift

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ open class MessageSizeCalculator: CellSizeCalculator {
4141
public var incomingMessagePadding = UIEdgeInsets(top: 0, left: 4, bottom: 0, right: 30)
4242
public var outgoingMessagePadding = UIEdgeInsets(top: 0, left: 30, bottom: 0, right: 4)
4343

44-
public var incomingCellTopLabelAlignment = LabelAlignment(textAlignment: .left, textInsets: UIEdgeInsets(left: 42))
45-
public var outgoingCellTopLabelAlignment = LabelAlignment(textAlignment: .right, textInsets: UIEdgeInsets(right: 42))
44+
public var incomingMessageTopLabelAlignment = LabelAlignment(textAlignment: .left, textInsets: UIEdgeInsets(left: 42))
45+
public var outgoingMessageTopLabelAlignment = LabelAlignment(textAlignment: .right, textInsets: UIEdgeInsets(right: 42))
4646

4747
public var incomingCellBottomLabelAlignment = LabelAlignment(textAlignment: .left, textInsets: UIEdgeInsets(left: 42))
4848
public var outgoingCellBottomLabelAlignment = LabelAlignment(textAlignment: .right, textInsets: UIEdgeInsets(right: 42))
@@ -59,8 +59,9 @@ open class MessageSizeCalculator: CellSizeCalculator {
5959

6060
attributes.messageContainerPadding = messageContainerPadding(for: message)
6161
attributes.messageContainerSize = messageContainerSize(for: message)
62-
attributes.topLabelAlignment = cellTopLabelAlignment(for: message)
63-
attributes.topLabelSize = cellTopLabelSize(for: message, at: indexPath)
62+
attributes.cellTopLabelSize = cellTopLabelSize(for: message, at: indexPath)
63+
attributes.messageTopLabelSize = messageTopLabelSize(for: message, at: indexPath)
64+
attributes.messageTopLabelAlignment = messageTopLabelAlignment(for: message)
6465

6566
attributes.bottomLabelAlignment = cellBottomLabelAlignment(for: message)
6667
attributes.bottomLabelSize = cellBottomLabelSize(for: message, at: indexPath)
@@ -75,32 +76,20 @@ open class MessageSizeCalculator: CellSizeCalculator {
7576

7677
open func cellContentHeight(for message: MessageType, at indexPath: IndexPath) -> CGFloat {
7778

78-
let avatarVerticalPosition = avatarPosition(for: message).vertical
7979
let avatarHeight = avatarSize(for: message).height
8080
let messageContainerHeight = messageContainerSize(for: message).height
8181
let bottomLabelHeight = cellBottomLabelSize(for: message, at: indexPath).height
82-
let topLabelHeight = cellTopLabelSize(for: message, at: indexPath).height
82+
let cellTopLabelHeight = cellTopLabelSize(for: message, at: indexPath).height
83+
let messageTopLabelHeight = messageTopLabelSize(for: message, at: indexPath).height
8384
let messageVerticalPadding = messageContainerPadding(for: message).vertical
8485

8586
var cellHeight: CGFloat = 0
8687

87-
switch avatarVerticalPosition {
88-
case .cellTop:
89-
cellHeight += max(avatarHeight, topLabelHeight)
90-
cellHeight += bottomLabelHeight
91-
cellHeight += messageContainerHeight
92-
cellHeight += messageVerticalPadding
93-
case .cellBottom:
94-
cellHeight += max(avatarHeight, bottomLabelHeight)
95-
cellHeight += topLabelHeight
96-
cellHeight += messageContainerHeight
97-
cellHeight += messageVerticalPadding
98-
case .messageTop, .messageCenter, .messageBottom:
99-
cellHeight += max(avatarHeight, messageContainerHeight)
100-
cellHeight += messageVerticalPadding
101-
cellHeight += topLabelHeight
102-
cellHeight += bottomLabelHeight
103-
}
88+
cellHeight += max(avatarHeight, messageContainerHeight)
89+
cellHeight += messageVerticalPadding
90+
cellHeight += cellTopLabelHeight
91+
cellHeight += messageTopLabelHeight
92+
cellHeight += bottomLabelHeight
10493

10594
return cellHeight
10695
}
@@ -127,19 +116,28 @@ open class MessageSizeCalculator: CellSizeCalculator {
127116
return isFromCurrentSender ? outgoingAvatarSize : incomingAvatarSize
128117
}
129118

130-
// MARK: - Top Label
119+
// MARK: - Top cell Label
131120

132121
public func cellTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
133122
let layoutDelegate = messagesLayout.messagesLayoutDelegate
134123
let collectionView = messagesLayout.messagesCollectionView
135124
let height = layoutDelegate.cellTopLabelHeight(for: message, at: indexPath, in: collectionView)
136125
return CGSize(width: messagesLayout.itemWidth, height: height)
137126
}
138-
139-
public func cellTopLabelAlignment(for message: MessageType) -> LabelAlignment {
127+
128+
// MARK: - Top message Label
129+
130+
public func messageTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
131+
let layoutDelegate = messagesLayout.messagesLayoutDelegate
132+
let collectionView = messagesLayout.messagesCollectionView
133+
let height = layoutDelegate.messageTopLabelHeight(for: message, at: indexPath, in: collectionView)
134+
return CGSize(width: messagesLayout.itemWidth, height: height)
135+
}
136+
137+
public func messageTopLabelAlignment(for message: MessageType) -> LabelAlignment {
140138
let dataSource = messagesLayout.messagesDataSource
141139
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
142-
return isFromCurrentSender ? outgoingCellTopLabelAlignment : incomingCellTopLabelAlignment
140+
return isFromCurrentSender ? outgoingMessageTopLabelAlignment : incomingMessageTopLabelAlignment
143141
}
144142

145143
// MARK: - Bottom Label

Sources/Layout/MessagesCollectionViewLayoutAttributes.swift

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@ open class MessagesCollectionViewLayoutAttributes: UICollectionViewLayoutAttribu
3030
// MARK: - Properties
3131

3232
public var avatarSize: CGSize = .zero
33-
public var avatarPosition = AvatarPosition(vertical: .cellBottom)
33+
public var avatarPosition = AvatarPosition(vertical: .messageBottom)
3434

3535
public var messageContainerSize: CGSize = .zero
3636
public var messageContainerPadding: UIEdgeInsets = .zero
3737
public var messageLabelFont: UIFont = UIFont.preferredFont(forTextStyle: .body)
3838
public var messageLabelInsets: UIEdgeInsets = .zero
3939

40-
public var topLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero)
41-
public var topLabelSize: CGSize = .zero
40+
public var cellTopLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero)
41+
public var cellTopLabelSize: CGSize = .zero
42+
43+
public var messageTopLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero)
44+
public var messageTopLabelSize: CGSize = .zero
4245

4346
public var bottomLabelAlignment = LabelAlignment(textAlignment: .center, textInsets: .zero)
4447
public var bottomLabelSize: CGSize = .zero
@@ -54,8 +57,10 @@ open class MessagesCollectionViewLayoutAttributes: UICollectionViewLayoutAttribu
5457
copy.messageContainerPadding = messageContainerPadding
5558
copy.messageLabelFont = messageLabelFont
5659
copy.messageLabelInsets = messageLabelInsets
57-
copy.topLabelAlignment = topLabelAlignment
58-
copy.topLabelSize = topLabelSize
60+
copy.cellTopLabelAlignment = cellTopLabelAlignment
61+
copy.cellTopLabelSize = cellTopLabelSize
62+
copy.messageTopLabelAlignment = messageTopLabelAlignment
63+
copy.messageTopLabelSize = messageTopLabelSize
5964
copy.bottomLabelAlignment = bottomLabelAlignment
6065
copy.bottomLabelSize = bottomLabelSize
6166
return copy
@@ -66,15 +71,17 @@ open class MessagesCollectionViewLayoutAttributes: UICollectionViewLayoutAttribu
6671
// MARK: - LEAVE this as is
6772
if let attributes = object as? MessagesCollectionViewLayoutAttributes {
6873
return super.isEqual(object) && attributes.avatarSize == avatarSize
69-
&& attributes.avatarPosition == attributes.avatarPosition
70-
&& attributes.messageContainerSize == messageContainerSize
71-
&& attributes.messageContainerPadding == messageContainerPadding
72-
&& attributes.messageLabelFont == messageLabelFont
73-
&& attributes.messageLabelInsets == messageLabelInsets
74-
&& attributes.topLabelAlignment == topLabelAlignment
75-
&& attributes.topLabelSize == topLabelSize
76-
&& attributes.bottomLabelAlignment == bottomLabelAlignment
77-
&& attributes.bottomLabelSize == bottomLabelSize
74+
&& attributes.avatarPosition == attributes.avatarPosition
75+
&& attributes.messageContainerSize == messageContainerSize
76+
&& attributes.messageContainerPadding == messageContainerPadding
77+
&& attributes.messageLabelFont == messageLabelFont
78+
&& attributes.messageLabelInsets == messageLabelInsets
79+
&& attributes.cellTopLabelAlignment == cellTopLabelAlignment
80+
&& attributes.cellTopLabelSize == cellTopLabelSize
81+
&& attributes.messageTopLabelAlignment == messageTopLabelAlignment
82+
&& attributes.messageTopLabelSize == messageTopLabelSize
83+
&& attributes.bottomLabelAlignment == bottomLabelAlignment
84+
&& attributes.bottomLabelSize == bottomLabelSize
7885
} else {
7986
return false
8087
}

Sources/Models/AvatarPosition.swift

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,6 @@ public struct AvatarPosition {
4646
/// An enum representing the verical alignment for an `AvatarView`.
4747
public enum Vertical {
4848

49-
/// Aligns the `AvatarView`'s top edge to the cell's top edge.
50-
case cellTop
51-
52-
/// Aligns the `AvatarView`'s bottom edge to the cell's bottom edge.
53-
case cellBottom
54-
5549
/// Aligns the `AvatarView`'s top edge to the `MessageContainerView`'s top edge.
5650
case messageTop
5751

Sources/Protocols/MessageCellDelegate.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,17 @@ public protocol MessageCellDelegate: MessageLabelDelegate {
6666
/// You can get a reference to the `MessageType` for the cell by using `UICollectionView`'s
6767
/// `indexPath(for: cell)` method. Then using the returned `IndexPath` with the `MessagesDataSource`
6868
/// method `messageForItem(at:indexPath:messagesCollectionView)`.
69-
func didTapTopLabel(in cell: MessageCollectionViewCell)
69+
func didTapCellTopLabel(in cell: MessageCollectionViewCell)
70+
71+
/// Triggered when a tap occurs in the messageTopLabel.
72+
///
73+
/// - Parameters:
74+
/// - cell: The cell tap the touch occurred.
75+
///
76+
/// You can get a reference to the `MessageType` for the cell by using `UICollectionView`'s
77+
/// `indexPath(for: cell)` method. Then using the returned `IndexPath` with the `MessagesDataSource`
78+
/// method `messageForItem(at:indexPath:messagesCollectionView)`.
79+
func didTapMessageTopLabel(in cell: MessageCollectionViewCell)
7080

7181
}
7282

@@ -78,6 +88,7 @@ public extension MessageCellDelegate {
7888

7989
func didTapBottomLabel(in cell: MessageCollectionViewCell) {}
8090

81-
func didTapTopLabel(in cell: MessageCollectionViewCell) {}
91+
func didTapCellTopLabel(in cell: MessageCollectionViewCell) {}
8292

93+
func didTapMessageTopLabel(in cell: MessageCollectionViewCell) {}
8394
}

Sources/Protocols/MessagesDataSource.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,16 @@ public protocol MessagesDataSource: AnyObject {
7272
///
7373
/// The default value returned by this method is `nil`.
7474
func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
75+
76+
/// The attributed text to be used for message bubble's top label.
77+
///
78+
/// - Parameters:
79+
/// - message: The `MessageType` that will be displayed by this cell.
80+
/// - indexPath: The `IndexPath` of the cell.
81+
/// - messagesCollectionView: The `MessagesCollectionView` in which this cell will be displayed.
82+
///
83+
/// The default value returned by this method is `nil`.
84+
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
7585

7686
/// The attributed text to be used for cell's bottom label.
7787
///
@@ -98,6 +108,10 @@ public extension MessagesDataSource {
98108
func cellTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
99109
return nil
100110
}
111+
112+
func messageTopLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
113+
return nil
114+
}
101115

102116
func cellBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
103117
return nil

0 commit comments

Comments
 (0)