Skip to content

Commit

Permalink
Merge pull request #1054 from haoxiuwen/doc-v2
Browse files Browse the repository at this point in the history
Add a New Type of Custom Message Cell for iOS UIKit
  • Loading branch information
haoxiuwen authored Nov 25, 2024
2 parents de9a07f + d62cfa7 commit 1f09be8
Show file tree
Hide file tree
Showing 5 changed files with 232 additions and 1 deletion.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion docs/.vuepress/sidebar/uikit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,13 @@ const chatUikitSidebar = [
children: [
{ text: '主题', link: 'chatuikit_theme.html' },
{ text: '会话列表', link: 'chatuikit_custom_conversation_list.html' },
{ text: '消息', link: 'chatuikit_custom_chat.html' },
{ text: '消息',
collapsible: true,
children: [
{ text: '自定义聊天页面', link: 'chatuikit_custom_chat.html' },
{ text: '实现新类型自定义消息 Cell', link: 'chatuikit_custom_cell.html' }
],
},
{ text: '通讯录', link: 'chatuikit_custom_contact_list.html' },
{ text: '联系人详情', link: 'chatuikit_custom_contact_details.html' },
{ text: '群详情', link: 'chatuikit_custom_group_details.html' },
Expand Down
225 changes: 225 additions & 0 deletions docs/uikit/chatuikit/ios/chatuikit_custom_cell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# 实现新类型自定义消息 Cell

本文以红包消息为例介绍如何添加一种新类型的自定义消息 Cell。

1. 根据需求继承 `EaseChatUIKit` 中的自定义消息 Cell。

```Swift
import UIKit
import EaseChatUIKit

class RedPackageCell: CustomMessageCell {

override func createContent() -> UIView {
UIView(frame: self.contentView.bounds).backgroundColor(.clear).tag(bubbleTag).backgroundColor(.systemRed)
}

override func refresh(entity: MessageEntity) {
super.refresh(entity: entity)
}

//如果想让气泡尖角改颜色
override func updateAxis(entity: MessageEntity) {
super.updateAxis(entity: entity)
if Appearance.chat.bubbleStyle == .withArrow {
self.bubbleWithArrow.arrow.image = UIImage(named: self.towards == .left ? "arrow_left": "arrow_right", in: .chatBundle, with: nil)?.withTintColor(self.towards == .left ? .systemRed:.systemRed)
} else {
self.bubbleMultiCorners.backgroundColor = .systemRed
}
}
}

```

2. 根据需求继承 `EaseChatUIKit` 中的 Cell 的渲染模型 `MessageEntity`,并指定气泡大小,其中 `redPackageIdentifier` 为红包的自定义消息的 event事件。

```Swift
import UIKit
import EaseChatUIKit

final class MineMessageEntity: MessageEntity {

override func customSize() -> CGSize {
if let body = self.message.body as? ChatCustomMessageBody {
switch body.event {
case EaseChatUIKit_user_card_message:
return CGSize(width: self.historyMessage ? ScreenWidth-32:limitBubbleWidth, height: contactCardHeight)
case EaseChatUIKit_alert_message:
let label = UILabel().numberOfLines(0).lineBreakMode(.byWordWrapping)
label.attributedText = self.convertTextAttribute()
let size = label.sizeThatFits(CGSize(width: ScreenWidth-32, height: 9999))
return CGSize(width: ScreenWidth-32, height: size.height+50)
case redPackageIdentifier:
return CGSize(width: limitBubbleWidth, height: limitBubbleWidth*(5/3.0))
default:
return .zero
}

} else {
return .zero
}
}


}
```

3. 添加发送附件消息的类型。

例如,增加发送红包消息。

```Swift

let redPackage = ActionSheetItem(title: "红包".chat.localize, type: .normal,tag: "Red",image: UIImage(named: "photo", in: .chatBundle, with: nil))
Appearance.chat.inputExtendActions.append(redPackage)
```

4. 在继承的 `MessageListController` 处理新增的附件消息类型的点击。

```Swift
class CustomMessageListController: MessageListController {

override func handleAttachmentAction(item: any ActionSheetItemProtocol) {
switch item.tag {
case "File": self.selectFile()
case "Photo": self.selectPhoto()
case "Camera": self.openCamera()
case "Contact": self.selectContact()
case "Red": self.redPackageMessage()
default:
break
}
}

private func redPackageMessage() {
self.viewModel.sendRedPackageMessage()
}

}

let redPackageIdentifier = "redPackage"

```

![img](/images/uikit/chatuikit/ios/configurationitem/chat/red_package_attachment.png)

5.`EaseChatUIKit` 中的 `MessageListViewModel` 增加发送红包消息的方法。

```Swift
extension MessageListViewModel {
func sendRedPackageMessage() {
var ext = Dictionary<String,Any>()
ext["something"] = "发红包"
let json = EaseChatUIKitContext.shared?.currentUser?.toJsonObject() ?? [:]
ext.merge(json) { _, new in
new
}
let chatMessage = ChatMessage(conversationID: self.to, body: ChatCustomMessageBody(event: redPackageIdentifier, customExt: ["money": "20", "name": "张三","message": "恭喜发财大吉大利"]), ext: ext)
self.driver?.showMessage(message: chatMessage)
self.chatService?.send(message: chatMessage) { [weak self] error, message in
if error == nil {
if let message = message {
self?.driver?.updateMessageStatus(message: message, status: .succeed)
}
} else {
consoleLogInfo("send text message failure:\(error?.errorDescription ?? "")", type: .error)
if let message = message {
self?.driver?.updateMessageStatus(message: message, status: .failure)
}
}
}
}


}

```

![img](/images/uikit/chatuikit/ios/configurationitem/chat/red_package_send.png)

6. 将上述继承的对象初始化后,在 `EaseChatUIKit`中进行注册。

```Swift

ComponentsRegister.shared.MessageRenderEntity = MineMessageEntity.self
ComponentsRegister.shared.Conversation = MineConversationInfo.self
ComponentsRegister.shared.MessageViewController = CustomMessageListController.self
ComponentsRegister.shared.registerCustomizeCellClass(cellType: RedPackageCell.self)
```

- 这里 `ComponentsRegister.shared.Conversation = MineConversationInfo.self` 是为了修改自定义消息在会话列表中。会话收到新消息时显示的内容这里暂定为显示 "[红包]",示例代码如下,主要更改在非文本消息类型的 `else` 中根据自定义消息的 `event` 显示对应的内容。
```Swift
import UIKit
import EaseChatUIKit


final class MineConversationInfo: ConversationInfo {

override func contentAttribute() -> NSAttributedString {
guard let message = self.lastMessage else { return NSAttributedString() }
var text = NSMutableAttributedString()

let from = message.from
let mentionText = "Mentioned".chat.localize
let user = EaseChatUIKitContext.shared?.userCache?[from]
var nickName = user?.remark ?? ""
if nickName.isEmpty {
nickName = user?.nickname ?? ""
}
if nickName.isEmpty {
nickName = from
}
if message.body.type == .text {
var result = message.showType
for (key,value) in ChatEmojiConvertor.shared.oldEmojis {
result = result.replacingOccurrences(of: key, with: value)
}
text.append(NSAttributedString {
AttributedText(result).foregroundColor(Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5).font(UIFont.theme.bodyLarge)
})
let string = text.string as NSString
for symbol in ChatEmojiConvertor.shared.emojis {
if string.range(of: symbol).location != NSNotFound {
let ranges = text.string.chat.rangesOfString(symbol)
text = ChatEmojiConvertor.shared.convertEmoji(input: text, ranges: ranges, symbol: symbol,imageBounds: CGRect(x: 0, y: -3, width: 16, height: 16))
text.addAttribute(.font, value: UIFont.theme.bodyLarge, range: NSMakeRange(0, text.length))
text.addAttribute(.foregroundColor, value: Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5, range: NSMakeRange(0, text.length))
}
}
if self.mentioned {
let showText = NSMutableAttributedString {
AttributedText("[\(mentionText)] ").foregroundColor(Theme.style == .dark ? UIColor.theme.primaryColor6:UIColor.theme.primaryColor5).font(Font.theme.bodyMedium)
AttributedText(nickName + ": ").foregroundColor(Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5)
}

let show = NSMutableAttributedString(attributedString: text)
show.addAttribute(.foregroundColor, value: Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5, range: NSRange(location: 0, length: show.length))
show.addAttribute(.font, value: UIFont.theme.bodyMedium, range: NSRange(location: 0, length: show.length))
showText.append(show)
return showText
} else {
let showText = NSMutableAttributedString {
AttributedText(message.chatType != .chat ? nickName + ": ":"").foregroundColor(Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5).font(Font.theme.bodyMedium)
}
showText.append(text)
showText.addAttribute(.foregroundColor, value: Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor6, range: NSRange(location: 0, length: showText.length))
showText.addAttribute(.font, value: UIFont.theme.bodyMedium, range: NSRange(location: 0, length: showText.length))
return showText
}
} else {
var content = message.showContent
if let body = message.body as? ChatCustomMessageBody,body.event == redPackageIdentifier {
content = "[红包]"
}
let showText = NSMutableAttributedString {
AttributedText((message.chatType == .chat ? content:(nickName+":"+content))).foregroundColor(Theme.style == .dark ? UIColor.theme.neutralColor6:UIColor.theme.neutralColor5).font(UIFont.theme.bodyMedium)
}
return showText
}
}

}

```

![img](/images/uikit/chatuikit/ios/configurationitem/chat/red_package_receive.png)

0 comments on commit 1f09be8

Please sign in to comment.