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

Swift开发:如何通过点击按钮加载对应食谱信息到统一UIView?

当然可行!这绝对是高效且易维护的正确思路

完全没必要为25款食谱单独创建视图——这种重复工作既浪费时间,后期修改样式或者内容时也会让你崩溃。下面是具体的实现步骤,一步步来:

1. 先定义统一的食谱数据模型

首先创建一个Recipe结构体,把所有食谱需要的属性都封装进去,这样所有食谱数据都能统一管理:

import UIKit

struct Recipe {
    let id: String // 可选,用来唯一标识食谱
    let title: String
    let imageName: String // 假设图片放在Assets资源库中
    let ingredients: [String]
    let steps: [String]
}

然后你可以把所有食谱数据存在一个数组里,统一维护:

let allRecipes: [Recipe] = [
    Recipe(id: "1", title: "番茄炒蛋", imageName: "tomato_egg", ingredients: ["番茄2个", "鸡蛋3个", "盐少许"], steps: ["1. 鸡蛋打散炒熟盛出", "2. 番茄切块炒出汁", "3. 倒入鸡蛋翻炒加盐"]),
    // 剩下24个食谱依次添加...
]

2. 创建通用的详情视图控制器

在Storyboard里创建一个新的ViewController,作为你的食谱详情模板,添加需要的UI元素:

  • UIImageView:展示食谱图片
  • UILabel:展示食谱标题
  • UITextView(或者两个UILabel):分别展示食材和制作步骤

然后在这个详情控制器的代码里,定义一个用来接收数据的属性,再在viewDidLoad里填充UI:

import UIKit

class RecipeDetailViewController: UIViewController {
    // 关联Storyboard里的UI元素
    @IBOutlet weak var recipeImageView: UIImageView!
    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var ingredientsTextView: UITextView!
    @IBOutlet weak var stepsTextView: UITextView!
    
    // 用来接收传过来的食谱数据
    var selectedRecipe: Recipe!

    override func viewDidLoad() {
        super.viewDidLoad()
        // 填充UI内容
        titleLabel.text = selectedRecipe.title
        recipeImageView.image = UIImage(named: selectedRecipe.imageName)
        // 把食材数组转成带格式的字符串
        ingredientsTextView.text = "食材清单:\n" + selectedRecipe.ingredients.joined(separator: "\n")
        // 给步骤加上序号
        let formattedSteps = selectedRecipe.steps.enumerated().map { "步骤\($0.offset+1):\($0.element)" }.joined(separator: "\n")
        stepsTextView.text = "制作步骤:\n" + formattedSteps
    }
}

3. 处理按钮点击与Segue数据传递

回到你的按钮网格所在的控制器,这里有两种常见的方式传递数据:

方式一:利用按钮的tag值

给每个按钮设置tag,对应allRecipes数组里的索引(比如第一个按钮tag=0,对应第一个食谱),然后给所有按钮绑定同一个点击事件:

@IBAction func recipeButtonTapped(_ sender: UIButton) {
    let selectedRecipe = allRecipes[sender.tag]
    // 触发segue跳转
    performSegue(withIdentifier: "ShowRecipeDetail", sender: selectedRecipe)
}

然后实现prepare(for:sender:)方法,把数据传给详情控制器:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "ShowRecipeDetail" {
        guard let detailVC = segue.destination as? RecipeDetailViewController,
              let recipe = sender as? Recipe else { return }
        detailVC.selectedRecipe = recipe
    }
}

方式二:自定义Button关联Recipe对象

如果不想用tag(比如以后食谱顺序可能变动),可以自定义一个UIButton子类,直接关联Recipe:

class RecipeButton: UIButton {
    var recipe: Recipe!
}

然后在创建按钮的时候,给它赋值recipe属性,点击事件里直接取:

@IBAction func recipeButtonTapped(_ sender: RecipeButton) {
    performSegue(withIdentifier: "ShowRecipeDetail", sender: sender.recipe)
}

后续的prepare方法和方式一完全一致。

额外小提示

  • 记得在Storyboard里给Segue设置正确的identifier(比如上面的"ShowRecipeDetail")
  • 如果你的按钮网格是动态创建的,记得循环给每个按钮设置tag或者关联Recipe对象
  • 以后如果要修改详情页的样式,只需要改这一个通用视图就行,所有食谱都会同步更新,超级方便!

内容的提问来源于stack exchange,提问作者I. Daley

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:06:36