SwiftUI页面跳转传值全攻略:闭包 委托 通知中心实战对比
(拍桌子)哎!刚学SwiftUI的兄弟姐们儿是不是经常遇到这种状况?辛辛苦苦做好登录页面,点完按钮要跳转到主页了,突然发现——用户数据传不过去!急得直薅头发对吧?今天咱们就来掰扯清楚,这三种传值方式到底怎么玩转!
一、闭包传值:快餐式解决方案
先来说说最像外卖的传值方式。就像你点奶茶选加珍珠还是椰果,闭包特别适合??即用即走??的场景。比如说有个商品详情页,用户选完尺码要带回数据:
swift复制struct ProductView: View { @State private var selectedSize = "" var onSizeSelected: (String) -> Void var body: some View { Picker("选尺码", selection: $selectedSize) { ForEach(["S", "M", "L"], id: \.self) { size in Text(size) } } .onChange(of: selectedSize) { onSizeSelected($0) //就像外卖小哥送货上门 } } }
这时候主页面调用就像点外卖:
swift复制ProductView { newSize in print("用户选了\(newSize)码") }
??优点??在哪呢?就像用自拍杆拍照——伸手就能用!但(敲黑板)这里有个坑:要是没处理好内存,闭包可能变成狗皮膏药甩不掉,导致内存泄漏。记得用[weak self]
当护身符啊!
二、委托模式:老派但可靠
这就像去银行办业务,必须按流程走。比如说设置页要修改用户名,需要层层上报:
swift复制protocol UserNameDelegate { func didUpdateName(_ newName: String) } struct SettingsView: View { var delegate: UserNameDelegate? func saveButtonTapped() { delegate?.didUpdateName("王大明") //像给领导递报告 } }
在父视图里就得老老实实遵守协议:
swift复制struct ParentView: View, UserNameDelegate { func didUpdateName(_ newName: String) { //更新数据... } }
可能你会问:这都2023年了还用这么老派的方式?我跟你说啊,当遇到??复杂交互流程??时,委托模式就像导航地图,步骤清清楚楚。不过要注意别把协议设计得太庞大,不然就像行李箱塞太多东西,拎着费劲!
三、通知中心:广播大喇叭
这个最适合搞事情要让所有人都知道的场景。比如说切换夜间模式:
swift复制// 在主题切换按钮里 Button("夜间模式") { NotificationCenter.default.post( name: .themeChanged, object: nil, userInfo: ["isDarkMode": true] ) } // 在各个页面监听 .onReceive(NotificationCenter.default.publisher(for: .themeChanged)) { notification in if let isDark = notification.userInfo?["isDarkMode"] as? Bool { // 像小区广播通知领鸡蛋 } }
这时候可能有人要说了:"这不就是全局变量嘛?"哎您还别说,用好了真能省不少事!但(扶眼镜)得注意别滥用,要不然满屏幕都是通知,跟菜市场大妈吵架似的,维护起来要命!
四、三种方案怎么选?
(掏心窝子说)我刚开始学的时候也犯迷糊,后来总结了个土办法:
-
??看关系亲疏??:
- 父子视图 → 闭包(直接)
- 远房亲戚视图 → 委托(正式)
- 八竿子打不着的 → 通知(广播)
-
??看数据流向??:
- 像寄快递(单向)用闭包
- 要回执单(双向)用委托
- 全村通知用广播
-
??看业务复杂度??:
- 简单需求:闭包完事
- 正经业务:委托规范
- 全局状态:通知安排
有次做电商项目,购物车数量同步就栽过跟头。开始用闭包传,结果不同页面数据对不上,后来换成通知中心才搞定,就跟疏通下水道似的,哗啦一下全通了!
(点烟沉思状)最后说点真心话:别被各种模式吓住,关键看实际需求。就像炒菜,该用铁锅用铁锅,该用砂锅用砂锅。新手最容易犯的错就是——手里拿着锤子,看啥都像钉子。多写几个demo试试手感,比死记概念强百倍!