React Native 不会在 iOS 上使用 UIFontDescriptor 和指定的设计,但你可以使用下一个运行时黑客技术 - “方法调整”来拦截对 UIFont 的系统调用并返回一个需要的,但它应该被实现在 ObjC 中。
只需将此 ObjC 代码添加到您的 XCode 项目中:
// UIFont+SystemDesign.m
#import <objc/runtime.h>
@implementation UIFont (SystemDesign)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = object_getClass((id)self);
SEL originalSelector = @selector(fontWithName:size:);
Method originalMethod = class_getClassMethod(class, originalSelector);
SEL swizzledSelector = @selector(_fontWithName:size:);
Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
}
else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
#pragma mark - Method Swizzling
+ (UIFont *)_fontWithName:(NSString *)fontName size:(CGFloat)fontSize {
NSString* const systemRounded = @"System-Rounded";
NSString* const systemSerif = @"System-Serif";
NSString* const systemMonospaced = @"System-Monospaced";
NSArray* fonts = @[systemRounded, systemSerif, systemMonospaced];
if ([fonts containsObject:fontName]) {
if (@available(iOS 13.0, *)) {
NSDictionary* designs = @{systemRounded : UIFontDescriptorSystemDesignRounded,
systemSerif : UIFontDescriptorSystemDesignSerif,
systemMonospaced : UIFontDescriptorSystemDesignMonospaced};
UIFontDescriptor *fontDescriptor = [UIFont systemFontOfSize:fontSize].fontDescriptor;
fontDescriptor = [fontDescriptor fontDescriptorWithDesign: designs[fontName]];
return [UIFont fontWithDescriptor:fontDescriptor size:fontSize];
}
else {
return [UIFont systemFontOfSize:fontSize];
}
}
return [self _fontWithName:fontName size:fontSize];
}
@end
然后你可以在你的 React Native 文件中使用“System-Rounded”、“System-Serif”和“System-Monospaced”字体:
export default function App() {
return (
<View style={styles.container}>
<Text style={styles.systemDefault}>Default</Text>
<Text style={styles.systemRounded}>Rounded</Text>
<Text style={styles.systemSerif}>Serif</Text>
<Text style={styles.systemMonospaced}>Monospaced</Text>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
systemDefault: {
fontFamily: 'System',
fontSize: 20,
},
systemRounded: {
fontFamily: 'System-Rounded',
fontSize: 20,
},
systemSerif: {
fontFamily: 'System-Serif',
fontSize: 20,
},
systemMonospaced: {
fontFamily: 'System-Monospaced',
fontSize: 20,
},
});