2017-01-23 52 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