如何在Swift的扩展中调用函数?

4

我正在制作一个应用程序,但我对如何在扩展文件中调用该函数感到困惑。

这是我试图从扩展中调用函数的代码。

import UIKit

class RecipeTableViewCell: UITableViewCell {

    @IBOutlet weak var commnetLabel: UILabel!
    @IBOutlet weak var recipeImageView: UIImageView!
    @IBOutlet weak var dateLabel: UILabel!
    @IBOutlet weak var recipeTypeLabel: UILabel!


    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }


    func configureView(recipe: RecipeData){
    
        commnetLabel.text = recipe.comment
        recipeImageView.setImage(imageUrl: recipe.imageUrl)
    //  dateLabel.text = recipe.recordedAt => get something like 2020-10-01 11:08:42

        dateLabel.text = setTemplate(strDate: recipe.recordedAt)
        recipeTypeLabel.text = recipe.recipeType

    }

}

在configureView函数中,我曾经写过dateLabel.text = recipe.recordedAt来向应用程序显示日期。现在我正在尝试更改其显示方式,因此我创建了一个扩展。
import Foundation

extension DateFormatter {

    func setTemplate (strDate: String) -> String {
    
    
        let dateFormatter = DateFormatter()
    
        dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "ydMMM", options: 0, locale: Locale(identifier: "ja_JP"))
    
        let result = dateFormatter.string(from: Date())
    
        return result
    }
}

我原以为在configureView函数中编写dateLabel.text = setTemplate(strDate: recipe.recordedAt)可以调用setTemplate函数并更改我的dateLabel的文本。但是,目前我收到了

未解决的标识符“setTemplate”的使用

我不明白为什么会出现这种情况,如何访问setTemplate函数。

有谁能告诉我为什么我会收到错误消息以及我做错了什么吗?

2个回答

4

你可能想要扩展 RecipeTableViewCell,而不是 DateFormatter

extension RecipeTableViewCell {
    func setTemplate(strDate: String) -> String {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "ydMMM", options: 0, locale: Locale(identifier: "ja_JP"))
        let result = dateFormatter.string(from: Date())
    
        return result
    }
}

如果您扩展了 `DateFormatter`,函数 `setTemplate` 将被添加到 `DateFormatter` 类中 -- 您无法从 `RecipeTableViewCell` 中访问它。但是如果您真的想要扩展 `DateFormatter`,可以按此方式进行:
extension DateFormatter {
    func setTemplate(strDate: String) -> String {
        self.dateFormat = DateFormatter.dateFormat(fromTemplate: "ydMMM", options: 0, locale: Locale(identifier: "ja_JP"))
        let result = self.string(from: Date())

        return result
    }
}

/// usage:
let formatter = DateFormatter()
dateLabel.text = formatter.setTemplate(strDate: recipe.recordedAt)

直接扩展DateFormatter可以让您从任何位置(而不仅仅是RecipeTableViewCell)访问setTemplate,因此您可能需要这样做。


1
非常感谢!我之前可能没有真正理解什么是扩展,但现在通过你的解释我明白了。我还有另一个问题。就像上面那个例子,你会使用扩展并编写一个方法(setTemplate),还是创建另一个类或结构体并在其中创建方法? - zzzzou
制作扩展要容易得多。当您需要存储数据时,类/结构更为适用(扩展不能包含存储的属性)。 - aheze

1

你的函数是正确的,但你需要将它变成静态的。我在 Playground 中测试过了,它可以工作。

extension DateFormatter {

 static func setTemplate (strDate: String) -> String {


    let dateFormatter = DateFormatter()

    dateFormatter.dateFormat = DateFormatter.dateFormat(fromTemplate: "ydMMM", options: 0, locale: Locale(identifier: "ja_JP"))

    let result = dateFormatter.string(from: Date())

    return result
 }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接