当我更改视图时,为啥我的按钮首选项/参数会重置?

Posted

技术标签:

【中文标题】当我更改视图时,为啥我的按钮首选项/参数会重置?【英文标题】:Why are my buttons preferences/parameters resetting when I change view?当我更改视图时,为什么我的按钮首选项/参数会重置? 【发布时间】:2015-10-25 14:30:20 【问题描述】:

我有这个 ios 应用程序,其中表格视图中单元格的值用于设置我的 UIButtons 上的首选项/参数。

当按下按钮时,我将标签 ID 发送到 tableview,当用户按下单元格时,它会收集文本和图像并将其(连同标签 ID)返回到主视图。

这成功地更改了具有相应按钮标签 ID 的按钮上的参数,但是当我现在按下一个新按钮执行相同的过程时,它会重置第一个按钮更改(清除图像和文本)并仅将更改应用于按下的新按钮。

这是主视图控制器类:

class ViewController: UIViewController 

var recievedItem: ChosenItem?
var imageToButton: UIImage?

@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!

func AddNew() 

    performSegueWithIdentifier("addNew", sender: nil)


@IBAction func loadItem(sender: UIButton!) 


    performSegueWithIdentifier("itemList", sender: sender)



override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

    if(segue.identifier == "itemList")

        let tableViewController : TableViewController = segue.destinationViewController as! TableViewController
        tableViewController.buttonTag = sender!.tag

    




@IBAction func play(sender: UIButton) 

    print("Jeg har fått \(recievedItem!.chosenWord)")



override func viewDidLoad() 
    super.viewDidLoad()

    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
    self.navigationController?.navigationBar.translucent = true

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Open", style: .Plain, target: self, action: "AddNew")

    navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: "AddNew")

    if(recievedItem != nil)
        imageToButton = UIImage(data: recievedItem!.chosenImage)

        switch recievedItem!.chosenButton

        case 0:
            button1.setBackgroundImage(imageToButton, forState: .Normal)
            button1.setTitle(recievedItem!.chosenWord, forState: .Normal)
        case 1:
            button2.setBackgroundImage(imageToButton, forState: .Normal)
            button2.setTitle(recievedItem!.chosenWord, forState: .Normal)
        case 2:
            button3.setBackgroundImage(imageToButton, forState: .Normal)
            button3.setTitle(recievedItem!.chosenWord, forState: .Normal)

        default:
            print("No buttonTag recieved")
        


    





override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.

这是tableview类:

class TableViewController: UITableViewController 

var words = [Words]()
var chosenItem: ChosenItem!
var buttonTag: Int!

override func viewDidLoad() 
    super.viewDidLoad()

    let appDel: AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
    let context: NSManagedObjectContext = appDel.managedObjectContext

    let request = NSFetchRequest(entityName: "Words")
    request.returnsObjectsAsFaults = false

    do 
     words = try context.executeFetchRequest(request) as! [Words]

     catch 
     print("Unresolved error")
     abort()
    

    print("Her er også button tag \(buttonTag)")


override func didReceiveMemoryWarning() 
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.



override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return self.words.count


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let itemWord = self.words[indexPath.row]

    cell.textLabel?.text = itemWord.word

    cell.imageView?.image = UIImage(data: itemWord.image!)

    return cell


override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
    print(self.words[indexPath.row].word!)

    chosenItem = ChosenItem()
    chosenItem.chosenButton = buttonTag
    chosenItem.chosenWord = self.words[indexPath.row].word!
    chosenItem.chosenImage = self.words[indexPath.row].image!
    performSegueWithIdentifier("backToMain", sender: chosenItem)



override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

    if(segue.identifier == "backToMain")

        let mainViewController : ViewController = segue.destinationViewController as! ViewController

        let data = sender as! ChosenItem

        mainViewController.recievedItem = data


    


这是保存数据的模型类:

class ChosenItem: NSObject 

var chosenButton: Int!
var chosenWord: String!
var chosenImage: NSData!


【问题讨论】:

"当我现在按下一个新按钮来做同样的程序"什么按钮,什么程序? @matt 共有三个不同的按钮。如果按下这些按钮中的任何一个,它会转到 tableView 并传递按下的按钮标记值。我使用标签值来了解按下了什么按钮。当按下一个单元格时,它会返回主视图并更改按下按钮的背景图像和文本。那就是“程序”。当我用其他按钮之一重复此操作时,第一个按钮被重置回默认值。是不是更清楚了? “它继续回到主视图”这听起来像问题。您不会“回到”主视图。 【参考方案1】:

问题出在这一行:

performSegueWithIdentifier("backToMain", sender: chosenItem)

不是你如何从推送或呈现的视图控制器返回到推送或呈现它的视图控制器!您所做的是创建 一个完全 视图控制器,这就是未设置所选按钮的原因;它是一个不同的视图控制器,具有不同的选择按钮,即没有,因为这个视图控制器刚刚出现。

这不仅会使所选按钮搞砸,而且最终您的应用程序会崩溃,因为您每次前进和后退时都会在另一个视图控制器之上创建一个视图控制器,最终您会耗尽内存。

从推送的视图控制器返回的方法是popViewController。从呈现的视图控制器返回的方法是dismissViewController

如果您知道自己在做什么,则可以改为使用称为 unwind segue 的特殊非 segue 转场,但听起来您还没有准备好这样做。

【讨论】:

啊!所以当我继续创建一个新视图并将其放在现有视图之上?所以我只是把它们叠在一起?但是当我使用 popViewController 时,我会一起从堆栈中删除视图吗?无论如何,当我再次转到主视图时,我已经使用 viewDidLoad() 从模型中获取数据。使用 popviewController 时是否调用了 som 函数? 被弹出的视图控制器得到viewWillDisappear:,因此它可以将任何信息交给另一个视图控制器(它仍然存在)。或者你可以做一个 unwind segue,正如我已经说过的,在这种情况下你可以使用prepareForSegue:

以上是关于当我更改视图时,为啥我的按钮首选项/参数会重置?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据偏好更改显示的按钮[关闭]

为啥 UIStackView 不断折叠标签?

应用程序崩溃时,共享首选项会重置数据。请指导

为啥当我在平移单元格时更改 UIImageView 的图像时,整个视图会重置一秒钟?

保存的首选项在重新启动时不起作用

SwiftUI 视图首选项:overlayPreferenceValue 在复杂容器上使用时返回 nil