首页 > 解决方案 > 调用字符串扩展,包括从 Objective-C 用 Swift 编写的函数

问题描述

当 Swift 中的扩展只使用如下变量时:

 extension NSString   {
        var isNumber: Bool {
            return length > 0 && rangeOfCharacter(from: CharacterSet.decimalDigits.inverted).location == NSNotFound
        }
    }

我可以使用非常友好的语法从 Objective-C 调用它:

NSString *str = @"twelve";
BOOL isNumber = str.isNumber;  

但是,当扩展程序使用如下函数时,我在语法上苦苦挣扎:

extension String {
 func asImage(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize? = nil) -> UIImage? {
        let size = size ?? (self as NSString).size(attributes: attributes as! [String : Any])
        if #available(iOS 10.0, *) {
            return UIGraphicsImageRenderer(size: size).image { _ in
                (self as NSString).draw(in: CGRect(origin: .zero, size: size),
                                        withAttributes: attributes as! [String : Any])
            }
        } else {
            // Fallback on earlier versions
            return nil
        }
    }

这可以从 Swift 调用,只需:

 var image = "Hello World".asImage()

但我不知道如何从 Objective-C 调用它。

事实上,autotype 甚至无法识别 str.asImage 并且当我尝试各种事情时,它会导致我陷入错误的兔子洞并修复导致其他错误的问题。

我如何从 Objective-C 调用上述扩展?

标签: iosobjective-cswiftswift-extensions

解决方案


Swift 类、扩展或协议只有在可转换或用@objc.. 显式标记时才能在 Objective-C 中表示,这意味着它也要求所有参数也可转换为 Objective-C。

struct也不能被转换,所以我们只剩下类(IE:类和具体类的扩展)并且要标记一个类@objc,它必须继承NSObject

例子:

@objc
extension NSString {
    func asImage(withAttributes attributes: [NSAttributedString.Key: Any]? = nil, size: CGSize = .zero) -> UIImage? {
        let size = size == .zero ? self.size(withAttributes: attributes!) : size
       if #available(iOS 10.0, *) {
           return UIGraphicsImageRenderer(size: size).image { _ in
               self.draw(in: CGRect(origin: .zero, size: size),
                                       withAttributes: attributes!)
           }
       } else {
           // Fallback on earlier versions
           return nil
       }
   }
}

请注意,我将CGSize参数更改为非可选参数并与零进行比较。

另请注意,我标记了它@objc并将其更改为扩展名,NSString因为String它本身不能转换为 Objective-C,因为它是struct!

然后在 Objective-C 中你可以这样称呼它:

[str asImageWithAttributes:@{....} size:CGSizeZero];

或者你想要的任何参数..


推荐阅读