从 Objective-C 调用字符串扩展,包括用 Swift 编写的函数
Call String extension including function written in Swift from Objective-C
当 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 调用上述分机?
A Swift class、扩展或协议只能在 Objective-C 中表示,如果它是可转换的或明确标记为 @objc
.. 这意味着它需要所有参数也可以转换为 Objective-C。
struct
也无法转换,因此我们只剩下 classes(IE:classes 的扩展和具体的 classes)并标记一个class@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,因为它是 [=13] =]!
然后在Objective-C中你可以这样称呼它:
[str asImageWithAttributes:@{....} size:CGSizeZero];
或任何你想要的参数..
当 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 调用上述分机?
A Swift class、扩展或协议只能在 Objective-C 中表示,如果它是可转换的或明确标记为 @objc
.. 这意味着它需要所有参数也可以转换为 Objective-C。
struct
也无法转换,因此我们只剩下 classes(IE:classes 的扩展和具体的 classes)并标记一个class@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,因为它是 [=13] =]!
然后在Objective-C中你可以这样称呼它:
[str asImageWithAttributes:@{....} size:CGSizeZero];
或任何你想要的参数..