質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.80%

favTableViewのエラー 「this class is not key value coding-compliant for the key favTableView.」 の解決方法

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 313

shuntar30

score 69

実現したいこと

Swiftで折り紙の折り図を表示するアプリを作っているのですが、UITabBarの「お気に入り」を押すと、「this class is not key value coding-complant for tha key favTableView.」というエラーが出て困っています。回答お願いします。
「お気に入り」ボタン

試したこと

  • Outlet接続を確認して、つなぎ直した
  • SwiftのソースコードでもDelegateとDataSourceをSelfにした
  • 名前が半角英字かを確認した -> 半角英字だった
  • 変数を宣言しているところを消して、もう一度入れ直した
  • StoryBoardでTableViewを消して、もう一度ドラッグした

できることは全部やったつもりですが、ダメでした。

エラーメッセージ

2020-04-20 11:57:08.639195+0900 Origami[5967:370916] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UIViewController 0x100e1e9a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key favTableView.'
*** First throw call stack:
(0x1a4c755f0 0x1a4997bcc 0x1a4b7a9e8 0x1a4f5b0bc 0x1a86d7ad0 0x1a89b8148 0x1a4b50ba0 0x1a89b5300 0x1a86de86c 0x1a86df2e4 0x1a86df59c 0x1a86522dc 0x1a86525fc 0x1a86534a0 0x1a8654790 0x1a8637cf0 0x1db692fb0 0x1a91cec7c 0x1ab7684ac 0x1ab76e604 0x1ab779148 0x1ab6c1e34 0x1ab6eb7c4 0x1a8d18f40 0x1a8dbbba4 0x1a8dbbbfc 0x1a8dbbbfc 0x1a8db38d0 0x1a4bf3b64 0x1a4bf3abc 0x1a4bf3244 0x1a4bee274 0x1a4bedc34 0x1aed3738c 0x1a8d2022c 0x1008b18dc 0x1a4a75800)
libc++abi.dylib: terminating with uncaught exception of type NSException

ソースコード

FavoriteViewController.swift

//
//  FavoriteViewController.swift
//  Origami
//
//  Created by ________ ________ on 4/16/20.
//  Copyright © 2020 ________ ________. All rights reserved.
//

import UIKit
import os.log

class FavoriteViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

    // テーブルビューインスタンス
    @IBOutlet weak var favTableView: UITableView!  // ここがおかしいのか?

    // (func prepare) に (indexPath.row) を渡すための変数
    var index: String?

    // テーブルビューに表示する配列
    private var items: Array<String> = []

    // 検索結果が入る配列
    private var searchResult: Array<String> = []

    // Documentsディレクトリのパスを取得
    let documentPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].absoluteString

    func fav(path: String) {
        let fav = try? FileManager.default.contentsOfDirectory(atPath: path)

        guard let favorite = fav else {
            os_log("=> \nNo name to submit")
            return
        }

        if favorite.count != 0 {
            for value in favorite {
                items.append(value)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        print("FavVC")

        fav(path: documentPath)

        favTableView.delegate = self
        favTableView.dataSource = self

        favTableView.reloadData()

    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }

    // MARK: - TableView Delegate Methods

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        os_log("=> \ntableView")
        print("tableView() -> Int")
        print("")
        return searchResult.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        os_log("=> \ntableView")
        print("tableView() -> UITableViewCell")
        print("")
        // セルを取得する
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "FavoriteCell", for: indexPath)

        fav(path: documentPath)

        // セルに表示する値を設定する
        cell.textLabel!.text = items[indexPath.row]
        cell.textLabel!.font = UIFont(name: "system", size: 28)

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.index = items[Int(indexPath.row)]
        self.performSegue(withIdentifier: "FavoriteSegue", sender: nil)
    }

    // MARK: - prepare

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "FavoriteSegue" {
            if let origamiView: OrigamiView = segue.destination as? OrigamiView {
                origamiView.image = UIImage(imageLiteralResourceName: self.index! + ".png")
                origamiView.titleText = self.index!
                os_log("=> \nSegue to OrigamiVC")
                print("\(self.index!) selected")
                print("titleText: \(self.index!)")
                print("image: \(self.index!).png")
                print("")
            }
        }
    }

}


ViewController.swift

//
//  ViewController.swift
//  Origami
//
//  Created by ________ ________ on 4/16/20.
//  Copyright © 2020 ________ ________. All rights reserved.
//

import UIKit
import os.log

class ViewController: UIViewController, UISearchBarDelegate, UITableViewDelegate, UITableViewDataSource {

    // MARK: - Variables

    // SearchBarインスタンス
    @IBOutlet weak var searchBar: UISearchBar!

