swift - 通过 prepareforsegue 在 2 个视图控制器之间添加值

Posted

技术标签:

【中文标题】swift - 通过 prepareforsegue 在 2 个视图控制器之间添加值【英文标题】:swift - adding values between 2 view controllers by prepareforsegue 【发布时间】:2015-02-17 08:36:33 【问题描述】:

我有 2 个 ViewController:ViewController1、ViewController2。 ViewController1 中的“添加”按钮将调出 ViewController2。然后,用户将在 ViewController2 中输入值,然后由 prepareforsegue 将其传递回 ViewController1。然后将这些值附加到 viewcontroller1 中类型数组的属性上。

这是重复的,用户继续按下添加按钮以从 ViewController1 中调出 ViewController2,然后通过 prepareforsegue 添加要附加到 ViewController1 中数组类型属性的新值。

但是,在从 ViewController2 附加第一组值之后,情况就不是这样了。第二组值将覆盖第一组值。

示例。

第一次通过后-> force =[1],stiffness[1]

第二次通过后->force=[2],stiffness[2]

我想要这个 -> 力 = [1,2], 刚度 [1,2]

我想继续添加直到 -> force = [1,2,3,4,5],stiffness[1,2,3,4,5]

ViewController1

class ViewController1: UITableViewController, UITableViewDataSource 
    var force = [Float]()
    var stiffness = [Float] ()
@IBAction func Add(sender: AnyObject)  


ViewController2

class ViewController2: UIViewController 
        var forceVar : Float = 0.0
        var stiffVar : Float = 0.0

@IBAction func submit(sender: AnyObject) 
        self.performSegueWithIdentifier("springSubmit", sender: sender)
        

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) 
        if(segue.identifier == "springSubmit") 
            var svcSubmitVariables = segue.destinationViewController as ViewController1

            svcSubmitVariables.force.append(forceVar)
            svcSubmitVariables.stiffness.append(stiffVar)   
        

【问题讨论】:

【参考方案1】:

performSegueWithIdentifier 方法将始终初始化新的视图控制器,因此在您的示例视图控制器中,显示 ViewController2 与提交数据后初始化的对象不同,并且这个新初始化的对象将只有初始化值。要实现您要查找的内容,您需要在 ViewController1 上声明一个函数,该函数会将数据附加到您的数组中,将该函数传递给 ViewController2 并在提交方法中调用它,这样您的视图控制器将如下所示:

ViewController1

class ViewController1: UITableViewController, UITableViewDataSource 

    var force = [Float]()
    var stiffness = [Float] ()

    override func viewWillAppear(animated: Bool) 

     //check if values are updated
     println(force)
     println(stiffness)
    

    @IBAction func Add(sender: AnyObject)  
        self.performSegueWithIdentifier("viewController2", sender: sender)
    

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) 
        if(segue.identifier == "viewController2") 

            var addVariables = segue.destinationViewController as ViewController2
            addVariables.submitFunc = appendData
                  
    

    func appendData(newForce:Float,newStiffness:Force)
        force.append(newForce)
        stiffness.append(newStiffness)
           

ViewController2

class ViewController2: UIViewController 
    var forceVar : Float = 0.0
    var stiffVar : Float = 0.0
    var submitFunc:((newForce:Float,newStiff:Float)->())!

    @IBAction func submit(sender: AnyObject) 

        submitFunc(forceVar,stiffVar)
        self.dismissViewControllerAnimated(false, completion: nil)

    

【讨论】:

提交方法不太明白?这个提交方法是做什么用的?是否应该准备好将值传回 ViewController1? @Cherry_thia 您不必在 ViewController2 上使用 perfromSegue 方法,因为 ViewController1 已经存在,而是在 ViewController1 上使用 performSegue 和 preapreForSegue 来显示 ViewController2 这仍然不起作用。每当 Viewcontroller2 进入 Viewcontroller1 时,Viewcontroller1 中的变量仍会初始化为零。 ViewController2 不应该转到 ViewController1,而是 ViewController2 必须只关闭自己才能使 ViewController1 再次出现。您可以发布所有代码吗? 您的代码是正确的,可能有问题的是访问新值的时刻:如果您在 viewDidLoad 方法中访问这些值,那么它是错误的,您应该按照已编辑答案中的描述在 viewWillAppear 上执行此操作跨度> 【参考方案2】:

