- 语音消息 显示

This commit is contained in:
linshujie 2026-06-05 18:29:32 +08:00
parent a2bde6e470
commit e849222272
13 changed files with 57 additions and 16 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -876,9 +876,14 @@ final class VoiceSendMsgCell: UITableViewCell {
return v return v
}() }()
private let playIcon: UIImageView = { private let playAnimation: LottieAnimationView = {
let iv = UIImageView(image: UIImage(named: "IM/video_send")) let v = LottieAnimationView()
return iv if let path = Bundle.main.path(forResource: "message_voice_play", ofType: "json") {
v.animation = LottieAnimation.filepath(path)
}
v.loopMode = .loop
v.contentMode = .scaleAspectFit
return v
}() }()
private let durationLabel: UILabel = { private let durationLabel: UILabel = {
@ -894,10 +899,13 @@ final class VoiceSendMsgCell: UITableViewCell {
backgroundColor = .clear backgroundColor = .clear
contentView.addSubview(timeLabel) contentView.addSubview(timeLabel)
contentView.addSubview(bubbleView) contentView.addSubview(bubbleView)
bubbleView.addSubview(playIcon) bubbleView.addSubview(playAnimation)
bubbleView.addSubview(durationLabel) bubbleView.addSubview(durationLabel)
contentView.addSubview(avatarView) contentView.addSubview(avatarView)
let tap = UITapGestureRecognizer(target: self, action: #selector(togglePlay))
bubbleView.addGestureRecognizer(tap)
timeLabel.layoutChain.top().centerX() timeLabel.layoutChain.top().centerX()
avatarView.layoutChain avatarView.layoutChain
.topToBottomOfView(timeLabel, offset: 14) .topToBottomOfView(timeLabel, offset: 14)
@ -908,13 +916,13 @@ final class VoiceSendMsgCell: UITableViewCell {
.rightToView(avatarView, offset: -13) .rightToView(avatarView, offset: -13)
.width(105).height(39).bottom(10) .width(105).height(39).bottom(10)
playIcon.layoutChain playAnimation.layoutChain
.right(36) .right(36)
.centerY() .centerY()
.width(11).height(15) .width(20).height(20)
durationLabel.layoutChain durationLabel.layoutChain
.leftToRightOfView(playIcon, offset: 8) .leftToRightOfView(playAnimation, offset: 4)
.centerY() .centerY()
} }
@ -930,6 +938,19 @@ final class VoiceSendMsgCell: UITableViewCell {
durationLabel.text = dur > 0 ? "\(dur)''" : "" durationLabel.text = dur > 0 ? "\(dur)''" : ""
} }
@objc private func togglePlay() {
if playAnimation.isAnimationPlaying {
playAnimation.stop()
} else {
playAnimation.play()
}
}
override func prepareForReuse() {
super.prepareForReuse()
playAnimation.stop()
}
private func formatTime(_ t: TimeInterval) -> String { private func formatTime(_ t: TimeInterval) -> String {
let date = Date(timeIntervalSince1970: t) let date = Date(timeIntervalSince1970: t)
let now = Date() let now = Date()
@ -941,7 +962,7 @@ final class VoiceSendMsgCell: UITableViewCell {
else { f.dateFormat = "yyyy-M-d HH:mm" } else { f.dateFormat = "yyyy-M-d HH:mm" }
return f.string(from: date) return f.string(from: date)
} }
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
bubbleView.setNeedsLayout() bubbleView.setNeedsLayout()
@ -987,9 +1008,14 @@ final class VoiceReceivedMsgCell: UITableViewCell {
return v return v
}() }()
private let playIcon: UIImageView = { private let playAnimation: LottieAnimationView = {
let iv = UIImageView(image: UIImage(named: "IM/video_received")) let v = LottieAnimationView()
return iv if let path = Bundle.main.path(forResource: "message_voice_play", ofType: "json") {
v.animation = LottieAnimation.filepath(path)
}
v.loopMode = .loop
v.contentMode = .scaleAspectFit
return v
}() }()
private let durationLabel: UILabel = { private let durationLabel: UILabel = {
@ -1005,10 +1031,12 @@ final class VoiceReceivedMsgCell: UITableViewCell {
backgroundColor = .clear backgroundColor = .clear
contentView.addSubview(timeLabel) contentView.addSubview(timeLabel)
contentView.addSubview(bubbleView) contentView.addSubview(bubbleView)
bubbleView.addSubview(playIcon) bubbleView.addSubview(playAnimation)
bubbleView.addSubview(durationLabel) bubbleView.addSubview(durationLabel)
contentView.addSubview(avatarView) contentView.addSubview(avatarView)
contentView.addSubview(nameLabel) contentView.addSubview(nameLabel)
let tap = UITapGestureRecognizer(target: self, action: #selector(togglePlay))
bubbleView.addGestureRecognizer(tap)
timeLabel.layoutChain.top().centerX() timeLabel.layoutChain.top().centerX()
@ -1029,13 +1057,13 @@ final class VoiceReceivedMsgCell: UITableViewCell {
.leftToRightOfView(avatarView, offset: 5) .leftToRightOfView(avatarView, offset: 5)
.bottomToView(avatarView) .bottomToView(avatarView)
playIcon.layoutChain playAnimation.layoutChain
.left(36) .left(36)
.centerY() .centerY()
.width(11).height(15) .width(20).height(20)
durationLabel.layoutChain durationLabel.layoutChain
.leftToRightOfView(playIcon, offset: 8) .leftToRightOfView(playAnimation, offset: 4)
.centerY() .centerY()
} }
@ -1052,6 +1080,19 @@ final class VoiceReceivedMsgCell: UITableViewCell {
durationLabel.text = dur > 0 ? "\(dur)''" : "" durationLabel.text = dur > 0 ? "\(dur)''" : ""
} }
@objc func togglePlay() {
if playAnimation.isAnimationPlaying {
playAnimation.stop()
} else {
playAnimation.play()
}
}
override func prepareForReuse() {
super.prepareForReuse()
playAnimation.stop()
}
private func formatTime(_ t: TimeInterval) -> String { private func formatTime(_ t: TimeInterval) -> String {
let date = Date(timeIntervalSince1970: t) let date = Date(timeIntervalSince1970: t)
let now = Date() let now = Date()