全局变量和可选斯威夫特结合全局变量和可选斯威夫特结合(Global variable and opt

2019-05-12 12:41发布

我有一个关于可选的绑定,全局变量和包装和展开一些很简单的疑问。 由于我是新来的SWIFT,其非常重要的,了解他们的概念山雀&位。

1)在斯威夫特如果我声明一个全局变量,我有两个选择要么使之选或不选,所以让我有2-4个或更多的可选变量。 因此,它是明智的可选绑定所有这些变量

viewDidLoad() method// so that I could use them without any problem of unwrapping and fatal error in my program.

2)让我自己更加明确由以下示例 - 我有2个VC在我的项目VC1和VC2。 VC2具有其中用户输入一些值,并将其显示在一个VC1 tabelview的文本字段。

在VC1

var namevc1 = NSMutableArray?//holds the input of textfield to be passed from VC2. 

正如你所看到的,我的VC1是加载第一个视图控制器,当我的项目运行和我使用一个可选的变量来填充我tabke vuew即

'arr'

所以,当应用程序在第一次运行,其空。 因此,它可能同时在代码中使用它的价值造成致命的错误。 那么,什么是其解决方案是否要解除绑定的

viewDidLoad() 

方法或在所有总声明代替可选的类型的空NSMutable数组类型。

提前致谢。

Answer 1:

我会从上面重复我的评论开始。

也许你误解斯威夫特全局变量的概念。

  1. 如果你有一个全局变量,你不会有任何的意见/方法/类等之间的“通行证”,因为该变量是在全局范围定义(可无处不在)。

  2. 一般全局变量是不是一个好主意,那你希望避免的事情。

对于全局变量和迅速的事,你真的应该包括单身人士加入讨论。 例如参见下面的现有的SO线程(S):

  • 任何理由不使用雨燕采用单“变”?
  • ( 如何创建一个全局变量? )

  • ( 斯威夫特声明全局变量 )


通过塞格斯的装置(用于制备&放松塞格斯)TableViewController和ViewController之间的通信

(这个答案最终是非常,可能有点过于透彻,我就不详细了解目前的tableview /视图-控制程序的状态是什么样子一样。对不起,长时间的答案,它可能会带来它的读者的不便)。

现在,让我们离开的全局变量,并讨论一个在您的例子中的两个控制器之间的通信可行的选择(其它之中)。 从你的问题,我来总结一下您的例子如下

  • VC1:故事板的切入点,一个UITableViewController组成UITableViewCell s,其中,在这些细胞中,将显示一些文字,比如,通过实例UILabel
  • VC2:一个UIViewController ,从VC1中含有的细胞,可访问UITextField实例。 当用户输入文本在文本框中,你要显示在VC2相关的细胞 (在这个意义上,它是被用来访问VC2 VC1在该小区有关的)文本。

我们将关联VC1和VC2与(可可触摸)班TableViewController (TableViewController.swift)ViewController ,分别为(ViewController.swift)。 在表视图控制器将细胞将与(可可触摸)类相关联TableViewCell (TableViewCell.swift)。 这些类的细节在下面跟随。

对于这个简单的示例中,注意,我们不会嵌入VC1到导航控制器(它是否则适合表视图 - >视图导航)。

我们将在故事板开始,添加了对一个对象(从对象库拖拽和拖放) Table View ControllerView Controller 。 该表视图容器将也会自动包含在其Table View ,一个TableViewCell 。 继续在故事板:

  • 一个添加UILabel对象到TableViewCell容器在Table View Controller (对齐如你所愿)
  • View Controller ,添加一个Text Field对象和Button对象(对齐它们如你所愿)。
  • 设置入口点Table View Controller
  • 从其后Ctrl键并拖动“显示” SEGUE TableViewCellView Controller
  • 选择Show SEGUE和从属性检查器中输入一个标识符,再说,ShowDetail。
  • 最后,随着TableViewCell选择,(如上文;从所述属性检查员),输入该小区的标识符。 在这里,我们将使用简单的使用标识符TableViewCell。

现在,我们离开的故事板现在并实现了三个班,与相关的Table View ControllerView Controller和前人TableViewCell

我们先从Table View Controller ,并实现我们UITableViewController子类。 请注意,在这里,而不是使用NSMutableArray举行的文本UITextLabel在每个单元中,我们可以简单的将一个String数组。

// TableViewController.swift
Import UIKit

class TableViewController: UITableViewController {

    // Properties
    var userTextLabels = [String]()
    var numberOfCells: Int?

    override func viewDidLoad() {
        super.viewDidLoad()

        numberOfCells = loadSampleTextLabels() // Load sample labels.
    }

    func loadSampleTextLabels() -> Int {
        userTextLabels += ["Label #1", "Label #2", "Label #3"]
        return userTextLabels.count
    }

    // func numberOfSectionsInTableView(tableView: UITableView) ...
    // func tableView(tableView: UITableView, numberOfRowsInSection section: Int) ...

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = ("TableViewCell")
        let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! TableViewCell

