iOS开发中如何实现展示两条及以上Toast提示消息
iOS 多Toast/重复Toast展示实现方案
iOS完全可以实现两条及以上Toast的顺序展示,你当前基于通知分发Toast事件的逻辑本身没有问题,出现无法重复/多条展示的核心原因是:你使用的Toast展示层没有做队列管理,短时间多次触发展示时,新Toast会直接覆盖还没显示完的旧Toast,部分开源Toast组件还自带短时间相同内容去重逻辑,连续触发相同内容会被直接拦截,最终看起来只弹出了一次。
方案1:快速实现单条Toast固定展示两次
如果只是需要把当前这条错误提示固定展示两次,不需要兼容其他并发Toast场景,不要在发通知的地方连续调用两次post方法——这种写法基本都会被组件的去重逻辑拦截,最终还是只弹一次。
正确的实现是在第一次Toast完全消失的回调里,延迟一小段时间再触发第二次展示,示例代码如下:
// 你监听Toast通知的方法 @objc func handleToastNotification(_ noti: Notification) { guard let message = noti.userInfo?["toastMessage"] as? String else { return } // 第一次展示,传入展示完成回调 showToast(message: message, duration: 2.0) { [weak self] in // 第一次消失后延迟0.3秒再弹第二次,避免两条衔接太突兀 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self?.showToast(message: message, duration: 2.0) } } }
如果你当前用的Toast组件没有完成回调,可以直接用DispatchQueue.main.asyncAfter,延迟时长设为「Toast显示时长 + 间隔时长」,比如显示2秒、间隔0.3秒,就延迟2.3秒再触发第二次展示。
方案2:通用多Toast队列方案(支持任意数量Toast顺序展示)
如果后续可能出现短时间触发多条不同Toast的场景,直接给Toast展示层加一个串行队列即可,所有Toast按触发顺序逐条展示,不会出现覆盖、丢失的问题:
- 先给负责Toast展示的单例/UIWindow分类/根控制器添加两个私有属性:
// 待展示的Toast消息队列,存消息内容和显示时长 private var toastQueue: [(msg: String, duration: TimeInterval)] = [] // 标记当前是否有Toast正在展示,避免重复触发 private var isToastShowing = false
- 改造原有展示逻辑,所有Toast事件先入队,当前没有展示中的内容时才取出队列第一条展示:
// 所有触发Toast的入口都调用这个方法,包括通知监听里的逻辑 func addToastToQueue(message: String, duration: TimeInterval = 2.0) { DispatchQueue.main.async { [weak self] in guard let self = self else { return } // 新消息入队 self.toastQueue.append((message, duration)) // 当前没有正在展示的Toast,就启动队列展示 if !self.isToastShowing { self.showNextToastInQueue() } } } private func showNextToastInQueue() { // 队列为空时重置状态 guard !toastQueue.isEmpty else { isToastShowing = false return } isToastShowing = true let currentToast = toastQueue.removeFirst() // 调用你原有的Toast展示方法,在展示完成的回调里触发下一条 yourOriginalToastDisplayMethod( message: currentToast.msg, duration: currentToast.duration ) { [weak self] in // 两条Toast之间留0.3秒间隔,体验更自然 DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { self?.showNextToastInQueue() } } }
- 最后把原来通知监听方法里直接调用Toast展示的代码,替换为调用
addToastToQueue即可,不管是连续触发两次相同内容,还是短时间触发多条不同内容的Toast,都会按顺序依次展示。
内容的提问来源于stack exchange,提问作者SpH
相关产品推荐
相关产品推荐

