You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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按触发顺序逐条展示,不会出现覆盖、丢失的问题:

  1. 先给负责Toast展示的单例/UIWindow分类/根控制器添加两个私有属性:
// 待展示的Toast消息队列,存消息内容和显示时长
private var toastQueue: [(msg: String, duration: TimeInterval)] = []
// 标记当前是否有Toast正在展示,避免重复触发
private var isToastShowing = false
  1. 改造原有展示逻辑,所有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()
        }
    }
}
  1. 最后把原来通知监听方法里直接调用Toast展示的代码,替换为调用addToastToQueue即可,不管是连续触发两次相同内容,还是短时间触发多条不同内容的Toast,都会按顺序依次展示。

内容的提问来源于stack exchange,提问作者SpH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:39:24