Отправка данных из TableView в DetailView Swift
Я пытаюсь сделать, возможно, одну из самых простых и более запутанных вещей для меня до сих пор, я хочу разработать свое собственное приложение, и для этого мне нужно иметь возможность передавать некоторую информацию в зависимости от того, какой пользователь щелкает по строке (это Swift lenguage)
У нас есть RootViewController(табличное представление) и DetailViewController (с 1 меткой и 1 изображением)
(наш взгляд)
Вот код:
@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, но я пробовал много разных способов сделать это возможным, и все работает нормально
Как мы можем сделать это???
4 ответа
Вот пример для вас:
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
}
}
Это может быть другое решение, без большого кода в методе 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]
}
}
}
Если вы перетащите переход из ячейки прототипа (в Интерфейсном Разработчике) на свой следующий 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
,
Это просто, я добавляю одно утверждение к ответу выше. Чтобы получить название выбранного автомобиля в метке подробного просмотра,
lblDetail.text = passValue
Вы можете добавить этот код строки в функцию viewDidLoad() вашего детального представления. Переданное значение содержит имя машины, которую выбрал пользователь (назначить в prepareForSegue), после чего вы можете присвоить ее метку подробного просмотра.
Надеюсь, поможет!!