web-dev-qa-db-ja.com

TableViewからDetailViewにデータを送信Swift

私は今まで自分のために最も簡単でわかりにくいものの1つをしようとしています。自分のアプリを開発したいのですが、それを行うには、どの行のユーザーのクリック(= Swift lenguage)

RootViewController(table view)とDetailViewController(1つのラベルと1つの画像)があります enter image description here

(私たちの見解)

コードは次のとおりです。

@IBOutlet weak var tableView: UITableView!


var vehicleData : [String] = ["Ferrari 458" , "Lamborghini Murcielago" , "Bugatti Veyron", "Mercedes Benz Biome"]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    var nib = UINib(nibName: "TableViewCell", bundle: nil)

    tableView.registerNib(nib, forCellReuseIdentifier: "cell")



}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return vehicleData.count
}



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


    let cell:TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as TableViewCell

    cell.lblCarName.text = vehicleData[indexPath.row]

    cell.imgCar.image = UIImage(named: vehicleData[indexPath.row])

    return cell   
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    performSegueWithIdentifier("DetailView", sender: self)
}

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

    if(segue.identifier == "DetailView") {

        var vc = segue.destinationViewController as DetailViewController

    }

}

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return 100
}

カスタムTableViewCellクラス(セルを含むxibファイルを持っています)

class TableViewCell: UITableViewCell {


@IBOutlet weak var lblCarName: UILabel!

@IBOutlet weak var imgCar: UIImageView!

override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

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

    // Configure the view for the selected state
}

class DetailViewController: UIViewController {



    @IBOutlet weak var lblDetail: UILabel!

    @IBOutlet weak var imgDetail: UIImageView!

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

質問は:

ユーザーがフェラーリ458をクリックすると、DetailViewControllerのlblDetailに次のように表示されます。車の欲しい)

ユーザーがBugatti Veyronをクリックすると、lblDetailに次のように表示されます。Bugatti Veyronは完璧なスーパースポーツマシンです。それは世界最速の車の一つです。

imgDetailはこの車の画像を表示します

クリックした行に応じてすべての車で同じこと

私は仕事が最初のView ControllerのprepareForSegue funcに関するものであることを知っていますが、それを可能にするためにさまざまな方法を試していましたが、何もうまくいきません

どのようにこれを行うことができますか???

19
FactorJose

以下に例を示します。

var valueToPass:String!

func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
    println("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell

    valueToPass = currentCell.textLabel.text
    performSegueWithIdentifier("yourSegueIdentifer", sender: self)
}

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

    if (segue.identifier == "yourSegueIdentifer") {
        // initialize new view controller and cast it as your view controller
        var viewController = segue.destinationViewController as AnotherViewController
        // your new view controller should have property that will store passed value
        viewController.passedValue = valueToPass
    }
}

ただし、passedValue変数をDetailViewControllerに作成することを忘れないでください。

これは、あるviewControllerから別のviewControllerにデータを渡す例に過ぎず、必要に応じてこの例でデータを渡すことができます。

詳細については、このリンクを参照してください。

Swiftでのリスト選択に基づいたViewController間の値の受け渡し

ITableViewにはdidSelectRowAtIndexPathまたはprepareForSegueメソッドを使用しますか?

Swift:UITableViewCellラベルを新しいViewControllerに渡す

https://teamtreehouse.com/forum/help-Swift-segue-with-variables-is-not-working

これが役に立つかもしれません。

Swift 3.0

var valueToPass:String!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell

    valueToPass = currentCell.textLabel?.text
    performSegue(withIdentifier: "yourSegueIdentifer", sender: self)
}

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

    if (segue.identifier == "yourSegueIdentifer") {
        // initialize new view controller and cast it as your view controller
        var viewController = segue.destination as! AnotherViewController
        // your new view controller should have property that will store passed value
        viewController.passedValue = valueToPass
    }
}
40
Dharmesh

これは、didSelectRowAtIndexPathメソッドに多くのコードを使用しない別のソリューションかもしれません。よりきれいに見えるかもしれませんが、余分な変数valueToPassは必要ありませんが、performSegueメソッド内の送信側引数はセグエ(またはnil)を開始した実際のオブジェクトであると想定されるため、ベストプラクティスではない場合があります。

// MARK: UITableViewDelegate methods

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)

    performSegue(withIdentifier: "goToSecondVC", sender: indexPath)
}

// MARK: UIViewController methods

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "goToSecondVC" {    
        if segue.destination.isKind(of: CarDetailsController.self) {
            let secondVC = segue.destination as! CarDetailsController

            let indexPath = sender as! IndexPath

            secondVC.passedValue = carsArray[indexPath.row]
        }
    }
}
4
ppalancica

インターフェースビルダーの)プロトタイプセルから次のView Controllerにセグエをドラッグし、そのセグエ識別子を「Your Segue Identifier」に設定する場合は、次のショートカットでも実行できます。

_override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "Your Segue Identifier" {
        let cell = sender as! YourCustomCell
        let vc = segue.destination as! PushedViewController
        vc.valueToPass = cell.textLabel?.text // or custom label
    }
}
_

また、performSegueWithIdentifier()didSelectRowAtIndexPath()も、このTable Viewメソッドも必要ありません。

_PushedViewController.Swift_(次のView Controller):

_var valueToPass: String!

override func viewDidLoad() {
    super.viewDidLoad()
    yourLabel.text = valueToPass
}
_

ラベルの値を設定することが重要ですafter Storyboardから初期化されます。つまり、前のView ControllerのprepareForSegue()でラベルを直接設定できないため、valueToPassで渡す必要があります。

1
Teodor Ciuraru

その簡単な、上記の答えに1つのステートメントを追加しています。詳細ビューラベルで選択した車の名前を取得するには、

lblDetail.text = passedValue

この行のコードを詳細ビューのviewDidLoad()funcに追加できます。 passingValueには、ユーザーが選択した車の名前が含まれ(prepareForSegueで割り当て)、detailedViewラベルに割り当てることができます。

それが役に立てば幸い!!

0