我已经创建了一个步进器来增加我的应用程序中的字体大小,现在,我想保存最后的字体大小,这样当用户重新打开应用程序时,最后一个字体大小将是持久的。我试图将它保存到UserDefaults,但它不会让我保存我的标签,因为我使用UIFont来建立我想要的字体类型,并且CGFloat能够使用我的步进器切换字体大小。
当我运行应用程序并尝试选择字体大小时,应用程序崩溃,我找不到问题。我知道问题是试图将数据从UIFont保存到UserDefaults,因为当我注释掉那行代码时,应用程序没有运行问题。
此外,在我尝试在ViewDidAppear函数中调用存储的UserDefault设置后,我收到错误消息,说我无法分配Any?输入UIFont?
任何帮助将不胜感激。同样,我的意图是,当用户使用步进器更改字体大小时,即使退出并重新打开应用程序,字体大小仍将保持持久。
import UIKit
import Foundation
class ViewController: UIViewController {
@IBOutlet weak var quotesLabel: UITextView!
@IBOutlet weak var welcomeLabel: UILabel!
@IBOutlet weak var topLabel: UILabel!
@IBOutlet weak var generateLabel: UILabel!
@IBOutlet weak var fontStepper: UIStepper!
@IBOutlet weak var minFontSizeLabel: UILabel!
@IBOutlet weak var adjustFontSizeLabel: UILabel!
@IBOutlet weak var maxFontSizeLabel: UILabel!
let quotesBook = QuotesBook()
let defaults = UserDefaults.standard
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
fontStepper.wraps = true
fontStepper.autorepeat = true
generateLabel.font = UIFont(name: "HoeflerText-Italic", size: 15)
generateLabel.textColor = UIColor(red: 25/255, green: 23/255, blue: 170/255, alpha: 230/255)
generateLabel.textAlignment = NSTextAlignment.center
topLabel.font = UIFont(name: "HoeflerText-Italic", size: 20)
topLabel.textColor = UIColor(red: 25/255, green: 23/255, blue: 170/255, alpha: 230/255)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func stepperPressed(_ sender: UIStepper) {
quotesLabel.isEditable = true
quotesLabel.font = UIFont (name: "Futura-MediumItalic", size: CGFloat(Float(sender.value)))
defaults.set(quotesLabel.font, forKey: "textSize")
}
@IBAction func showQuoteBttn(_ sender: Any) {
quotesLabel.textAlignment = NSTextAlignment.center
maxFontSizeLabel.isHidden = false
adjustFontSizeLabel.isHidden = false
minFontSizeLabel.isHidden = false
fontStepper.isHidden = false
generateLabel.isHidden = false
welcomeLabel.isHidden = true
topLabel.isHidden = true
quotesLabel.isHidden = false
quotesLabel.text = quotesBook.randomQuote()
}
override func viewDidAppear(_ animated: Bool) {
if let b = defaults.object(forKey: "textSize")
{
quotesLabel.font = b
}
}
答案 0 :(得分:6)
您无法将(UI)Font
直接保存到用户默认值中,因为它不符合属性列表。
合适的解决方案是分别保存字体的String
名称和Float
大小。这可以通过UserDefaults
:
extension UserDefaults {
func set(font : UIFont, forKey key : String)
{
let fontName = font.fontName
let fontSize = font.pointSize
self.set(fontName, forKey: key + "_name")
self.set(Float(fontSize), forKey: key + "_size")
}
func font(forKey key : String) -> UIFont?
{
guard let fontName = string(forKey: key + "_name") else { return nil }
let fontSize = float(forKey: key + "_size")
if fontSize == 0.0 { return nil }
return UIFont(name: fontName, size: CGFloat(fontSize))
}
}
或者 - 也可以使用扩展程序 - 归档并从NSData
取消归档字体:
extension UserDefaults {
func set(font: UIFont, forKey key: String)
{
let data = NSKeyedArchiver.archivedData(withRootObject: font)
self.set(data, forKey: key)
}
func font(forKey key: String) -> UIFont?
{
guard let data = data(forKey: key) else { return nil }
return NSKeyedUnarchiver.unarchiveObject(with: data) as? UIFont
}
}
答案 1 :(得分:1)
UIFont
无法保存到UserDefaults。您可以根据需要保存字体大小和字体名称。
将字体保存到UserDefaults
:
let font = UIFont.systemFont(ofSize: 15)
let defaults = UserDefaults()
defaults.set(font.pointSize, forKey: "font")
defaults.set(font.fontName, forKey: "fontName")
稍后恢复:
let fontSize = defaults.float(forKey: "font")
let fontName = defaults.string(forKey: "fontName")
if let name = fontName {
let savedFont = UIFont(name: name, size: CGFloat(fontSize))
print("Saved font: \(savedFont)")
}
else {
// Use default font
}
答案 2 :(得分:0)
(这是我搜索此问题的解决方案时出现的第一项,因此我不妨分享一个可持续的解决方案。在这里使用macOS,但NSFontDescriptor也存在于iOS上,只是替代UIFont。) >
推荐的保存字体的方法是不要这样做(有点浮躁,对不起)-但是在2013年的WWDC 223会议上(将字体与TextKit一起使用),建议专门用于 a)不选择属性(换句话说,不只保存字体名称和大小),并且 b)不保存NSFont,而是保存NSFontDescriptor。
NSFontDescriptor是一个容易被忽略的类,但是documentation很清楚
符号特征取代了NSFontManager使用的现有NSFontTraitMask类型。
所以我们应该使用它。尤其是在iOS上,您可以用它做很多奇怪的事情,包括要使用的字体的级联首选项,特定于语言的设置等。
保存,假设您使用的字体名为“字体”:
let fontDescriptor = font.fontDescriptor
let descriptorData = NSKeyedArchiver.archivedData(withRootObject: fontDescriptor)
userDefaults.set(descriptorData, forKey: "descriptorData")
阅读:
if let descriptorData = userDefaults.data(forKey: "descriptorData"){
if let fontDescriptor = NSKeyedUnarchiver.unarchiveObject(with: descriptorData) as? NSFontDescriptor {
let myFont = NSFont(descriptor: fontDescriptor, size: 0)
}
}
将大小设置为'0'意味着它将从描述符中获取大小,否则将覆盖它。
这不会保存字体颜色;如果要保存默认的文字颜色,则仍需要单独进行。