2017-02-21 43 views
0

Начинающий здесь, это мой первый снимок при использовании делегата, и я довольно смущен - я пытаюсь передать данные между двумя контроллерами, первым из которых является отображение таблицы некоторые продукты, а другой - модальный вид, который позволяет пользователю вводить новый продукт, который будет отображаться в этом представлении таблицы. Когда пользователь нажимает «Сохранить» в модальном представлении, я хочу сохранить новый продукт в основные данные и отобразить его в виде таблицы.Использование делегата для сохранения значений для основных данных

Пользователь вводит информацию в трех текстовых полей в AddProductController (вид модальный), а затем попадает сохранить, который называет handleSave:

func handleSave() { 

    guard let newProductUrl = self.urlTextField.text else { 
     print("error getting text from product url field") 
     return 
    } 
    guard let newProductName = self.nameTextField.text else { 
     print("error getting text from product name field") 
     return 
    } 
    guard let newProductImage = self.logoTextField.text else { 
     print("error getting text from product logo field") 
     return 
    } 

    DispatchQueue.main.async { 
     self.productSaveDelegate?.save(name: newProductName, url: newProductUrl, image: newProductImage) 

     let companyController = CompanyController() 
     self.navigationController?.pushViewController(companyController, animated: true) 
    } 

} 

Который в свою очередь, вызывает save в ProductController (TableView):

func save(name: String, url: String, image: String) { 

    guard let appDelegate = 
     UIApplication.shared.delegate as? AppDelegate else { 
      return 
    } 

    let managedContext = 
     appDelegate.persistentContainer.viewContext 

    let entity = 
     NSEntityDescription.entity(forEntityName: "Product", 
            in: managedContext)! 

    let product = NSManagedObject(entity: entity, 
            insertInto: managedContext) 


    product.setValue(name, forKey: "name") 
    product.setValue(url, forKey: "url") 
    product.setValue(image, forKey: "image") 


    do { 
     try managedContext.save() 
     products.append(product) 
    } catch let error as NSError { 
     print("Could not save. \(error), \(error.userInfo)") 
    } 
    tableView.reloadData() 
} 

Если я правильно понимаю, я использую делегат как своего рода ссылку между ними, чтобы я мог передавать введенные пользователем значения непосредственно в мой save functio п? Исправьте меня, если я ошибаюсь. Я довольно новый. Но я создаю делегат вне области видимости класса в верхней части ProductController (контроллер TableView) следующим образом:

protocol ProductSaveDelegate { 
    func save(name: String, url: String, image: String) 
} 

Тогда в AddProductController (модальный вид, в котором пользователь вводит информацию о новых продуктах) инициализирует делегат рядом в верхней части класса:

var productSaveDelegate: ProductSaveDelegate? 

И затем использовать его, чтобы вызвать функцию save в handleSave(), как показано выше.

Когда я пытаюсь добавить ProductSaveDelegate к определению класса AddProductController Я получаю сообщение об ошибке AddProductController не соответствует протоколу.

Что я могу изменить здесь, чтобы правильно ввести данные пользователя в данные ядра? Заранее благодарю за любую помощь!

+0

Убедитесь, что ваш ** AddProductController ** выглядит следующим образом: 'class AddProductController: UIViewController, ProductSaveDelegate {}', и вы должны реализовать метод протокола в этом классе, который является 'func save (name: String, url: String, image: String) ' –

ответ

0

Делегаты действительно классные и могущественные, но иногда, да, они могут ввести в заблуждение. Вам необходимо инициализировать делегат внутри ProductController, а не AddProductController.

Это большое изображение, которое показывает, как работает делегат и протокол установка:

enter image description here

Изображение от Andrew Банкрофта website

В этом случае, ваш делегат ваш ProductController и ваш доверитель является ваш AddProductController

0

УБЕДИТЕСЬ, ЧТО ВЫ ПОДПИСЫЛИ ДЕЛЕГАЦИИ

НЕ забывайте -

classObject.Делегат = само

Я полагаю, вы уже знакомы с делегатами,

Вы получаете эту ошибку, потому что, либо у вас есть not implemented the delegate method от AddProductController (в вашем случае является ложным, так как я могу видеть он реализован), или вы забыли подписаться делегата, чтобы сделать это вам нужно, чтобы убедиться -

  1. Подписавшись делегат, то есть, прежде чем перейти к следующему набору контроллера делегат к себе, как -

также в том же классе вы должны реализовать метод, определенный в протоколе, т.е. func save(name: String, url: String, image: String) в вашем случае (уже реализовано)

Вы также можете проверить a small demo, я выполнил здесь протоколы.