Подтвердить что ты не робот

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.

Спасибо

4b9b3361

Ответ 1

Передача данных между двумя контроллерами представлений зависит от того, как контроллеры представления связаны друг с другом. Если они связаны с segue, вам нужно будет использовать метод performSegueWithIdentifier и переопределить метод 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) 
}

Ответ 2

Вы спросили:

Как получить метку ячейки при ее выборе, а затем передать ее другому ViewController?

Я мог бы предложить перефразировать вопрос следующим образом: "Как получить данные, связанные с выбранной ячейкой, и передать их другому контроллеру представления?"

Это может звучать как одно и то же, но здесь есть важное концептуальное различие. Вы действительно не хотите извлекать значение из метки ячейки. В наших приложениях используется парадокс MVC, поэтому, когда вы хотите передать данные из одной сцены в другую, вы хотите вернуться к model (массив items), а не представление (свойство text UILabel).

Это тривиальный пример, поэтому это различие немного академическое, но по мере усложнения приложений эта модель возврата к модели становится все более важной. Строковое представление из ячейки обычно является плохой заменой для реальных объектов модели. И, как вы увидите ниже, так же легко (если не проще) извлекать данные из модели, поэтому вы должны просто сделать это.

В целом, в этом случае вам вообще не нужен метод didSelectRowAtIndexPath. Все, что вам нужно, это segue из ячейки представления таблицы в целевую сцену, дать segue уникальный идентификатор (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 см. предыдущую версию этого ответа.

Ответ 3

Хорошо. Было 2 дня. Я искал ответ, что как можно сохранить выбранные текстовые данные метки UITableViewCell и отобразить эти данные на другой ярлык на другом контроллере просмотра, который выйдет после нажатия на клетка. Наконец, я завершил задачу и ее успех. Вот полный код с шагами с использованием Swift.Я использую Xcode 6.4.

Шаг 1.

У меня есть два класса, назначенные контроллерам представлений раскадровки с именем "iOSTableViewControllerClass.swift", который является диспетчером представления таблиц и "iOSTutorialsViewControllerClass.swift", который является обычным View Controller.

Шаг 2.

Теперь сделайте segue из iOSTableViewControllerClass в iOSTutorialsViewControllerClass, перетаскивая элемент управления в области раскадровки и выберите "показать" в раскрывающемся меню. Нажмите на эту выделенную кнопку в соответствии с приведенным ниже изображением и выполните сеанс.

Сделать Segue, выбрав этот значок, перетащить управление в другое представление Controller

Шаг 3.

Теперь выберите сегмент, нажав на раскадровку и дайте ей идентификатор в Инспекторе атрибутов. В этом случае я назвал его "iOSTutorials"

Выберите Segue в раскадровке и назовите его

Шаг 4.

Теперь на этом шаге поместите ярлык на вашу ячейку, а также на другой контроллер представления и сделайте выходы из них на соответствующих классах.  В моем случае это "@IBOutlet weak var iOSCellLbl: UILabel!" и "@IBOutlet слабый var iOSTutsClassLbl: UILabel!".

Шаг 5.

Создайте переменную типа строки в первом классе контроллера таблиц. Я сделал это как "var sendSelectedData = NSString()". Также создайте переменную типа string во втором классе. Я сделал это как "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 text on the second view controller
   iOSTutsClassLbl.text = SecondArray
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

Ответ 4

Я делаю это так.

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)



}