SwiftUI点击Randomize按钮如何每次从restaurantList获取新随机值?
问题原因
你当前的代码中,随机索引的计算逻辑是在body渲染构建NavigationLink时就完成的,后续只要body没有触发重新渲染,这个随机值就不会更新,所以每次点击跳转都是同一个餐厅。
修复方案
方案1:适配iOS 16+(推荐)
使用NavigationStack配合navigationDestination,点击按钮时才生成随机值触发跳转:
struct RandomizeTab: View { var restaurantInfo = Restaurants() // 存储选中的餐厅,类型替换为你定义的Restaurant模型类型 @State private var selectedRestaurant: Restaurant? var body: some View { NavigationStack { Button { // 点击时才计算随机索引 guard !restaurantInfo.restaurantList.isEmpty else { return } let randomIndex = Int.random(in: 0..<restaurantInfo.restaurantList.count) selectedRestaurant = restaurantInfo.restaurantList[randomIndex] } label: { Text("Randomize") .font(.title3) .fontWeight(.bold) .padding() .background(Color.red) .foregroundColor(.white) .clipShape(Capsule()) } .navigationDestination(item: $selectedRestaurant) { restaurant in DetailView(restaurantInfo: restaurant) } } } }
方案2:兼容iOS 15及更早版本
使用NavigationView配合绑定跳转状态的隐藏NavigationLink实现:
struct RandomizeTab: View { var restaurantInfo = Restaurants() // 类型替换为你定义的Restaurant模型类型 @State private var randomRestaurant: Restaurant? @State private var isJumpToDetail = false var body: some View { NavigationView { VStack { Button { // 点击时才计算随机索引 guard !restaurantInfo.restaurantList.isEmpty else { return } let randomIndex = Int.random(in: 0..<restaurantInfo.restaurantList.count) randomRestaurant = restaurantInfo.restaurantList[randomIndex] isJumpToDetail = true } label: { Text("Randomize") .font(.title3) .fontWeight(.bold) .padding() .background(Color.red) .foregroundColor(.white) .clipShape(Capsule()) } // 隐藏的跳转入口,由状态控制触发 NavigationLink(isActive: $isJumpToDetail) { if let restaurant = randomRestaurant { DetailView(restaurantInfo: restaurant) } } label: { EmptyView() } } } } }
额外优化建议
使用0..<restaurantInfo.restaurantList.count代替原来的0...restaurantInfo.restaurantList.count-1,可以避免数组为空时出现索引范围错误,代码里已经加了数组非空判断,你可以根据需要补充空数组时的提示逻辑。
内容的提问来源于stack exchange,提问作者sadel
相关产品推荐
相关产品推荐

