Swift 2 Нулевой делегат

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

Вот что у меня есть до сих пор:

//
//  DataTableViewController.swift
//  assignment8
//

import Foundation
import UIKit


class DataTableViewController: UITableViewController {

  var delegate:StudentSelectionDelegate! = nil
  var students = [Student]();
  var course = Course();

  // MARK: - UITableViewDataSource

  override func viewDidLoad() {
    super.viewDidLoad()

    tableView.delegate = self
    tableView.dataSource = self

  }

  func didSelectStudent(controller:UITableViewController, student:Student!) {

    controller.navigationController?.popViewControllerAnimated(true)

  }

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    self.course = courseStorage.getCourse();
    self.students = course.getArrayOfStudentSortedByLastName();
    return course.count;
  }


  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let row = indexPath.row
    let currentStudent = students[row];
    if (delegate != nil) {
      delegate.didSelectStudent(self,student:currentStudent)
    }
    else {
      print ("delegate is nil :(");
    }
    tableView.deselectRowAtIndexPath(indexPath, animated: true)
  }

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("studentCell", forIndexPath: indexPath)

    cell.textLabel?.text = students[indexPath.row].lastName + ", " +
      students[indexPath.row].firstName;
    return cell
  }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    print("ping");
    if segue.identifier == "studentSegue" {
      let nextScene =  segue.destinationViewController as! studentViewController
      // Pass the selected object to the new view controller.
      if let indexPath = self.tableView.indexPathForSelectedRow {
        let selectedStudent = students[indexPath.row]
        print (selectedStudent.firstName);
        nextScene.student = selectedStudent;
      }
    }
  }
}

а также

//
//  DataViewController.swift
//  assignment8
//

import UIKit



class DataViewController: UIViewController {

  @IBOutlet weak var dataLabel: UILabel!
  var dataObject: String = ""
  let tableData = ["One","Two","Three"];



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

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

  override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    self.dataLabel!.text = dataObject
  }

  func tableView(tableView: UITableView!, numberOfRowsInSection section: Int)
    -> Int {
    return self.tableData.count;
  }
}

а также

//
//  studentViewController.swift
//  assignment8
//

import UIKit

protocol StudentSelectionDelegate {
  func didSelectStudent(controller: UITableViewController, student:Student)
}

class studentViewController: UIViewController {

  var delegate = StudentSelectionDelegate.self;

  var name = String();
  var student = Student();


  @IBOutlet weak var StudentName: UILabel!
  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
  }

  func didSelectStudent(controller:UITableViewController, student:Student!) {
    student.description;
    print ("pong")
    StudentName.text = student.firstName + " " + student.lastName;

    controller.navigationController?.popViewControllerAnimated(true);
  }

  override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
  }
  //  override func viewWillAppear(animated: Bool) {
  //    StudentName.text = name
  //  }

}

моя раскадровка Пока это моя раскадровка.

Итак, каждый раз, когда я пытаюсь щелкнуть студента, он будет печатать сообщение, которое я решил использовать, если делегат равен нулю. До сих пор я пытался просмотреть все другие ответы на SO, но ни один из них не устранил мою проблему.


person Digits    schedule 08.12.2015    source источник
comment
Как вы создаете переходы от одного контроллера представления к другому? Вам нравится переход из табличного представления? Я не думаю, что это хорошая идея - вызывать tableview.didselectrowatindexpath внутри себя, может быть, вы хотите сделать это с помощью Performseguewithidentifier?   -  person Joel García Verástica    schedule 08.12.2015
comment
Вот как это было сделано в нескольких уроках, которым я следовал, например, здесь. makeapppie.com/2015/02/17/< /а>   -  person Digits    schedule 08.12.2015


Ответы (1)


Чтобы иметь возможность отправлять информацию с одного контроллера представления на другой, вы должны использовать переходы. Похоже, это то, что вы делаете в соответствии с изображением. Если вы не знаете, как использовать переход, вы можете найти хороший ответ здесь: Отправка данных с помощью Segue с помощью Swift

С помощью переходов вы сможете установить делегата следующего контроллера представления:

protocol MyDelegate {
     func myFunction()
}

class FirstViewController: UIViewController, MyDelegate {

    func myFunction() {
        // do what the function does
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if let secondVC = segue.destinationViewController as? SecondViewController {
            secondVC.delegate = self
        }
    }
}


class SecondViewController: UIViewController {
    var delegate: MyDelegate!
}

Прежде чем перейти ко второму контроллеру представления (вы готовитесь к переходу), вы устанавливаете для переменной делегата SecondViewController значение self, поскольку FirstViewController соответствует протоколу MyDelegate, поэтому его можно использовать там. Теперь в SecondViewController вы можете использовать delegate.myFunction(), и он будет делать все, что написано внутри функции FirstVC, потому что FirstVC является делегатом SecondVC.

person Aleksi Sjöberg    schedule 08.12.2015
comment
Спасибо, что сказали мне, что делегаты предназначены только для отправки данных обратно из другого представления, и что переходы — это то, что требуется для отправки данных в первую очередь! Я думал, что добавление перехода в мою раскадровку заставит моего делегата вызвать переход, но это не так! Теперь мне вообще не нужен делегат. - person Digits; 08.12.2015