From b14da73178febb9709396d740adbd4bda69d6294 Mon Sep 17 00:00:00 2001 From: brunoantoninho Date: Mon, 10 Oct 2022 18:32:11 +0100 Subject: [PATCH 1/3] Implemented scale font size if large text option enabled in the device accessibility settings --- Sources/Views/Cells/MessageContentCell.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/Views/Cells/MessageContentCell.swift b/Sources/Views/Cells/MessageContentCell.swift index 034180d5a..1a1c43d89 100644 --- a/Sources/Views/Cells/MessageContentCell.swift +++ b/Sources/Views/Cells/MessageContentCell.swift @@ -56,6 +56,7 @@ open class MessageContentCell: MessageCollectionViewCell { open var cellTopLabel: InsetLabel = { let label = InsetLabel() label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true label.textAlignment = .center return label }() @@ -64,6 +65,7 @@ open class MessageContentCell: MessageCollectionViewCell { open var cellBottomLabel: InsetLabel = { let label = InsetLabel() label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true label.textAlignment = .center return label }() @@ -72,6 +74,7 @@ open class MessageContentCell: MessageCollectionViewCell { open var messageTopLabel: InsetLabel = { let label = InsetLabel() label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true return label }() @@ -79,6 +82,7 @@ open class MessageContentCell: MessageCollectionViewCell { open var messageBottomLabel: InsetLabel = { let label = InsetLabel() label.numberOfLines = 0 + label.adjustsFontForContentSizeCategory = true return label }() From fe104ad94ed04dce7775085903892d49f5cd061e Mon Sep 17 00:00:00 2001 From: brunoantoninho Date: Tue, 11 Oct 2022 11:06:50 +0100 Subject: [PATCH 2/3] Updated InputBarAccessoryView dependency --- Example/ChatExample.xcodeproj/project.pbxproj | 17 +++++++++++++++++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++++++++ Package.swift | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 Example/ChatExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/Example/ChatExample.xcodeproj/project.pbxproj b/Example/ChatExample.xcodeproj/project.pbxproj index 98d7293e3..d318d9b59 100644 --- a/Example/ChatExample.xcodeproj/project.pbxproj +++ b/Example/ChatExample.xcodeproj/project.pbxproj @@ -49,6 +49,7 @@ 9B49D53A263D9606008804B5 /* CustomLayoutSizeCalculator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B49D539263D9606008804B5 /* CustomLayoutSizeCalculator.swift */; }; 9B49D542263DA6F9008804B5 /* CustomMessageContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B49D541263DA6F9008804B5 /* CustomMessageContentCell.swift */; }; 9B49D547263DAA29008804B5 /* CustomTextMessageContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B49D546263DAA29008804B5 /* CustomTextMessageContentCell.swift */; }; + ABCBBB1428F57513008955E4 /* InputBarAccessoryView in Frameworks */ = {isa = PBXBuildFile; productRef = ABCBBB1328F57513008955E4 /* InputBarAccessoryView */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -124,6 +125,7 @@ buildActionMask = 2147483647; files = ( 13EFA5D927AC5634003002CC /* Kingfisher in Frameworks */, + ABCBBB1428F57513008955E4 /* InputBarAccessoryView in Frameworks */, 1C5433DF24C38DBF00A5383B /* SwiftUI.framework in Frameworks */, 13EFA5D727AC5631003002CC /* MessageKit in Frameworks */, ); @@ -350,6 +352,7 @@ packageProductDependencies = ( 13EFA5D627AC5631003002CC /* MessageKit */, 13EFA5D827AC5634003002CC /* Kingfisher */, + ABCBBB1328F57513008955E4 /* InputBarAccessoryView */, ); productName = ChatExample; productReference = 882B5E331CF7D4B900B6E160 /* ChatExample.app */; @@ -427,6 +430,7 @@ mainGroup = 882B5E2A1CF7D4B900B6E160; packageReferences = ( 13CCA06125793E24005C19BB /* XCRemoteSwiftPackageReference "Kingfisher" */, + ABCBBB1228F57513008955E4 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */, ); productRefGroup = 882B5E341CF7D4B900B6E160 /* Products */; projectDirPath = ""; @@ -837,6 +841,14 @@ minimumVersion = 5.15.8; }; }; + ABCBBB1228F57513008955E4 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/deemaze/InputBarAccessoryView.git"; + requirement = { + branch = "custom-attachment-cell"; + kind = branch; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -858,6 +870,11 @@ package = 13CCA06125793E24005C19BB /* XCRemoteSwiftPackageReference "Kingfisher" */; productName = Kingfisher; }; + ABCBBB1328F57513008955E4 /* InputBarAccessoryView */ = { + isa = XCSwiftPackageProductDependency; + package = ABCBBB1228F57513008955E4 /* XCRemoteSwiftPackageReference "InputBarAccessoryView" */; + productName = InputBarAccessoryView; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 882B5E2B1CF7D4B900B6E160 /* Project object */; diff --git a/Example/ChatExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/Example/ChatExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000..f9b0d7c5e --- /dev/null +++ b/Example/ChatExample.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/Package.swift b/Package.swift index 1a585e1d1..a35b61494 100644 --- a/Package.swift +++ b/Package.swift @@ -31,7 +31,7 @@ let package = Package( .plugin(name: "SwiftFormatPlugin", targets: ["SwiftFormatPlugin"]), ], dependencies: [ - .package(url: "https://github.com/nathantannar4/InputBarAccessoryView", .upToNextMajor(from: "6.1.0")), + .package(url: "https://github.com/deemaze/InputBarAccessoryView", branch: "custom-attachment-cell") ], targets: [ // MARK: - MessageKit From 4dea9609eaebf4102b0006328971d179117c5fe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Oliveira?= Date: Thu, 9 Oct 2025 17:15:38 +0100 Subject: [PATCH 3/3] Add RTL language support for message positioning Implements RTLLanguageProvider protocol to enable automatic message bubble positioning for RTL languages (Hebrew, Arabic, etc.). When RTL mode is active, outgoing messages appear on the left and incoming on the right. Related: NOA-832 --- Sources/Layout/MessageSizeCalculator.swift | 73 +++++++++++++++++++--- Sources/Views/MessagesCollectionView.swift | 8 +++ 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/Sources/Layout/MessageSizeCalculator.swift b/Sources/Layout/MessageSizeCalculator.swift index 1d9065c9e..da74bfa1d 100644 --- a/Sources/Layout/MessageSizeCalculator.swift +++ b/Sources/Layout/MessageSizeCalculator.swift @@ -123,13 +123,27 @@ open class MessageSizeCalculator: CellSizeCalculator { open func avatarPosition(for message: MessageType) -> AvatarPosition { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - var position = isFromCurrentSender ? outgoingAvatarPosition : incomingAvatarPosition + + // Check if RTL mode is active + let isRTL = messagesLayout.messagesCollectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing positions + var position: AvatarPosition + if isRTL { + position = isFromCurrentSender ? incomingAvatarPosition : outgoingAvatarPosition + } else { + position = isFromCurrentSender ? outgoingAvatarPosition : incomingAvatarPosition + } switch position.horizontal { case .cellTrailing, .cellLeading: break case .natural: - position.horizontal = isFromCurrentSender ? .cellTrailing : .cellLeading + if isRTL { + position.horizontal = isFromCurrentSender ? .cellLeading : .cellTrailing + } else { + position.horizontal = isFromCurrentSender ? .cellTrailing : .cellLeading + } } return position } @@ -157,7 +171,16 @@ open class MessageSizeCalculator: CellSizeCalculator { open func cellTopLabelAlignment(for message: MessageType) -> LabelAlignment { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - return isFromCurrentSender ? outgoingCellTopLabelAlignment : incomingCellTopLabelAlignment + + // Check if RTL mode is active + let isRTL = messagesLayout.messagesCollectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing alignments + if isRTL { + return isFromCurrentSender ? incomingCellTopLabelAlignment : outgoingCellTopLabelAlignment + } else { + return isFromCurrentSender ? outgoingCellTopLabelAlignment : incomingCellTopLabelAlignment + } } // MARK: - Top message Label @@ -179,7 +202,16 @@ open class MessageSizeCalculator: CellSizeCalculator { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - return isFromCurrentSender ? outgoingMessageTopLabelAlignment : incomingMessageTopLabelAlignment + + // Check if RTL mode is active + let isRTL = collectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing alignments + if isRTL { + return isFromCurrentSender ? incomingMessageTopLabelAlignment : outgoingMessageTopLabelAlignment + } else { + return isFromCurrentSender ? outgoingMessageTopLabelAlignment : incomingMessageTopLabelAlignment + } } // MARK: - Message time label @@ -205,7 +237,16 @@ open class MessageSizeCalculator: CellSizeCalculator { open func cellBottomLabelAlignment(for message: MessageType) -> LabelAlignment { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - return isFromCurrentSender ? outgoingCellBottomLabelAlignment : incomingCellBottomLabelAlignment + + // Check if RTL mode is active + let isRTL = messagesLayout.messagesCollectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing alignments + if isRTL { + return isFromCurrentSender ? incomingCellBottomLabelAlignment : outgoingCellBottomLabelAlignment + } else { + return isFromCurrentSender ? outgoingCellBottomLabelAlignment : incomingCellBottomLabelAlignment + } } // MARK: - Bottom Message Label @@ -227,7 +268,16 @@ open class MessageSizeCalculator: CellSizeCalculator { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - return isFromCurrentSender ? outgoingMessageBottomLabelAlignment : incomingMessageBottomLabelAlignment + + // Check if RTL mode is active + let isRTL = collectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing alignments + if isRTL { + return isFromCurrentSender ? incomingMessageBottomLabelAlignment : outgoingMessageBottomLabelAlignment + } else { + return isFromCurrentSender ? outgoingMessageBottomLabelAlignment : incomingMessageBottomLabelAlignment + } } // MARK: - MessageContainer @@ -235,7 +285,16 @@ open class MessageSizeCalculator: CellSizeCalculator { open func messageContainerPadding(for message: MessageType) -> UIEdgeInsets { let dataSource = messagesLayout.messagesDataSource let isFromCurrentSender = dataSource.isFromCurrentSender(message: message) - return isFromCurrentSender ? outgoingMessagePadding : incomingMessagePadding + + // Check if RTL mode is active + let isRTL = messagesLayout.messagesCollectionView.rtlLanguageProvider?.isRTLLanguage ?? false + + // In RTL, swap incoming/outgoing paddings + if isRTL { + return isFromCurrentSender ? incomingMessagePadding : outgoingMessagePadding + } else { + return isFromCurrentSender ? outgoingMessagePadding : incomingMessagePadding + } } open func messageContainerSize(for _: MessageType, at _: IndexPath) -> CGSize { diff --git a/Sources/Views/MessagesCollectionView.swift b/Sources/Views/MessagesCollectionView.swift index a551ef2f9..afe2d1e2c 100644 --- a/Sources/Views/MessagesCollectionView.swift +++ b/Sources/Views/MessagesCollectionView.swift @@ -23,6 +23,12 @@ import Foundation import UIKit +/// Protocol to provide RTL (Right-to-Left) language support for MessageKit +public protocol RTLLanguageProvider: AnyObject { + /// Returns `true` if the current language is RTL (Right-to-Left) + var isRTLLanguage: Bool { get } +} + open class MessagesCollectionView: UICollectionView { // MARK: Lifecycle @@ -55,6 +61,8 @@ open class MessagesCollectionView: UICollectionView { open weak var messageCellDelegate: MessageCellDelegate? + open weak var rtlLanguageProvider: RTLLanguageProvider? + open var isTypingIndicatorHidden: Bool { messagesCollectionViewFlowLayout.isTypingIndicatorViewHidden }