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

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

ただいまの
回答率

88.92%

Swift3におけるpickerViewの作成

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,184

greenSIer

score 8

前提・実現したいこと

プログラミング初心者です。

以下のサイトを参考に、Xcodeを使用したiOSのアプリ開発で
PickerViewを使用した画面を作成したいと考えています。

参考にしているサイト↓
http://joyplot.com/documents/2017/03/21/swift-uipickerview/

発生している問題・エラーメッセージ

* Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<MapFinal.webViewPageViewController 0x7fc1b0e1bd80> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key picker.' * First throw call stack:
(
0   CoreFoundation                      0x0000000110743b0b __exceptionPreprocess + 171
1   libobjc.A.dylib                     0x00000001101a8141 objc_exception_throw + 48
2   CoreFoundation                      0x0000000110743a59 -[NSException raise] + 9
3   Foundation                          0x000000010fcbe00b -
以下省略

エラーメッセージ

該当のソースコード

import UIKit

class webViewPageViewController: UIViewController, UIWebViewDelegate,UIPickerViewDelegate, UIPickerViewDataSource {

    @IBOutlet weak var changeMode: UISegmentedControl!
    @IBOutlet weak var webView: UIWebView!
    //往路を表示するボタン
    @IBOutlet weak var outward: UIButton!
    //復路を表示するボタン
    @IBOutlet weak var inward: UIButton!


    @IBOutlet weak var picker: UIPickerView!

    // 選択肢
    let dataList = ["iOS", "macOS", "tvOS", "Android", "Windows"]
    let dataList2 = ["りんご", "ばなな", "おれんじ", "すいか"]


    override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.delegate = self
        self.view.addSubview(webView)

        // プロトコルの設定
        picker.delegate = self
        picker.dataSource = self

        // はじめに表示する項目を指定
        picker.selectRow(1, inComponent: 0, animated: true)
        picker.selectRow(2, inComponent: 1, animated: true)

        self.view.addSubview(picker)

    /*
        let initialUrl = NSURL(string: "")

        let request = URLRequest(url: initialUrl! as URL)
        // Webページを開く
        self.webView.loadRequest(request)
        self.webView.scalesPageToFit = true
     */
    }

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

    @IBAction func showOutward(_ sender: UIButton) {
        let url = NSURL(string: "https://transit.yahoo.co.jp/search/result?flatlon=&from=%E4%BA%AC%E6%88%90%E6%9B%B3%E8%88%9F&tlatlon=&to=%E5%AE%9D%E7%94%BA&&ticket=ic&userpass=1&al=1&shin=1&ex=1&hb=1&lb=1&sr=1&s=0&expkind=1&ws=3&kw=%E5%AE%9D%E7%94%BA")
        let request = URLRequest(url: url! as URL)
        // Webページを開く
        self.webView.loadRequest(request)
        self.webView.scalesPageToFit = true
    }

    @IBAction func showInward(_ sender: UIButton) {
        let url = NSURL(string: "https://transit.yahoo.co.jp/search/result?flatlon=&from=%E5%AE%9D%E7%94%BA&tlatlon=&to=%E4%BA%AC%E6%88%90%E6%9B%B3%E8%88%9F&via=&via=&via=&&type=1&ticket=ic&userpass=1&al=1&shin=1&ex=1&hb=1&lb=1&sr=1&s=0&expkind=1&ws=3&kw=%E4%BA%AC%E6%88%90%E6%9B%B3%E8%88%9F")
        let request = URLRequest(url: url! as URL)
        // Webページを開く
        self.webView.loadRequest(request)
        self.webView.scalesPageToFit = true
    }

    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        // 表示する列数
        return 2
    }

    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        // アイテム表示個数を返す
        if component == 0 {
            // 1個目のピッカーの設定
            return dataList.count
        }
        return dataList2.count
    }


    // UIPickerViewDelegate

    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        // 表示する文字列を返す
        if component == 0 {
            // 1個目のピッカーの設定
            return dataList[row]
        }
        return dataList2[row]
    }

    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        // 選択時の処理
        if component == 0 {
            // 1個目のピッカーの設定
            print(dataList[row])
        }
        print(dataList2[row])
    }

}

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

試したこと

デバッグをするに、delegateのところでエラーが出ているようで、
もろもろ試してはおりますがなかなか事象が解決しません。
どうかお知恵を拝借できませんでしょうか。

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • aja

    2017/07/12 18:03

    エラーがでているのであれば、そのエラーを提示しましょう

    キャンセル

  • greenSIer

    2017/07/13 00:41

    エラーは「発生している問題・エラーメッセージ」に記載させていただいている内容になります。また、Xcode上では、class AppDelegate: UIResponder, UIApplicationDelegate {の行が赤くなっております。こちらで内容は充足できておりますでしょうか?import UIKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } }

    キャンセル

回答 1

checkベストアンサー

0

UIPickerView は storyboard 上に配置していると思いますが、
エラー内容から正しく繋がっていない可能性があります。

    @IBOutlet weak var picker: UIPickerView!

参考:
What does this mean? “'NSUnknownKeyException', reason: … this class is not key value coding-compliant for the key X”

また、記事中ではコードで UIPickerView を生成しており、こちらも一度試してみてはどうでしょうか?

        let picker = UIPickerView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 100))
        picker.center = self.view.center

...         

        self.view.addSubview(picker)

と思いましたが、
現状のコードに以下があるのに気づきました。
stoaryboard で UIPickerView を追加しているなら不要です。
前述のようにコードで生成する場合は必要になります。

        self.view.addSubview(picker)

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/07/14 21:22

    おっしゃる通り、mainstoryboardで作成したpickerViewがうまく接続できていなかったようです。
    原因は不明で解決できませんでしたので、mainstoryboardの使用をあきらめコードで対応することにしました。
    ご回答ありがとうございました。
    引き続き頑張ります。

    キャンセル

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

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

関連した質問

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