0

オプションのバインディング、グローバル変数、およびラッピングとアンラッピングに関して、非常に単純な疑問があります。私は SWIFT を初めて使用するので、SWIFT の概念の詳細を理解することは非常に重要です。

1) Swift でグローバル変数を宣言すると、それをオプションまたは非オプションにする 2 つのオプションがあるため、2 ~ 4 個以上のオプションの変数を使用できます。したがって、これらすべての変数をオプションでバインドすることをお勧めします

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

2)次の例で自分自身をより明確にしましょう-プロジェクト VC1 に 2 つの VC と VC2 があります。VC2 には、ユーザーが値を入力して VC1 の表ビューに表示するテキスト フィールドがあります。

Vc1 で

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

ご覧のとおり、VC1 は、プロジェクトの実行時に読み込まれる最初のビュー コントローラーであり、オプションの変数を使用して、tabke ビューにデータを入力しています。

'arr'

そのため、アプリが初めて実行されるときは空の . そのため、コードでその値を使用しているときに致命的なエラーが発生する可能性があります。それで、それをアンバインドするかどうかの解決策は何ですか

viewDidLoad() 

メソッドまたは全体として、オプションの type の代わりに空の NSMutable 配列型を宣言します。

前もって感謝します。

4

1 に答える 1

6

上記のコメントを繰り返すことから始めます。

Swift のグローバル変数の概念を誤解している可能性があります。

  1. グローバル変数がある場合、変数はグローバル スコープで定義されている (どこからでもアクセスできる) ため、ビュー/メソッド/クラスなどの間でそれを「渡す」必要はありません。

  2. 一般に、グローバル変数は良い考えではなく、避けたいものです。

グローバル変数とスウィフトの問題に関しては、シングルトンを議論に含めるべきです。たとえば、次の既存の SO スレッドを参照してください。


セグエによる TableViewController と ViewController 間の通信 (セグエの準備と巻き戻し)

(この回答は、現在のテーブルビュー/ビューコントローラープログラムの状態がどのように見えるかを詳しく知らなかったため、最終的には非常に、おそらく少し徹底しすぎました。長い回答と、それが読者にもたらす可能性のある不便について申し訳ありません)

ここで、グローバル変数を残して、この例で 2 つのコントローラー間の通信に実行可能なオプションの 1 つ (とりわけ) について説明します。あなたの質問から、あなたの例を次のように要約します

  • VC1 : ストーリーボード エントリ ポイント、 でUITableViewController構成されるUITableViewCell。これらのセルでは、たとえば のインスタンスを介してテキストを表示しますUILabel
  • VC2 :インスタンスUIViewControllerを含む、VC1 のセルからアクセスできるUITextFieldユーザーがこのテキスト フィールドにテキストを入力すると、そのテキストが VC2 の関連付けられたセル (VC2 へのアクセスに使用されたのは VC1 のセルであるという意味で関連付けられている) に表示されます

VC1 と VC2 を (ココア タッチ) クラスTableViewController( TableViewController.swift ) とViewController( ViewController.swift ) にそれぞれ関連付けます。Table View Controller のセルは (cocoa touch) クラスTableViewCell( TableViewCell.swift ) に関連付けられます。これらのクラスの詳細は以下のとおりです。

この単純な例では、VC1 をナビゲーション コントローラーに埋め込まないことに注意してください (それ以外の場合は、テーブル ビュー -> ビュー ナビゲーションに適しています)。

Table View Controllerストーリーボードから開始し、およびのオブジェクトを追加します (オブジェクト ライブラリからドラッグ アンド ドロップ) View Controller。また、テーブル ビュー コンテナには、自動的Table ViewTableViewCell. ストーリーボードの続き:

  • のコンテナにUILabelオブジェクトを追加します(必要に応じて配置します)TableViewCellTable View Controller
  • で、オブジェクトとオブジェクトをView Controller追加します(必要に応じて位置合わせします)。Text FieldButton
  • エントリ ポイントを に設定しTable View Controllerます。
  • その後、「Show」セグエを から に Ctrl キーを押しながらドラッグしTableViewCellますView Controller
  • セグエを選択Showし、属性インスペクタからその識別子、たとえばShowDetailを入力します。
  • 最後にTableViewCell、(上記のように、属性インスペクターから) を選択して、セルの識別子を入力します。ここでは、単に識別子TableViewCellを使用します。

