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

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

ただいまの
回答率

88.06%

XcodeのPageViewController.swift編集中のエラーについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,520
退会済みユーザー

退会済みユーザー

【決定版】UIPageViewControllerの使い方(Swift)
↑上のサイトを見ながら作業を進めていたのですが、
いくつかエラーが出たので原因と解決方法を教えていただきたいです。
サイト中の「UIPageViewControllerを編集しよう」の「2.最初の画面を設定」までは動作確認できています。

環境

Xcode:バージョン8.2(8C38)
macOS Sierra:バージョン10.12.2

コードとエラー内容

PageViewController.swift内のコードと3つのViewControllerの名前はすべて上記のサイトと同じです。
(サイトのコード中のreturn storyboard!.instantiateViewControllerWithIdentifier ...の部分は書き直せというエラーが出たのでここではreturn storyboard!.instantiateViewController(withIdentifier:) ...と修正しています。)
エラー箇所は全部で5箇所で、エラーが出た部分に// ↓ エラーとコメントしています。

// PageViewController.swift

import UIKit

class PageViewController: UIPageViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setViewControllers([getFirst()], direction: .forward, animated: true, completion: nil)
        self.dataSource = self
    }

    func getFirst() -> FirstViewController {
        return storyboard!.instantiateViewController(withIdentifier:)("FirstViewController") as! FirstViewController
    }

    func getSecond() -> SecondViewController {
        return storyboard!.instantiateViewController(withIdentifier:)("SecondViewController") as! SecondViewController
    }

    func getThird() -> ThirdViewController {
        return storyboard!.instantiateViewController(withIdentifier:)("ThirdViewController") as! ThirdViewController
    }

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

// ↓ エラー①
extension PageViewController : UIPageViewControllerDataSource {

    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {

     // ↓ エラー②
        if viewController.isKindOfClass(ThirdViewController) {
            // 3 -> 2
            return getSecond()

     // ↓ エラー③
        } else if viewController.isKindOfClass(SecondViewController) {
            // 2 -> 1
            return getFirst()
        } else {
            // 1 -> end of the road
            return nil
        }
    }

    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {

     // ↓ エラー④
        if viewController.isKindOfClass(FirstViewController) {
            // 1 -> 2
            return getSecond()

     // ↓ エラー⑤
        } else if viewController.isKindOfClass(SecondViewController) {
            // 2 -> 3
            return getThird()
        } else {
            // 3 -> end of the road
            return nil
        }
    }
}

エラー内容は
①がType 'PageViewController' does not conform to protocol 'UIPageViewControllerDataSource'
②〜⑤がValue of type 'UIViewController' has no member 'isKindOfClass'
です。

質問:エラーの解決方法は?

google翻訳で翻訳してみると、
エラー①は
「タイプ 'PageViewController'はプロトコル 'UIPageViewControllerDataSource'に準拠していません」
エラー②〜⑤は
「タイプ 'UIViewController'の値にメンバー 'isKindOfClass'がありません」
と言っていることがわかりました。

②〜⑤のValue of type 'UIViewController' has no member 'isKindOfClass'は、
Swiftのコンパイルエラー寄せ集め←ここのサイトを参考にすると
「UIViewControllerの中にisKindOfClassが無い(?)」という意味かと考えたのですが、ではどうすれば解決するのかがわかりません。
①に関しても同じです。

解決策と原因が分かる方がいらっしゃれば、回答よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

エラー①は、protocolのシグニチャと合致してないから。
エラー②〜⑤は、isKindOfClassはisKindに変更されました。引数のクラスは{クラス名}.selfで渡します。

import UIKit

class PageViewController: UIPageViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.setViewControllers([getFirst()], direction: .forward, animated: true, completion: nil)
        self.dataSource = self
    }

    func getFirst() -> FirstViewController {
        return storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
    }

    func getSecond() -> SecondViewController {
        return storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    }

    func getThird() -> ThirdViewController {
        return storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
    }

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

extension PageViewController : UIPageViewControllerDataSource {

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {

        if viewController.isKind(of: ThirdViewController.self) {
        // 3 -> 2
            return getSecond()
        } else if viewController.isKind(of: SecondViewController.self) {
            // 2 -> 1
            return getFirst()
        } else {
            // 1 -> end of the road
            return nil
        }
    }

    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {

        if viewController.isKind(of: FirstViewController.self) {
        // 1 -> 2
            return getSecond()
        } else if viewController.isKind(of: SecondViewController.self) {
            // 2 -> 3
            return getThird()
        } else {
            // 3 -> end of the road
            return nil
        }
    }
}

 エラー①の補足

「タイプ 'PageViewController'はプロトコル 'UIPageViewControllerDataSource'に準拠していません」 というのは実装を義務付けらているメソッドが存在しないという意味です。commandを押しながらUIPageViewControllerDataSourceをクリックして定義を確認してみると上の2つは実装がマストなのがわかります(オプショナルでない)。今回のシグニチャというのは、ファンクション名および引数の型と戻り値の型や外部引数名の定義です。修正前はこの定義がUIPageViewControllerDataSourceプロトコルで宣言されているものと違うので実装されていないとみなされエラーになっていました。

public protocol UIPageViewControllerDataSource : NSObjectProtocol {

    @available(iOS 5.0, *)
    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?

    @available(iOS 5.0, *)
    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?

    @available(iOS 6.0, *)
    optional public func presentationCount(for pageViewController: UIPageViewController) -> Int // The number of items reflected in the page indicator.

    @available(iOS 6.0, *)
    optional public func presentationIndex(for pageViewController: UIPageViewController) -> Int // The selected item reflected in the page indicator.
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/12/16 02:34

    回答有難うございます。無事動作確認ができました。

    もし良ければもう一つ教えていただきたいのですが、
    回答中の「プロトコルの"シグニチャ"と合致していない」の
    Swiftでのシグニチャとは何か・「プロトコルとシグニチャが合致していない」とはどういう状態のことかを
    簡単にでもいいので教えていただきたいです。

    キャンセル

  • 2016/12/16 05:46

    補足追加しました

    キャンセル

  • 2016/12/17 02:06

    補足追加有難うございます。助かりました。

    キャンセル

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

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

関連した質問

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