我想让用户选择自定义字体。
import SwiftUI
class FontPickerVM: ObservableObject {
@AppStorage("custom_font") var font: Font? = nil
// @Published var font: Font? = nil
}
extension Font: RawRepresentable {
public typealias RawValue = String
public init?(rawValue: RawValue) {
}
public var rawValue: RawValue {
}
}
RawRepresentable
我该如何实施Font
?
我正在使用 aUIFontPickerViewController
来选择字体。
import UIKit
import SwiftUI
public struct SUIFontPicker: UIViewControllerRepresentable {
@Environment(\.presentationMode) var presentationMode
private let onFontPick: (UIFontDescriptor) -> Void
public init(onFontPick: @escaping (UIFontDescriptor) -> Void) {
self.onFontPick = onFontPick
}
public func makeUIViewController(context: UIViewControllerRepresentableContext<SUIFontPicker>) -> UIFontPickerViewController {
let configuration = UIFontPickerViewController.Configuration()
configuration.includeFaces = true
configuration.displayUsingSystemFont = false
let vc = UIFontPickerViewController(configuration: configuration)
vc.delegate = context.coordinator
return vc
}
public func makeCoordinator() -> SUIFontPicker.Coordinator {
return Coordinator(self, onFontPick: self.onFontPick)
}
public class Coordinator: NSObject, UIFontPickerViewControllerDelegate {
var parent: SUIFontPicker
private let onFontPick: (UIFontDescriptor) -> Void
init(_ parent: SUIFontPicker, onFontPick: @escaping (UIFontDescriptor) -> Void) {
self.parent = parent
self.onFontPick = onFontPick
}
public func fontPickerViewControllerDidPickFont(_ viewController: UIFontPickerViewController) {
guard let descriptor = viewController.selectedFontDescriptor else { return }
onFontPick(descriptor)
parent.presentationMode.wrappedValue.dismiss()
}
public func fontPickerViewControllerDidCancel(_ viewController: UIFontPickerViewController) {
parent.presentationMode.wrappedValue.dismiss()
}
}
public func updateUIViewController(_ uiViewController: UIFontPickerViewController,
context: UIViewControllerRepresentableContext<SUIFontPicker>) {
}
}
struct FontPicker: View {
@State var isFontPickerPresented = false
@Environment(\.font) var defaultFont
@StateObject var vm = FontPickerVM()
var body: some View {
Button {
isFontPickerPresented = true
printDetails()
} label: {
Text("Select font")
}
.sheet(isPresented: $isFontPickerPresented) {
SUIFontPicker { fontDescriptor in
let newFont = UIFont(descriptor: fontDescriptor, size: 18)
vm.font = Font(newFont as CTFont)
printDetails()
}
}
.font(vm.font)
}
func printDetails(){
print("default font:", defaultFont ?? "")
print("custom font:", vm.font ?? "")
}
}
struct FontPicker_Previews: PreviewProvider {
static var previews: some View {
Form {
FontPicker()
FontPicker()
}
}
}
我必须指定大小UIFont(descriptor: fontDescriptor, size: 18)
,但我只想更改字体系列。
如果是这种情况,那么您应该设置
configuration.includeFaces
为false
,以便用户只能选择一个族,而不能选择该族中的面(粗体、斜体等)。之后,
UIFontDescriptor
由 返回 的UIFontPickerViewController
应该始终NSFontFamilyAttribute
在其 中有一个键fontAttributes
。获取该键的值并将其存储在AppStorage
.例子:
如果您还想保存字体描述符中的其他信息(尽管根据我的经验,a 中的字体描述符
UIFontPickerViewController
没有太多“其他信息”),您可以Data
使用技术上将字体描述符转换为NSKeyedArchiver
。然后您可以将其存储Data
在@AppStorage
.