【问题标题】:Is it possible to use iOS 13 system fonts in React Native?是否可以在 React Native 中使用 iOS 13 系统字体?
【发布时间】:2020-01-19 03:06:48
【问题描述】:

我想在我的 React Native 应用程序中使用自 iOS 13 以来可用的新系统字体。特别是,我需要 roundedserifmonospaced 的。在本机端,它是使用 UIFontDescriptor.SystemDesign https://developer.apple.com/videos/play/wwdc2019/227/?time=142 完成的

在 React Native 方面,我们可以使用 { fontFamily: 'System' }StyleSheet,但它只提供默认的无衬线设计。

是否可以使用一些 Swift 代码来修改 Text 组件的字体描述符?或者我应该在 React Native 存储库中提交一个带有功能请求的问题?

【问题讨论】:

  • 您是要在 Android 上也使用它,还是只在您的 iOS 应用程序中使用它?您还可以分享一个满足这些要求的字体示例吗?

标签: ios swift react-native uifont typography


【解决方案1】:

您不能在 React Native 中指定系统字体的字体变体。您可以下载该字体并将其用作自定义字体。 [1]

我建议从 utils/primitives 文件中导出一个组件并将该组件的样式设置为使用自定义字体。

// Text.js
import {Text} from 'react-native'
export const Text = () => <Text style={{fontFamily: 'customFontFamily'}} />;



// App.js
import {View} from 'react-native'
import {Text} from './Text'

const App = () => {
return (
  <View>
    <Text>Hello World</Text>
  </View>
 )
}'

export default App;

[1]https://gist.github.com/parshap/cf9cf0388d55a044004e5e78fa317b39

【讨论】:

  • 我担心 Apple 在将其字体加载为自定义字体时可能会遇到问题?
  • 我不熟悉字体的授权。可直接从苹果下载developer.apple.com/fonts
【解决方案2】:

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,
  },
});

【讨论】:

  • 那么RN是如何创建和使用字体的呢?我想启用 OpenType 功能。调酒是唯一的方法吗?
  • @philk RN 使用 iOS SDK 来处理字体和合法的方式 - 使您的 RN Native 组件支持操作系统级别的功能或尝试找到现有的。
猜你喜欢
  • 1970-01-01
  • 2013-01-20
  • 1970-01-01
  • 1970-01-01
  • 2018-07-30
  • 2021-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多