    // テーブルビューインスタンス
    @IBOutlet weak var myTableView: UITableView!

    // (func prepare) に (indexPath.row) を渡すための変数
    var index: String?

    // テーブルビューに表示する配列
    private var items: Array<String> = []

    // 検索結果が入る配列
    private var searchResult: Array<String> = []

    // MARK: - Functions

    override func viewDidLoad() {
        super.viewDidLoad()

        print("HomeVC")

        // MARK: - ここに作品名を入力
        items = ["かみひこうき", "ぱんつ", "つる", "薗部式ユニット ユニット", "薗部式ユニット 組み方"]
        // MARK: - 作品名終了
        searchResult = items
        // MARK: TableView関連
        // デリゲートの設定
        searchBar.delegate = self

        myTableView.delegate = self
        myTableView.dataSource = self
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
    }

    // MARK: - 渡された文字列を含む要素を検索し、テーブルビューを再表示する
    func searchItems(searchText: String) {
        os_log("=> \nsearch")
        print("searchItems(searchText: \(searchText))")
        print("items: \(items)")
        searchResult.removeAll()
        //要素を検索する
        if searchText != "" {
            do {
                let c = items.count - 1
                var i = 0
                var searchWord = items[i]
                print("loop: \(c + 1)")
                while i <= c {
                    searchWord = items[i]
                    if searchWord.contains(searchText) {
                        searchResult.append(searchWord)
                        print("searchResult: \(searchResult)")
                    }
                    i += 1
                }
                print("Filter Succeeded")
            } catch {
                print("Filter Failed")
            }
        } else {
            //渡された文字列が空の場合は全てを表示
            searchResult = items
            print("All Show")
        }
        print("")
        //tableViewを再読み込みする
        do {
            try myTableView.reloadData()
            os_log("=> \nmyTableView.reloadData()")
            print("Reload Succeeded")
            print("")
        } catch {
            os_log("=> \nmyTableView.reloadData()")
            print("Reload Failed")
            print("")
        }
    }

    // MARK: - SearchBar Delegate Methods
    // テキストが変更される毎に呼ばれる
    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        //検索する
        searchItems(searchText: searchText)
    }

    // Searchボタンが押されると呼ばれる
    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        view.endEditing(true)
        //検索する
        searchItems(searchText: searchBar.text! as String)
    }

    // MARK: - TableView Delegate Methods

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        os_log("=> \ntableView")
        print("tableView() -> Int")
        print("")
        return searchResult.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        os_log("=> \ntableView")
        print("tableView() -> UITableViewCell")
        print("")
        // セルを取得する
        let cell: UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "OrigamiCell", for: indexPath)

        // セルに表示する値を設定する
        cell.textLabel!.text = searchResult[indexPath.row]
        cell.textLabel!.font = UIFont(name: "system", size: 28)

        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.index = searchResult[Int(indexPath.row)]
        self.performSegue(withIdentifier: "OrigamiView", sender: nil)
    }

    // MARK: - prepare

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "OrigamiView" {
            if let origamiView: OrigamiView = segue.destination as? OrigamiView {
                origamiView.image = UIImage(imageLiteralResourceName: self.index! + ".png")
                origamiView.titleText = self.index!
                os_log("=> \nSegue to OrigamiVC")
                print("\(self.index!) selected")
                print("titleText: \(self.index!)")
                print("image: \(self.index!).png")
                print("")
            }
        }
    }

}

開発環境

MacOS Catalina 10.15.4
Xcode11.4
Swift5

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+1

 '[<UIViewController 0x100e1e9a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key favTableView.'


このエラーですが、

[<FavoriteViewController ....


となっていないので、おそらくStoryboardでViewControllerのカスタムクラスを正しく設定できていないのだと思われます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/20 15:18

    回答ありがとうございます。

    キャンセル

  • 2020/04/20 15:54

    確認したところ、クラスはFavoriteViewControllerなっていたので、別の理由だと思います。

    キャンセル

  • 2020/04/20 15:58 編集

    あと、UIViewControllerなので、クラス名ではないと思います。

    キャンセル

checkベストアンサー

0

Storyboardでのセグエの設定の仕方

上記のリンクで、コード上でのperformで画面遷移するためには、Storyboard上での遷移元のUIViewControllerの上の左の〇のアイコンから、画面遷移先へCtrlを押しながらSegueを作らないとダメでだと思うのですが、それをしていないとかではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/04/21 13:34

    ありがとうございます。解決できました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.80%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • iOSに関する質問
  • favTableViewのエラー 「this class is not key value coding-compliant for the key favTableView.」 の解決方法