【SwiftUI】iOSで使用可能なフォント一覧

はじめに

アプリの開発中、ふと「iOSで使えるフォントってどんなものがあるんだろう?」と思ってググったところ、以下の素晴らしい記事に出会いました。
(大変参考になりました。ありがとうございます🙏)

Qiita – 「iOS のシステム内蔵フォント一覧」
https://qiita.com/lovee/items/6048bf780558517e72e6

当方、現在SwiftUIの勉強中なため、調べたついでにSwiftUI版にしてさらにフォントの選定に使えそうなものをと思い、作ってみました。

Xcode 11.3.1 で作成し、動作確認をしています。

こんな感じのやつ

ソース

import SwiftUI
import Combine
import UIKit

struct FontData: Identifiable {
    var id: String = UUID().uuidString
    var fontName: String
}

class FontListViewModel: ObservableObject {
    
    @Published var filterText = ""
    @Published var sampleText = "あア亜aA"
    @Published var fontSize: CGFloat = 16.0
    @Published var fonts: Array<FontData> = []

    var strFontSize: String {
        get {
            return String(format: "%.1f", Double(fontSize))
        }
    }

    private var allFonts: Array<FontData> = []
    private var cancellables: [AnyCancellable] = []
    
    init() {
        UIFont.familyNames.forEach {
            print("\($0)")
            UIFont.fontNames(forFamilyName: $0).forEach {
                print(" - \($0)")
                allFonts.append(FontData(fontName: $0))
            }
        }
        
        fonts = allFonts
        
        $filterText
            .collect(.byTime(DispatchQueue.global(), 1.0))
            .receive(on: DispatchQueue.main)
            .sink(receiveValue: { [weak self] value in
                guard let strongSelf = self else {
                    return
                }
                strongSelf.fonts = strongSelf.filterList(with: value.last!)
            })
            .store(in: &cancellables)
    }
    
    func filterList(with text: String) -> [FontData] {
        if text.count > 0 {
            return allFonts.filter {
                $0.fontName.range(of: text, options: .caseInsensitive) != nil
            }
        }
        else {
            return allFonts
        }
    }
}

struct FontListView: View {
    
    @ObservedObject var model: FontListViewModel
    
    var body: some View {
        VStack {
            VStack {
                HStack(alignment: .center, spacing: 8) {
                    Image(systemName: "magnifyingglass")
                        .frame(width: 32, height: 32)
                    TextField("Search", text: $model.filterText)
                }
                
                HStack(alignment: .center, spacing: 8) {
                    Image(systemName: "text.bubble")
                        .frame(width: 32, height: 32)
                    TextField("Sample", text: $model.sampleText)
                }
                
                HStack(alignment: .center, spacing: 8) {
                    Image(systemName: "textformat.size")
                        .frame(width: 32, height: 32)
                    Text(self.model.strFontSize)
                        .frame(width: 48, alignment: .center)
                    Slider(value: $model.fontSize, in: 5.0...50.0, step: 1.0)
                }
            }
            .padding(.horizontal, 16)

            List(model.fonts) {
                Text("\(self.model.sampleText) - \($0.fontName)")
                    .font(Font(UIFont(name: $0.fontName, size: self.model.fontSize)!))
            }
        }
    }
}

struct FontListView_Previews: PreviewProvider {
    static var previews: some View {
        FontListView(model: FontListViewModel())
    }
}

Githubにもアップしています。
https://github.com/hk2ndwalker/iOS/tree/master/SwiftUI/FontListView

おわりに

自分で画面デザインをやろうとすると、いかにデザイナーさんがありがたい存在であるかってことを実感しますね。

何かのお役に立てば幸いです。