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

SwiftUI:带条件接收@Published值的自定义视图修饰符实现

自定义视图修饰符实现条件化监听@Published值变化

你可以通过自定义ViewModifier并扩展View,实现更紧凑的条件化监听逻辑,替代原有需要手动编写drop(while)的写法:

自定义修饰符实现

import SwiftUI

struct ConditionalOnReceiveModifier<Value, Content: View>: ViewModifier {
    let publisher: Published<Value>.Publisher
    let condition: Bool
    let action: (Value) -> Void
    
    func body(content: Content) -> some View {
        content
            .onReceive(publisher.filter { _ in condition }) { newValue in
                action(newValue)
            }
    }
}

extension View {
    func onReceive<P>(_ publisher: P, when condition: Bool, perform action: @escaping (P.Output) -> Void) -> some View where P: Publisher, P.Failure == Never {
        self.modifier(ConditionalOnReceiveModifier(
            publisher: publisher as! Published<P.Output>.Publisher,
            condition: condition,
            action: action
        ))
    }
}

使用方式

在视图中直接通过when参数指定激活条件,写法更简洁直观:

@State private var isActive = false
@EnvironmentObject var globalOO: GlobalOO

var body: some View {
    Text("示例视图")
        .onReceive(globalOO.$value, when: isActive) { newValue in
            // 仅当isActive为true时,处理新值
            print("收到新值:\(newValue)")
        }
}

原理说明

这个自定义修饰符内部通过filter操作符替代了drop(while),直接根据传入的condition布尔值判断是否触发回调。当condition动态变化时(比如绑定了@State、@Binding变量),SwiftUI会自动追踪其变化,实时调整监听的激活状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:00:00