        // Text for current cell
        let cellText = userTextLabels[indexPath.row]
        cell.userSuppliedTextLabel.text = cellText

        return cell
    }

    // ... communication?
}

其中两个注释方法是在任何使用标准方法UITableViewController ,对于切片的数量(例如return 1 )和细胞(例如return (numberOfCells ?? 0)在表中,分别。 我将离开这些固定给你。

现在,我们的关联TableViewCell与子类的实例表视图对象(S) UITableViewCell 。 在这里,我们将使用我们的细胞一个非常简单的类; 每个小区只含有单一UILabel实例(通过故事板按Ctrl键创建为@IBOutletUILabel在表视图细胞)。

// TableViewCell.swift
import UIKit

class TableViewCell: UITableViewCell {

    // Properties
    @IBOutlet weak var userSuppliedTextLabel: UILabel!
        // Ctrl-drag from UILabel (in TableViewCell) in storyboard

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

    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}

最后,对于从表视图细胞访问的视图控制器:使用单个@IBOutletUITextField用于用户输入的文本,并使用预先存在的处理事件在此文本字段UITextFieldDelegate 。 例如:

//  ViewController.swift
import UIKit

class ViewController: UIViewController, UITextFieldDelegate {

    // Properties
    @IBOutlet weak var userSuppliedText: UITextField!
        // Ctrl-drag from storyboard...
    var cellText: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        userSuppliedText.text = cellText ?? "..."

        // Handle the user input in the text field through delegate callbacks
        userSuppliedText.delegate = self
    }

    // UITextFieldDelegate
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        // User finished typing (hit return): hide the keyboard.
        textField.resignFirstResponder()
        return true
    }

    func textFieldDidEndEditing(textField: UITextField) {
        cellText = textField.text
    }

}

我们还宣布字符串属性( cellText )这里,这将作为充当VC1和VC2之间的通信容器。

我们回到故事板和从---身份检查---三个故事板对象(关联Table View ControllerView ControllerTableViewCell与我们刚才上面写自己的关联类)。

我们现在几乎我们的目标; 它仍然只是说明如何在两个控制器之间的通信。

我们将与通信开始 VC1 VC2 。 在你上面的评论,你是在正确的轨道上(这个特定的解决方案,无论如何)通过查看prepareForSegue(...)方法。 在类的Table View Controller ,我们添加下面的方法:

// ... add to TableViewController.swift
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    // Get the new view controller using segue.destinationViewController.
    // Pass the selected object to the new view controller.

    if segue.identifier == "ShowDetail" {
        let viewController = segue.destinationViewController as! ViewController
        if let selectedCell = sender as? TableViewCell {
            let indexPath = tableView.indexPathForCell(selectedCell)!
            let currentTextInCell = userTextLabels[indexPath.row]
            viewController.cellText = currentTextInCell // <-- note this
        }
    }
}

因此,对于VC1-> VC2通信,就可以(在这个例子中)带来任何现有当前占用文本UILabel在发送方小区(如由字符串数组指定userTextLabels )。 看看viewDidLoad(...)ViewController.swift方法怎么看这个值是从VC1通过并设置为默认的文本UITextField的VC2。

现在,通信VC2-> VC1,这是你问一下,加另一种方法(编程)之间的特定通信方向,再次TableViewController.swift:

// ... add to TableViewController.swift
@IBAction func unwindToTableView(sender: UIStoryboardSegue) {
    if let sourceViewController = sender.sourceViewController as? ViewController, 
        text = sourceViewController.cellText {
            // ^ note 2nd clause of if let statement above    
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            // Update cell text
            userTextLabels[selectedIndexPath.row] = text
            tableView.reloadRowsAtIndexPaths([selectedIndexPath], withRowAnimation: .None)
        }
    }
}

在这里,我们定义了一个开卷作用,在触发时,检索cellText那是SEGUE,即源视图控制器的性能,在我们的例子,实例ViewController 。 但是,我们如何触发这个动作?

返回到故事板和View Controller 。 需要注意的三个小图标,在顶部View Controller对象,更具体,最右边的这些,命名为Exit 。 从您按住Ctrl键的动作ButtonExit图标,并选择unwindToTableView行动Segue公司。 当您点击按钮视图控制器,视图开卷(出口)和土地的unwindToTableView的方法TableViewController

生成的应用程序应该是这个样子:


这是程较长比我预想的,但一旦你开始编写...无论如何,上面所使用的方法,自然,没有全局变量,但利用引用和未来( prepareForSegue )或历史( unwindToTableView )的意见得到(通常从当前或历史视图),或通过使用这些参考文献(未来/历史视图设置(通常在未来视图)值的电流)。

苹果对在tableviewcontroller /视图 - 控制上下文的示例应用程序,我会建议去在自己的非常彻底的教程。 我发现,当我开始编码斯威夫特很宝贵的自己。

着手开发iOS应用(SWIFT)



文章来源: Global variable and optional binding in Swift