2017-01-23 56 views
0

我已经创建了一个步进器来增加我的应用程序中的字体大小,现在我想保存最后的字体大小,以便当用户重新打开应用程序时,最后的字体大小将保持不变。我试图将其保存到UserDefaults,但它不会让我保存我的标签,因为我使用UIFont来建立我想要的字体类型,并且CGFloat能够使用我的步进器切换字体大小。保存UIFont?以UserDefault Swift 3

当我运行该应用程序,并尝试选择字体大小,应用程序崩溃,我找不到问题。我知道问题是试图将来自UIFont的数据保存到UserDefaults中,因为当我注释掉那行代码时,应用程序没有运行问题。

此外,我尝试调用ViewDidAppear函数中存储的UserDefault设置后,我收到一个错误,说我不能指定任何?键入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 
    } 

} 
+1

你为什么不只是保存的字体大小? – redent84

+0

你好!这就是我试图去做的原因。但是,我不想创建另一个按钮来保存字体大小。我想要做的是,一旦你完成使用步进器来选择任何你想要的字体大小,应用程序将记住这个大小,直到你再次改变它。 – Henry

+0

谢谢大家所有的解决方案。我非常感谢你们抽出时间帮助我。我会在稍后尝试。上帝保佑你们。 – Henry

回答

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 
} 
+0

只要它可以转换为NSData,任何东西都可以保存为'NSUserdefaults' – Lefteris

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 
    } 
} 
+0

正确的表达式,它不是可序列化的...... – Lefteris

+0

@Lefteris不,它不是,可序列化和符合属性列表是两个独立的事情。 – fpg1503

+0

其实不是。只要它可以转换为NSData,你可以保存它 – Lefteris