it-roy-ru.com

Отправка данных из TableView в DetailView Swift

Я пытаюсь сделать, возможно, одну из самых простых и более запутанных вещей для меня до сих пор Я хочу разработать свое собственное приложение, и для этого мне нужно иметь возможность передавать некоторую информацию в зависимости от того, какой пользователь щелкнул по строке (это быстрый язык)

У нас есть RootViewController (табличное представление) и 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()
    }

Вопрос в том: 

если пользователь щелкнет Ferrari 458, lblDetail в DetailViewController покажет: Ferrari 458 - это суперкар, способный развивать скорость до 325 км/ч ...... (что бы мы ни хотели) и imgDetail будет в состоянии показать изображение (что мы хотим) автомобиля

Если пользователь щелкнет Bugatti Veyron, теперь lblDetail покажет нам: Bugatti Veyron - идеальная и супер спортивная машина. Это один из самых быстрых автомобилей в мире ....

imgDetail покажите нам изображение этого автомобиля

То же самое со всеми автомобилями, в зависимости от того, какую строку мы нажали

Я знаю, что работа идет вокруг функции prepareForSegue в первом View Controller, но я пробовал много разных способов сделать это возможным, и все работает нормально

Как мы можем сделать это ???

17
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 в другой, и вы можете передавать данные в этом примере по мере необходимости.

А для получения дополнительной информации обратитесь по этой ссылке.

Передача значений между ViewControllers на основе выбора списка в Swift

Использовали ли didSelectRowAtIndexPath или метод prepareForSegue для UITableView?

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
    }
}
39
Dharmesh

Это может быть другое решение, без большого количества кода в методе didSelectRowAtIndexPath . Обратите внимание, что, хотя он может выглядеть чище, и нам не нужна дополнительная переменная valueToPass, это не может быть наилучшей практикой, поскольку аргумент отправителя внутри метода executeSegue должен быть фактическим объектом, который инициировал переход (или ноль).

// 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]
        }
    }
}
3
ppalancica

Если вы перетащите переход из ячейки прототипа (в Интерфейсном Разработчике) на свой следующий View Controller и установите для его идентификатора перехода значение «Ваш идентификатор перехода», вы также можете сделать это с помощью этого ярлыка:

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(), ни этот метод табличного представления.

В PushedViewController.Swift (следующий View Controller):

var valueToPass: String!

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

Важно установить значение метки после она инициализируется из раскадровки. Это означает, что вы не можете установить метку непосредственно в prepareForSegue() предыдущего Контроллера представления, поэтому необходимо передать ее с помощью valueToPass.

1
Teodor Ciuraru

Это просто, я добавляю одно утверждение к вышеуказанному ответу . Чтобы получить название выбранного автомобиля в подробном ярлыке вида,

lblDetail.text = passValue

вы можете добавить этот код строки в функцию viewDidLoad () вашего детального представления. Переданное значение содержит имя машины, которую выбрал пользователь (назначить в prepareForSegue), после чего вы можете присвоить ее метку подробного просмотра.

Надеюсь, поможет!!

0
Pruthvi Hariharan