🍇
【SwiftUI】英語フォントと日本語フォントを併用する
概要
- SwiftUIにおいて、英語フォントと日本語フォントを併用する方法を考えてみる
想定するケース
-
ヒラギノ角ゴシックで構成される日本語テキストとFuturaで構成される英語テキストの2種類から構成される文字列に、それぞれ異なるフォントを適用する。 - 使用するフォントはそれぞれ、
ヒラギノ角ゴシックとFuturaの2種類とする。
実装案 1)フォント指定を併用する
1-1. フォント指定の併用
- 英語フォントが日本語に対応しないことを利用して、英語→日本語の順番で
.fontモディファイアを2個連続で指定する。 - まず英語にフォントを指定して、その後日本語にフォントを適用する。
- 2個目の
.fontが全体に対してフォント情報をオーバーライドしていなければ問題なく行けるはず
1-2. 実装
Text("USBメモリ")
.font(.custom("Futura", size: 20))
Text("Wi-Fiスポット")
.font(.custom("HiraginoSans-W6", size: 20))
Text("COVID検査")
.font(.custom("Futura", size: 20))
.font(.custom("HiraginoSans-W6", size: 20))
1-3.結果
- 仮説通り、全て
ヒラギノ角ゴになってしまった。

<hr>
実装案 2)カスタムModifierを使用する
2-1. カスタムModifierを使う
- Textを分割して日本語と英語に区別する
- それをHStackでくっつければそれっぽくなるのでは。
2-2. 実装
/// 英語or数字か判定する
extension String {
var isAlphanumeric: Bool {
let range = "[a-zA-Z0-9]+"
return NSPredicate(format: "SELF MATCHES %@", range).evaluate(with: self)
}
}
/// Modifierの定義
struct CustomText: ViewModifier {
let contentText: String
func body(content: Content) -> some View {
let array_text = Array(contentText).map{String($0)}
return HStack(spacing: 0) {
ForEach(array_text, id: \.self) { item in
if item.isAlphanumeric == true {
Text(item)
.font(.custom("Futura", size: 20))
} else {
Text(item)
.font(.custom("HiraginoSans-W6", size: 20))
}
}
}
}
}
/// Viewを拡張して扱いやすくする
extension View {
func customText(_ text: String) -> some View {
self.modifier(CustomText(contentText: text))
}
}
/// Viewを定義する
Text("").modifier(CustomText(contentText: "COVID検査"))
2-3.結果
- 上手く実装できた。

注意
謝辞
-
isAlphaNumericのコードは下記からお借りしました。
Discussion