如何在 Swift 中覆盖 Objective-c 类函数?

Posted

技术标签:

【中文标题】如何在 Swift 中覆盖 Objective-c 类函数?【英文标题】:How to override Objective-c class functions in Swift? 【发布时间】:2016-01-04 09:40:55 【问题描述】:

我目前正在尝试覆盖 UIFont 的 systemFontOfSize 方法以返回具有给定字体大小的自定义字体。我的代码目前如下所示:

extension UIFont

    class func systemFontOfSize(fontSize: CGFloat) -> UIFont
    
        return UIFont(name: "HelveticaNeue", size: 10)!
    

但是,我无法覆盖该方法。使用上面显示的代码时,出现以下错误:

"Method 'systemFontOfSize' with Objective-C selector 'systemFontOfSize:' conflicts with previous declaration with the same Objective-C selector"

添加覆盖时,错误是该方法没有覆盖任何东西。 有谁知道如何解决这个问题?

【问题讨论】:

不能覆盖类extension中的方法,只能在子类中。 @MartinR 对不起,我同时做了同样的事情...... 【参考方案1】:

如果符合您的需要,您可以按如下方式使用 Objective C 扩展。

可以在此处找到与此技术相关的早期讨论以及我的源代码作为答案:Is there a way to change default font for your application。

您所要做的就是使用上面链接中提到的代码实现该类,并在您的伞头文件中包含以下头文件,以便能够在调用 Swift 代码中的方法时应用该代码。

头文件UIFont+Utils.h:

@interface UIFont (Utils)

+ (UIFont *)systemFontOfSize:(CGFloat)size;
+ (UIFont *)lightSystemFontOfSize:(CGFloat)size;
+ (UIFont *)boldSystemFontOfSize:(CGFloat)size;
+ (UIFont *)preferredFontForTextStyle:(NSString *)style;

@end

【讨论】:

【参考方案2】:

您可以使用#selectorUIFont 调用重定向到自定义函数。

有关如何为整个 ios 应用程序替换字体功能的最佳方法,请查看以下 SO 问题,寻找来自 - Javier Amor Penas 的答案:Set a default font for whole iOS app?

【讨论】:

【参考方案3】:

class FontClass: UIFont override class func systemFontOfSize(fontSize: CGFloat) -> UIFont return UIFont(name: "HelveticaNeue", size: 10)! 在项目中,你可以这样使用它: FontClass.systemFontOfSize(10) 希望能帮到你!

【讨论】:

可以轻松地将它与情节提要结合使用吗? 没问题!仍然感谢您的帮助:)【参考方案4】:

来自Apple's documentation 的扩展:

注意

扩展可以为类型添加新功能,但不能覆盖现有功能。

您不能覆盖扩展中的现有方法,只能添加新方法。

【讨论】:

如果有不同的方法来覆盖现有方法,以便它使用自定义字体来处理所有内容,包括放置在情节提要中的 tableview 标题和标签,那也很好。 您可以通过UIAppearance 执行此操作。请参阅this SO 问题或this article 该解决方案的问题在于它将所有内容的大小设置为相同的大小 否 :) 它只是将所有内容设置为我的字体而不是系统字体。代码基本上是这样的: + (UIFont *)systemFontOfSize:(CGFloat)fontSize return [UIFont fontWithName:[[AppTheme sharedInstance].fontFamilyName stringByAppendingString:@"-regular"] size:fontSize]; 【参考方案5】:

为了能够覆盖该函数,您必须首先继承 UIFont。你想做什么,是不可能的。您正在尝试重新定义扩展中的功能。所以,我没有正面的信息,但这是现实。

PS:如果你是 Objective C 的“专家”,可能会有一些 hack ...

【讨论】:

我担心可能是这种情况:( @user1945317 好的,您是否尝试检查 UIAppearance?使用 UIAppearance 协议获取类的外观代理。您可以通过向类的外观代理发送外观修改消息来自定义类实例的外观。

以上是关于如何在 Swift 中覆盖 Objective-c 类函数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中覆盖 Objective-c 类函数?

在objective-c或swift中覆盖pod文件方法的最佳实践是啥?

Swift getter 覆盖非计算变量

在 Swift 3 中覆盖 UIViewController 初始化

如何在 Swift 中调用 Objective-C 类别方法

Objective-C 观察者 - 如何在 Swift 中使用