覆盖UIImage(named: )方法

6
我正在尝试重写UIImage类方法init(named:)。我的目标是能够检索图像的文件名。
代码应该如下所示:
class UIImageWithFileName: UIImage {

    let fileName: String

    override init(named:String){
        super.init(named)
    fileName = named
    }
}

这段代码似乎不可能实现,原因如下。
我创建了一个UIImage的子类,开始输入init...但令我惊讶的是,没有可以重写的init(named:)方法。这里是完整的init方法列表:

enter image description here

enter image description here

如何覆盖UIImage init(named:)
3个回答

3
原来"init(named:"是明确不可继承的。
如果查看UIImage的定义,你会看到这个:
public class UIImage : NSObject, NSSecureCoding, NSCoding {

    public /*not inherited*/ init?(named name: String) // load from main bundle

    @available(iOS 8.0, *)
    public /*not inherited*/ init?(named name: String, inBundle bundle: NSBundle?, compatibleWithTraitCollection traitCollection: UITraitCollection?)

这意味着你需要自行解决或打开文件,并将原始数据传递给超类。

1
我该如何在从文件中打开图像时使用资源目录? - potato
1
这个相关问题中有更多的信息。 "named"方法是Objective-C中的工厂方法,因此我猜想Swift中对应的init方法是为了方便而设计的。 - Michael Dautermann
1
为了获取Assets Catalog中的适当路径,您可以尝试使用此相关问题中的一个答案:https://dev59.com/P2Mk5IYBdhLWcg3wyw0U - Michael Dautermann
1
想出了一个解决方案。看一眼并告诉我你的想法。 - potato

1
这是一个解决方法:
class UIImageWithName: UIImage {

var fileName: String!

func ofFile(named:String) -> UIImageWithName?{
    let cgImage = UIImage(named: named)?.CGImage
    if let validName = cgImage{
        let image = UIImageWithName(CGImage: validName)
        image.fileName = named
        return image
    }
    return nil
}

}

不确定是否高效或有争议。请给予反馈。


0
我发现这个很好用。
class MyImage: UIImage {

    convenience init?(named name: String) {
        guard let image = UIImage(named: name),
            let cgImage = image.cgImage else {
                return nil
        }
        self.init(cgImage: cgImage)
    }

}

1
这可能远非安全。它甚至没有考虑图像方向。 - Sulthan
这个不行,它没有考虑到比例、方向和其他通常需要考虑的因素。 - Koen.

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