The default font seems to be .AppleSystemUIFont
based on UIFont.preferredFont(forTextStyle: .body).familyName
. How can it be selected in a UIFontPickerViewController
so that users can revert back to the original default font?
import SwiftUI
class FontPickerViewController: UIViewController, UIFontPickerViewControllerDelegate {
var isPickerPresented: Binding<Bool>?
var onFontPick: ((UIFontDescriptor) -> Void)?
override func loadView() {
super.loadView()
let button = UIButton(type: .system)
button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
button.setTitle("Choose font", for: .normal)
button.addTarget(self, action: #selector(showFontPicker), for: .touchUpInside)
button.sizeToFit()
button.backgroundColor = .clear
view = button
}
func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
dismiss(animated: true)
isPickerPresented?.wrappedValue = false
guard let fontDescriptor = viewController.selectedFontDescriptor else { return }
onFontPick?(fontDescriptor)
}
func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
dismiss(animated: true)
isPickerPresented?.wrappedValue = false
}
@objc func showFontPicker() {
let configuration = UIFontPickerViewController.Configuration()
configuration.includeFaces = true
configuration.displayUsingSystemFont = false
let fontPicker = UIFontPickerViewController(configuration: configuration)
fontPicker.delegate = self
present(fontPicker, animated: true)
isPickerPresented?.wrappedValue = true
}
}
struct FontPickerViewControllerRepresentable: UIViewControllerRepresentable {
@Binding var isPickerPresented: Bool
var onFontPick: (UIFontDescriptor) -> Void
public func makeCoordinator() -> Coordinator {
return Coordinator(self, onFontPick: self.onFontPick)
}
public class Coordinator {
var parent: FontPickerViewControllerRepresentable
let picker = FontPickerViewController()
init(_ parent: FontPickerViewControllerRepresentable, onFontPick: @escaping (UIFontDescriptor) -> Void) {
self.parent = parent
picker.onFontPick = onFontPick
picker.isPickerPresented = parent._isPickerPresented
}
}
func makeUIViewController(context: Context) -> FontPickerViewController {
context.coordinator.picker
}
func updateUIViewController(_ uiViewController: FontPickerViewController, context: Context) {
if isPickerPresented {
context.coordinator.picker.showFontPicker()
} else {
}
}
@available(iOS 16.0, *)
func sizeThatFits(_ proposal: ProposedViewSize, uiViewController: FontPickerViewController, context: Context) -> CGSize? {
uiViewController.view.intrinsicContentSize
}
}
struct FontPicker: View {
@State var isPickerPresented = false
@State var selectedFont: UIFont?
var font: Font? {
if let selectedFont {
return Font(selectedFont)
}
return nil
}
var body: some View {
Button {
isPickerPresented = true
} label: {
HStack {
FontPickerViewControllerRepresentable(isPickerPresented: $isPickerPresented) { fontDescriptor in
let size = UIFont.preferredFont(forTextStyle: .body).pointSize
let font = UIFont(descriptor: fontDescriptor, size: size)
selectedFont = font
}
Spacer()
Text(selectedFont?.familyName ?? "Not Selected")
.font(font)
.foregroundColor(.secondary)
}
}
.onAppear {
print(UIFont.preferredFont(forTextStyle: .body))
}
}
}
}
struct Test3_Previews: PreviewProvider {
static var previews: some View {
Form {
FontPicker()
let defaultFont = UIFont.preferredFont(forTextStyle: .body)
Text(defaultFont.familyName)
Text(defaultFont.fontName)
}
}
}