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

Этот класс не является ключевым значением, совместимым с кодировкой для отмены ключа

Я продолжаю получать эту ошибку: Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<FoodTracker.MealViewController 0x7faa9ed189d0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key cancel.'

Я пытаюсь завершить руководство разработчика Apple, чтобы начать работу с приложениями iOS. Мой код и раскадровка выглядят точно так же, как в файле примера. Я надеюсь, что свежий глаз может увидеть что-то, чего я не вижу?

import UIKit
import os.log

class MealViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    //MARK: Properties
    @IBOutlet weak var nameTextField: UITextField!
    @IBOutlet weak var photoImageView: UIImageView!
    @IBOutlet weak var ratingControl: RatingControl!
    @IBOutlet weak var saveButton: UIBarButtonItem!
    /*
     This value is either passed by 'MealTableViewController' in
     'prepare(for:sender) or constructed as part of adding a new meal.
    */
    var meal: Meal?

    override func viewDidLoad() {
        super.viewDidLoad()

        // Handle the text field user input through delegate callbacks
        nameTextField.delegate = self

        // Enable save button only if text field has valid Meal name
        updateSaveButtonState()
    }

    //MARK: UITextFieldDelegate
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // Hide the keyboard
        textField.resignFirstResponder()
        return true
    }
    func textFieldDidEndEditing(_ textField: UITextField) {
        updateSaveButtonState()
        navigationItem.title = textField.text
    }
    func textFieldDidBeginEditing(_ textField: UITextField) {
        // Disable save button while editing
        saveButton.isEnabled = false
    }

    //MARK: UIImagePickerControllerDelegate
    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        // Dismiss the picker if the user canceled
        dismiss(animated: true, completion: nil)
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
        // The info dictionary may contain multiple representations of the image. You want to use the original.
        guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
            fatalError("Expected a dictionary containing an image, but was provided the following: \(info)")
        }
        // Set photoImageView to display the selected image
        photoImageView.image = selectedImage
        // Dismiss the picker
        dismiss(animated: true, completion: nil)
    }

    //MARK: Navigation
    @IBAction func cancel(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }


    // Configure view controller before it presented
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        super.prepare(for: segue, sender: sender)

        // Configure destination view controller only when save button pressed
        guard let button = sender as? UIBarButtonItem, button === saveButton else {
            os_log("The save button was not pressed, cancelling", log: OSLog.default, type: .debug)
            return
        }

        let name = nameTextField.text ?? ""
        let photo = photoImageView.image
        let rating = ratingControl.rating

        // Set meal to be passed to MealTableViewController after unwind segue
        meal = Meal(name: name, photo: photo, rating: rating)
    }

    //MARK: Actions
    @IBAction func selectImageFromPhotoLibrary(_ sender: UITapGestureRecognizer) {
        // Hide the keyboard
        nameTextField.resignFirstResponder()
        // UIImagePickerController is a view controller that lets a user pick media from their photo library
        let imagePickerController = UIImagePickerController()
        // Only allow photos to be picked, not taken
        imagePickerController.sourceType = .photoLibrary
        // Make sure ViewController is notified when the user picks an image
        imagePickerController.delegate = self
        present(imagePickerController, animated: true, completion: nil)
    }

    //MARK: Private Methods
    private func updateSaveButtonState() {
        // Disable the save button if the text field is empty
        let text = nameTextField.text ?? ""
        saveButton.isEnabled = !text.isEmpty
    }
}

Есть еще несколько файлов, но, пожалуйста, просто дайте мне знать, что вам нужно, потому что я очень новичок в Swift/XCode и не уверен, что предоставлять/не предоставлять.

4b9b3361

Ответ 1

Это означает, что у вас есть что-то на вашем раскадровке, связанное с IBOutlet, которое называется cancel но у вас нет этого IBOutlet в вашем классе. Поэтому компилятор не может найти Key cancel (это свойство) в вашем классе. Вы должны найти эту кнопку (я думаю, это UIButton из-за имени) в раскадровке, щелкните правой кнопкой мыши на ней и нажмите "x", чтобы удалить это соединение. Или вы можете вообще удалить эту кнопку. Или вы можете добавить этот IBOutlet в свой класс.

Ответ 2

Я согласен с тем, что Алекс Шубин упомянул в своем ответе, - это эффективное решение, подобное "искать любые соединения, которые больше не существуют и удалить их". У меня была такая же проблема, и его предложение исправило эту ошибку. Для тех, кто новичок в программировании, и Xcode, как я, может оказаться полезным немного больше информации о том, как найти кнопку x в раскадровке.

Нажмите на желтый круг в верхней части контроллера вида в раскадровке.

enter image description here

Затем покажите инспектор соединений в правом верхнем углу панели служебных программ. Инспектор соединений - это меню справа, кружок с правой стрелкой. Щелкните это, и вы увидите все подключения для этого контроллера.

Я включаю скриншот того, что выглядит в моем приложении.

enter image description here

Ответ 3

Проверьте имя модуля в разделе "Identity Inspector". Необходимо выбрать либо имя модуля, либо "Наследовать модуль из цели". Если имеется несколько модулей, выберите соответствующий.