ios - 调用字符串扩展,包括从 Objective-C 用 Swift 编写的函数

标签 ios objective-c swift swift-extensions

当 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 调用上述扩展?

最佳答案

如果 Swift 类、扩展或协议(protocol)可转换或用 @objc 显式标记,则只能用 Objective-C 表示。这意味着它要求所有参数都可转换为 Objective-C也是如此。

struct 也无法转换,因此我们只剩下类(即:类和具体类的扩展),并且要标记类 @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因为它是一个结构!

然后在 Objective-C 中你可以这样调用它:

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

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

关于ios - 调用字符串扩展,包括从 Objective-C 用 Swift 编写的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58423761/

相关文章:

swift 4 : Cannot assign value of type '(_) -> Void' to type '(() -> ())?'

ios - 裁剪要与GLKTextureLoader一起使用的UIImage

ios - UITextField 在输入数字的最后添加 3 个零阻止输入

ios - UITabBarControllerDelegate 的 shouldSelect 方法从未被调用

iphone - TableView :willDisplayHeaderView:inSection: not called when running for iOS 6. 1

ios - Apple-app-site-association 文件未链接到应用程序

ios - Xcode 5 IOS 7 错误 : failed to launch '/private/var/mobile/Applications/' -- NotFound

ios - UITableViewController 的静态内容消失了

objective-c - 左右两侧带有图像的 UIButton

ios - 如何在 Swift 中使用 Arkit 在图像上播放托管视频?