【问题标题】:Saving state of UIButton (checkbox) - Swift保存 UIButton 的状态(复选框) - Swift
【发布时间】:2015-02-16 17:00:25
【问题描述】:

我是一名新开发人员,我正在用 Swift 制作一个待办事项列表应用程序。我能够弄清楚如何在单击时更改UIButton(复选框)的状态。目前,我正试图弄清楚如何在退出应用程序或切换视图并返回时保存该状态。我能够使用NSUserDefaults 成功保存文本(待办事项列表任务),并且还在我的按钮上进行了实验,但不知道如何让它工作。

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var myButton: Qbutton!

override func viewDidLoad() {
    super.viewDidLoad()

    var isChecked = NSUserDefaults.standardUserDefaults().boolForKey("isBtnChecked") // here we obtain the last state of the button
    myButton.isChecked = isChecked
    self.view.addSubview(myButton)

我在QButton 的子类中有UIButton

class Qbutton: UIButton {

    var isSelected: Bool = defaults.boolForKey("isButtonChecked")

    // Images
    let selectedImage = UIImage(named: "Selected")
    let unselectedImage = UIImage(named: "Unselected")


    //Bool Property
    var isChecked:Bool = false{
        didSet{
            if isChecked == true{
                self.setImage(selectedImage, forState: UIControlState.Normal)
            }else{
                self.setImage(unselectedImage, forState: UIControlState.Normal)
            }
            defaults.setObject(isChecked, forKey: "isButtonChecked")
        }
    }

    override init(frame: CGRect){
    super.init(frame:frame)
    self.layer.masksToBounds = true
    self.setImage(unselectedImage, forState: UIControlState.Normal)

    self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
    self.isChecked = false
}

required init(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

func buttonClicked(sender: UIButton) {
    if(sender == self){
        if isChecked == true{
            isChecked = false
        }else{
            isChecked = true
        }
    }
}
}

【问题讨论】:

  • 您的代码很好,您遇到了什么问题?通过var isSelected: Bool = defaults.boolForKey("SelectedState")访问您的默认设置
  • 如果 isChecked == true 是多余的。 if isChecked {...}
  • 另外,如果你想切换一个布尔值(func checkBox),你可以简单地这样做:isChecked = !isChecked
  • 我继续重构我的一些代码。我仍然遇到问题,因为当我关闭应用程序并尝试运行它时,我的按钮状态不会保存。

标签: ios xcode swift uibutton nsuserdefaults


【解决方案1】:

我认为您可以在变量 isChecked 更改时使用 NSUserDefaults 保存 UIButton 的状态。像这样的:

var isChecked:Bool = false{
    didSet{
        if isChecked {
            self.setImage(selectedImage, forState: UIControlState.Normal)
        }else{
            self.setImage(unselectedImage, forState: UIControlState.Normal)
        }
        NSUserDefaults.standardUserDefaults().setObject(isChecked, forKey: "isBtnChecked")
        // this method is automatically invoked at periodic intervals, but
        //if you cannot wait for the automatic synchronization you can invoke it
        NSUserDefaults.standardUserDefaults().synchronize() 
    }


}

现在,当您的应用启动时,您可以使用以下命令检查 UIButton 的最后状态:

var isSelected: Bool = NSUserDefaults.standardUserDefaults().boolForKey("isBtnChecked")

更新

我使用您的 Qbutton 类做了一个示例。我希望这可以帮助你:

import Foundation
import UIKit

class Qbutton: UIButton {

    // Images
    let selectedImage = UIImage(named: "Selected")
    let unselectedImage = UIImage(named: "Unselected")

    //Bool Property
    var isChecked:Bool = false{
        didSet{
            if isChecked {
                self.setImage(selectedImage, forState: UIControlState.Normal)
            }else{
                self.setImage(unselectedImage, forState: UIControlState.Normal)
            }
            NSUserDefaults.standardUserDefaults().setObject(isChecked, forKey: "isBtnChecked")
            // this method is automatically invoked at periodic intervals, but
            //if you cannot wait for the automatic synchronization you can invoke it
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    override init(frame: CGRect){
        super.init(frame:frame)
        self.layer.masksToBounds = true
        self.setImage(unselectedImage, forState: UIControlState.Normal)

        self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
        self.isChecked = false
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func buttonClicked(sender: UIButton) {
        if(sender == self){
            if isChecked == true{
                isChecked = false
                self.setImage(unselectedImage, forState: UIControlState.Normal)
            }else{
                isChecked = true
                self.setImage(selectedImage, forState: UIControlState.Normal)
            }
        }
    }
}

现在在UIViewController 中创建一个Qbutton,在将其添加到UIViewController 视图之前,我读取了变量“isBtnChecked”的最后状态。

来自official docs

如果布尔值与用户默认值中的 defaultName 相关联,则返回该值。否则,返回 NO。

import UIKit
class ViewController: UIViewController {
    var myButton: Qbutton!

    override func viewDidLoad() {
        super.viewDidLoad()

        myButton = Qbutton(frame: CGRectMake(100,100,50 ,50));
        var isChecked = NSUserDefaults.standardUserDefaults().boolForKey("isBtnChecked") // here we obtain the last state of the button
        myButton.isChecked = isChecked // we set the value
        self.view.addSubview(myButton)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }
}

更新 2

这里是一个使用UIButton的selected属性的例子

import Foundation
import UIKit

class Qbutton: UIButton {

    // Images
    let selectedImage = UIImage(named: "Selected")
    let unselectedImage = UIImage(named: "Unselected")


    //Bool Property
    override var selected: Bool{
        didSet{
            if selected {
                self.setImage(selectedImage, forState: UIControlState.Normal)
            }else{
                self.setImage(unselectedImage, forState: UIControlState.Normal)
            }
            NSUserDefaults.standardUserDefaults().setObject(selected, forKey: "isBtnChecked")
            NSUserDefaults.standardUserDefaults().synchronize()
        }
    }

    override init(frame: CGRect){
        super.init(frame:frame)
        self.layer.masksToBounds = true
        self.setImage(unselectedImage, forState: UIControlState.Normal)

        self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
   }

    func buttonClicked(sender: UIButton) {
        self.selected = !self.selected
    }
}

还有UIViewController

import UIKit
class ViewController: UIViewController {
    var myButton: Qbutton!

    override func viewDidLoad() {
        super.viewDidLoad()

        myButton = Qbutton(frame: CGRectMake(100,100,50 ,50));
        myButton.selected = NSUserDefaults.standardUserDefaults().boolForKey("isBtnChecked") // here we obtain the last state of the button
        self.view.addSubview(myButton)

    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }
}

希望对你有帮助!

【讨论】:

  • 是的,它没有那么多余。
  • 这个解决方案一半解决了我的问题。我无法在第二个花括号之外添加NSUSerDefaults。只有紧跟在else 之后的大括号。另外,我在哪里添加 var 实例?
  • 当在我的 Button 类中添加 var 并在 else 语句之后立即添加 NSUserDefaults 时,在选择一个按钮时它只会选择我表中的顶部一个并且也不会让我取消选择它。
  • 检查我更新的答案,我尝试向您展示一个完整的工作代码示例
  • 当 UIButton 的 selected 属性非常适合此任务时,为什么还需要添加 isChecked?
【解决方案2】:

我认为你完全想多了,把它弄复杂了。因为它只是一个简单的按钮,所以最简单的方法是通过IBAction 设置一个布尔值。如果我在你的问题中遗漏了什么,请告诉我。

在 Objective-C 中会是这样的......

{
    BOOL _isStateEnabled;
}

-(IBAction)clickedButton: (id)sender {
    _isStateEnabled = !_isStateEnabled;
}

在 Swift 中我不是很流利,但是,像这样..

{
    let _isStateEnabled as boolean;
}

func buttonClicked(sender: UIButton) {
    _isStateEnabled = !_isStateEnabled;
}

【讨论】:

  • 我必须仔细研究一下并将其转换为 Swift。目前,我的复选框正在工作,它们只是没有保存到 NSUserDefaults。这是我现在的问题。
  • @JohnJLilley 应该像创建布尔变量并将其设置为“不是”点击按钮时的当前状态一样简单。您可以使用 NSArchive 对布尔值进行编码和解码。
猜你喜欢
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 2018-06-17
相关资源
最近更新 更多