视图控制器

    import UIKit

class ViewController: UITableViewController, UITableViewDataSource 

    var springNumber:NSInteger = 0
    var force = [Float]()
    var stiffness = [Float] ()

    // MARK: UITableViewDataSource
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int 
        return 1
    

    override func tableView(tableView: UITableView,
        numberOfRowsInSection section: Int) -> Int 
            return springNumber
    

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

            let cell = tableView.dequeueReusableCellWithIdentifier("Cell")
                as UITableViewCell

            cell.textLabel!.text = "Spring \(indexPath.row)"

            return cell
    

    func fwall() -> Float 
        for rows in 0..<(springNumber+1)  
            force[0] = force[0] + force[rows]
        
        force[0] = -(force[0])
        return force[0]
    

    override func viewWillAppear(animated: Bool) 

        super.viewWillAppear(animated)

        title = "Springs' Variables"
            tableView.registerClass(UITableViewCell.self,
                forCellReuseIdentifier: "Cell")

        if(springNumber==0) 
            force.append(0.0) 

        println(force)
        println(stiffness)
    

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

    //Adding Values
    @IBAction func Add(sender: AnyObject) 
        self.performSegueWithIdentifier("addSpring", sender: sender)
    

    @IBAction func solve_Pressed(sender: AnyObject) 
        self.fwall()
        self.performSegueWithIdentifier("Solve", sender: sender)
    

    func appendData (newForce: Float, newStiffness:Float, newSpring: NSInteger) 
        force.append(newForce)
        stiffness.append(newStiffness)
        springNumber = newSpring
        println(springNumber)
        println(force)
        println(stiffness)
    

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

        if (segue.identifier == "addSpring") 
            var addVariables = segue.destinationViewController as SpringTableViewControllerInsertVariables
                addVariables.submitFunc = appendData
        

        if (segue.identifier == "Solve") 
            var svcViewController2 = segue.destinationViewController as ViewController2
            svcViewController2.forceView2 = self.force
            svcViewController2.stiffView2 = self.stiffness
            svcViewController2.springNumView2 = self.springNumber
        

        if (segue.identifier == "showDetail") 

        
    

springTableViewControllerInsertVariables 的代码

import UIKit

类 SpringTableViewControllerInsertVariables: UIViewController

var forceVar : Float = 0.0
var stiffVar : Float = 0.0
var springNum : NSInteger = 0

var submitFunc: ((newForce:Float,newStiff:Float,newSpring:NSInteger)->())!

@IBOutlet weak var image: UIImageView!

var imageArray :[UIImage] = [UIImage(named: "springAtWall.jpg")!, UIImage(named:"spring.jpg")!]

override func viewDidLoad() 
    if(springNum == 0) image.image = imageArray[0] 
    else image.image = imageArray[1] 


@IBOutlet weak var force: UILabel!
@IBOutlet weak var forceEntered: UITextField!

@IBOutlet weak var stiffness: UILabel!
@IBOutlet weak var stiffnessEntered: UITextField!

@IBAction func checkboxed(sender: AnyObject) 
    //when checkedboxed is checked here. 
    //1)UIImage is changed
    //2)calculate2 function is used for calculate1


@IBAction func submit(sender: AnyObject) 
    //might not work because springNum will be initialise to zero when this viewcontroller starts...

    forceVar = (forceEntered.text as NSString).floatValue
    stiffVar = (stiffnessEntered.text as NSString).floatValue

    springNum = springNum + 1

    submitFunc(newForce: forceVar ,newStiff: stiffVar, newSpring: springNum)

    self.dismissViewControllerAnimated(false, completion: nil)


【讨论】:

以上是关于swift - 通过 prepareforsegue 在 2 个视图控制器之间添加值的主要内容,如果未能解决你的问题,请参考以下文章

Swift:如何在 UICollectionViewCell 中使用“prepareForSegue”?

prepareForSegue 不适用于自定义 segue (swift)

Swift:prepareForSegue 有两个不同的 segue

Swift:PrepareForSegue 正在运行但未加载 ViewController

在 Swift 2 中通过“prepareForSegue”传递数据

(Swift) PrepareForSegue: 致命错误: 在展开可选值时意外发现 nil