You are trying to save the list using UserDefaults.standard. It is a list of custom classes that inherit UIButton, but this is an error. Can UserDefaults.standard store only types that have been done with Int and String? I did as follows. If I want to save the UIbutton list as below, can you try another method?

var Buttons = [UIButton] () I want to save this list
var Buttontitles = [String] ()
// Custom class inheriting UIButton
class MyButton: UIButton {
        let x: Int
        let y: Int
        init (x: Int, y: Int, frame: CGRect) {
            self.x = x
            self.y = y
            super.init (frame: frame)
        required init (coder aDecoder: NSCoder) {
            fatalError ("init (coder :) has not been implemented")
func create_buttons (button_name: String) {
        Button_num + = 1
        if Button_num% 2 == 0 {
            Button_num_row + = 1
        } else {
            Button_num_row = 0
            Button_num_col + = 1

        var btn: UIButton = MyButton (
            x: Button_num_row,
            y: Button_num_col,
            frame: CGRect (x: CGFloat (50 + Button_num_row * 150), y: CGFloat (Button_num_col) * 100, width: 100, height: 50))
        btn.setTitle (button_name, for: UIControlState.normal)
        // Action when button is pressed
        btn.addTarget (self, action: #selector (pushed), for: UIControlEvents.touchUpInside)
        // red for viewing
        btn.backgroundColor = UIColor.red
        btn.showsTouchWhenHighlighted = true
        btn.layer.shadowOpacity = 0.5
        Buttontitles.append ((btn.currentTitle)!)
        Buttons.append (btn)
        // Add to screen
        view.addSubview (btn)
     // Trying to save below! ! ! !
        let defaults = UserDefaults.standard
        defaults.set (Buttons, forKey: "Buttons") // Can't save UIButton type? By the way, you can do defaults.set (Buttontitles, forKey: "Buttons") with a list of strings

  • Answer # 1

    Looks like this

    import UIKit
    class DataConvertor {
        let buttonArray: [UIButton]
        let titleLabeLArray: [String] = ["abc", "def", "ghi", "jkl"]
        let userDefaults = UserDefaults.standard
        init () {
            buttonArray = titleLabeLArray.map {title->UIButton in
                let button = UIButton ()
                button.setTitle (title, for: .normal)
                return button
        func set () {
            let data = NSKeyedArchiver.archivedData (withRootObject: buttonArray)
            userDefaults.set (data, forKey: "data")
            userDefaults.synchronize ()
        func get () {
            guard let data = userDefaults.object (forKey: "data") as? Data else {
                fatalError ()
            guard let array = NSKeyedUnarchiver.unarchiveObject (with: data) as? [UIButton] else {
                fatalError ()
            array.forEach {button->Void in
                guard let text = button.titleLabel? .text else {
                    fatalError ()
                print (text) // abc
                             // def
                             // ghi
                             // jkl

    I can. The name is appropriate.

    Since it's troublesome, it's safe to put only the necessary values ​​in userDefaults.

  • Answer # 2

    UserDefaults cannot save UIButton types.
    It seems that the interface can be saved as Any? Type, but it is used when retrieving it.

    func integer (forKey defaultName: String)->Int
    There is nofunc uibutton (foKey defaultName: String)->UIButtonin the set of methods such as

    . UserDefaults can only contain Int, Float, String, etc., which are generally called primitive types, and their arrays and dictionaries.

    The request to save the UIButton list in this question is to save the UIButton title list in UserDefaults in the form of a String array, for example. I think it can be realized in the form of generation.