Swift: передать метку UITableViewCell новому ViewController
У меня есть UITableView, который заполняет ячейки данными, основанными на вызове JSON. вот так:
var items = ["Loading..."]
var indexValue = 0
// Here is SwiftyJSON code //
for (index, item) in enumerate(json) {
var indvItem = json[index]["Brand"]["Name"].stringValue
self.items.insert(indvItem, atIndex: indexValue)
indexValue++
}
self.tableView.reloadData()
Как получить метку ячейки, когда она выбрана, а затем передать ее другому ViewController?
Мне удалось получить:
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!;
println(currentCell.textLabel.text)
}
Я просто не могу понять, как передать это как переменную следующему UIViewController.
Спасибо
4 ответа
Передача данных между двумя контроллерами представления зависит от того, как контроллеры представления связаны друг с другом. Если они связаны с segue, вам нужно будет использовать метод executeSegueWithIdentifier и переопределить метод prepareForSegue.
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
}
}
Если ваш контроллер представления не связан с segue, то вы можете передавать значения непосредственно из функции tableView
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!;
let storyboard = UIStoryboard(name: "YourStoryBoardFileName", bundle: nil)
var viewController = storyboard.instantiateViewControllerWithIdentifier("viewControllerIdentifer") as AnotherViewController
viewController.passedValue = currentCell.textLabel.text
self.presentViewController(viewContoller, animated: true , completion: nil)
}
Вы спрашивали:
Как получить метку ячейки, когда она выбрана, а затем передать ее другому ViewController?
Я мог бы предложить перефразировать вопрос следующим образом: "Как получить данные, связанные с выбранной ячейкой, и передать их другому контроллеру представления?"
Это может звучать так же, но здесь есть важное концептуальное различие. Вы действительно не хотите получать значение из метки ячейки. Наши приложения используют парадигму MVC, поэтому, когда вы хотите передать информацию о данных из одной сцены в другую, вы хотите вернуться к модели (items
массив), а не вид (text
собственность UILabel
).
Это тривиальный пример, поэтому это различие немного академично, но по мере усложнения приложений эта модель возврата к модели становится все более важной. Строковое представление из ячейки, как правило, является плохой заменой фактических объектов модели. И, как вы увидите ниже, получить данные из модели так же просто (если не проще), так что вы должны просто сделать это.
Кроме того, вам не нужно didSelectRowAtIndexPath
Метод вообще в этом случае. Все, что вам нужно, это перейти от ячейки табличного представления к сцене назначения, дать этому переходу уникальный идентификатор (Details
в моем примере), а затем реализовать prepare(for:sender:)
:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DetailsViewController {
let selectedRow = tableView.indexPathForSelectedRow!.row
destination.selectedValue = items[selectedRow]
}
}
Кроме того, если ваш переход между ячейкой и сценой назначения, вы также можете использовать sender
из prepare(for:sender:)
:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let destination = segue.destination as? DetailsViewController {
let cell = sender as! UITableViewCell
let selectedRow = tableView.indexPath(for: cell)!.row
destination.selectedValue = items[selectedRow]
}
}
Но идея та же самая. Определите, какая строка была выбрана, и получите информацию из модели, items
массив.
Выше Swift 3. Для Swift 2.3, пожалуйста, смотрите предыдущую версию этого ответа.
Хорошо... Прошло 2 дня, я искал ответ, как я могу сохранить выбранные текстовые данные метки UITableViewCell и отобразить эти данные в другую метку на другом View Controller, который появится после нажатия на ячейку. Наконец-то я выполнил задание и его успешно. Вот полный код с шагами, использующими Swift. Я использую Xcode 6.4.
Шаг 1.
У меня есть два класса, назначенных контроллерам представления раскадровки с именем "iOSTableViewControllerClass.swift", который является контроллером табличного представления, и "iOSTutorialsViewControllerClass.swift", который является обычным контроллером представления.
Шаг 2.
Теперь перейдите от iOSTableViewControllerClass к iOSTutorialsViewControllerClass, перетащив Control в области раскадровки, и выберите "показать" из выпадающего меню. Нажмите на эту выделенную кнопку в соответствии с изображением ниже и выполните переход.
Шаг 3.
Теперь выберите переход, щелкнув по раскадровке и присвоив ей идентификатор в Инспекторе атрибутов. В этом случае я назвал его "iOSTutorials"
Шаг 4
Теперь на этом шаге поместите метку на вашу ячейку, а также на другой контроллер представления и сделайте из них выходы в соответствующих классах. В моем случае это "@IBOutlet слабая переменная iOSCellLbl: UILabel!" и "@IBOutlet слабая переменная iOSTutsClassLbl: UILabel!".
Шаг 5
Создайте переменную строкового типа в первом классе контроллера табличного представления. Я сделал это как "var sendSelectedData = NSString()" и сделал переменную строкового типа во втором классе. Я сделал это как "var SecondArray:String!".
Шаг 6
Теперь мы готовы к работе. Вот полный код для первого класса -
// iOSTableViewControllerClass.swift
import UIKit
class iOSTableViewControllerClass: UITableViewController, UITableViewDataSource,UITableViewDelegate {
// Creating A variable to save the text from the selected label and send it to the next view controller
var sendSelectedData = NSString()
//This is the outlet of the label but in my case I am using a fully customized cell so it is actually declared on a different class
@IBOutlet weak var iOSCellLbl: UILabel!
//Array for data to display on the Table View
var iOSTableData = ["Label", "Button", "Text Field", "Slider", "Switch"];
override func viewDidLoad() {
super.viewDidLoad()
//Setting the delegate and datasource of the table view
tableView.delegate = self
tableView.dataSource = self
//Registering the class here
tableView.registerClass(CustomTableViewCellClassiOS.self, forCellReuseIdentifier: "CellIDiOS")
//If your using a custom designed Cell then use this commented line to register the nib.
//tableView.registerNib(UINib(nibName: "CellForiOS", bundle: nil), forCellReuseIdentifier: "CellIDiOS")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return iOSTableData.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let CellIDentifier = "CellIDiOS"
//In this case I have custom designed cells so here "CustomTableViewCellClassiOS" is the class name of the cell
var cell:CustomTableViewCellClassiOS! = tableView.dequeueReusableCellWithIdentifier(CellIDentifier, forIndexPath: indexPath) as? CustomTableViewCellClassiOS
if cell == nil{
tableView.registerNib(UINib(nibName: "CellForiOS", bundle: nil), forCellReuseIdentifier: CellIDentifier)
cell = tableView.dequeueReusableCellWithIdentifier(CellIDentifier) as? CustomTableViewCellClassiOS
}
//Here we are displaying the data to the cell label
cell.iOSCellLbl?.text = iOSTableData[indexPath.row]
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("You selected cell #\(indexPath.row)!")
// Get Cell Label text here and storing it to the variable
let indexPathVal: NSIndexPath = tableView.indexPathForSelectedRow()!
println("\(indexPathVal)")
let currentCell = tableView.cellForRowAtIndexPath(indexPathVal) as! CustomTableViewCellClassiOS!;
println("\(currentCell)")
println("\(currentCell.iOSCellLbl?.text!)")
//Storing the data to a string from the selected cell
sendSelectedData = currentCell.iOSCellLbl.text!
println(sendSelectedData)
//Now here I am performing the segue action after cell selection to the other view controller by using the segue Identifier Name
self.performSegueWithIdentifier("iOSTutorials", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
//Here i am checking the Segue and Saving the data to an array on the next view Controller also sending it to the next view COntroller
if segue.identifier == "iOSTutorials"{
//Creating an object of the second View controller
let controller = segue.destinationViewController as! iOSTutorialsViewControllerClass
//Sending the data here
controller.SecondArray = sendSelectedData as! String
}
Вот полный код для второго класса..--
// iOSTutorialsViewControllerClass.swift
import UIKit
class iOSTutorialsViewControllerClass: UIViewController {
//Creating the Outlet for the Second Label on the Second View Controller Class
@IBOutlet weak var iOSTutsClassLbl: UILabel!
//Creating an array which will get the value from the first Table View Controller Class
var SecondArray:String!
override func viewDidLoad() {
super.viewDidLoad()
//Simply giving the value of the array to the newly created label's text on the second view controller
iOSTutsClassLbl.text = SecondArray
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Я делаю это так.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let selectedName = nameArray[indexPath.row]
let newView: nextViewName = self.storyboard?.instantiateViewController(withIdentifier: "nextViewName") as! nextViewName
newView.label.text = selectedValue
self.present(newView, animated: true, completion: nil)
}