今のところストーリーボードは残し、Table View Controller、 、View Controllerおよび前者のに関連付けられた 3 つのクラスを実装しTableViewCellます。

から始めて、サブクラスTable View Controllerを実装します。UITableViewControllerここでは、各セルNSMutableArrayのテキストを保持するためにan を使用する代わりに、単純に配列を使用することに注意してください。UITextLabelString

// 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?
}

コメントアウトされた 2 つのメソッドは、テーブル内UITableViewControllerのセクション数 (例return 1) とセル数 (例 ) でそれぞれ使用される標準的な方法です。return (numberOfCells ?? 0)これらの修正はお任せします。

ここTableViewCellで、テーブル ビュー内のオブジェクトをサブクラスのインスタンスに関連付けますUITableViewCell。ここでは、セルに非常に単純なクラスを使用します。UILabel単一のインスタンスを含む各セル(ストーリーボードの Ctrl キーを押しながらテーブル ビューのセル@IBOutletからドラッグして作成)。UILabel

// 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)
    }

}

最後に、テーブル ビュー セルからアクセスされるビュー コントローラーの場合: ユーザーのテキスト入力に使用される単一@IBOutletの をUITextField使用し、既存の を使用してこのテキスト フィールドのイベントを処理します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 間の通信のコンテナーとして機能する文字列プロパティ ( ) も宣言しています。

ストーリーボードに戻り、---アイデンティティ インスペクタから--- 3 つのストーリーボード オブジェクト ( Table View ControllerView ControllerTableViewCell) を、上で記述した関連クラスに関連付けます。

これでほぼ目標に到達しました。あとは、2 つのコントローラー間の通信方法を指定するだけです。

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送信者セルで現在占有されている既存のテキストを ( String 配列で指定されているように) 持ち込むことができますuserTextLabelsViewController.swiftviewDidLoad(...)メソッドを見て、この値が VC1 からどのように渡され、VC2 でデフォルト テキストとして設定されるかを確認します。UITextField

ここで、あなたが求めていた特定の通信方向である通信 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と、セグエのソースであったビュー コントローラーのプロパティ、つまり、この場合は のインスタンスを取得するアンワインド アクションを定義しますViewController。しかし、このアクションをトリガーするにはどうすればよいでしょうか。

絵コンテと に戻りView Controllerます。オブジェクトの上部にある 3 つの小さなアイコンに注意してください。View Controller具体的には、これらの最も右にあるExit. ButtonCtrl キーを押しながらアクションをExitアイコンにドラッグし、unwindToTableViewアクション セグエを選択します。ビューコントローラーのボタンをクリックすると、ビューが巻き戻され (終了し)、 のunwindToTableViewメソッドに着陸しTableViewControllerます。

結果のアプリは次のようになります。

enter image description here


これは私が予想していたよりもずっと長くなりましたが、書き始めると... とにかく、上記の方法は、当然、グローバル変数を使用しませんが、将来 ( prepareForSegue) または履歴 ( unwindToTableView) ビューへの参照を使用して (通常は現在または過去のビュー) または設定 (通常は現在または将来のビュー) の値を、これらの参照 (将来/履歴ビューへ) を使用して設定します。

Apple には、tableviewcontroller/viewcontroller コンテキストのサンプル アプリに関する非常に詳細なチュートリアルがあり、参照することをお勧めします。Swift のコーディングを始めたとき、私自身が非常に価値があると感じました。

iOS アプリの開発を開始する (Swift)

于 2015-12-14T20:05:41.300 に答える