既存のUIPageViewControllerのボタンを使用してプログラムでビューをスライドするにはどうすればよいですか

ジョージ

私は3つのメインビューを持つアプリを開発しています。ユーザーがスワイプするだけで3つのビューを変更できるようにするために(Tinderアプリのように)、PageViewControllerを作成しました。これはうまく機能します。このPageViewControllerは次のように機能します。

  1. ユーザーが「ログイン」または「サインアップ」ボタンのいずれかをタップすると、PageViewControllerにセグエします
  2. PageViewControllerは、firstViewControllerを初期ビューとして設定します
  3. PageViewControllerには、「getFirst」(firstViewControllerを取得する)、「getSecond」(secondViewControllerを取得する)、「getThird」(thirdViewControllerを取得する)の3つのメソッドがあります。

また、各3つのビューの上部にボタンを追加し、ユーザーがそれらのビューをスワイプしたときと同じように、それらのボタンをタップして他のビューにスライドできるようにしました(これもTinderのようなものです)。

そこで、実験のために、SecondViewControllerに2つのボタンを追加しました。左はFirstViewControllerに移動するためのもので、右はThirdViewControllerに移動するためのものです。次に、SecondViewControllerファイルに「UIPageViewControllerDelegate」を追加し、PageViewControllerファイルから左ボタンの「getFirst」メソッドと右ボタンの「getThird」メソッドを呼び出そうとしました。

しかし、左ボタンをタップすると、PageViewControllerファイルの「getFirst」メソッド行にこのエラーメッセージが表示されます(右ボタンでも同じエラーが発生する可能性があります)。

スレッド1:致命的なエラー:オプション値のアンラップ中に予期せずnilが見つかりました

コードは以下のとおりです。

PageViewController

import UIKit

class PageViewController: UIPageViewController {

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


extension PageViewController : UIPageViewControllerDataSource {

    //FirstViewController
    @objc func getFirst() -> FirstViewController {
        return storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
    }
    //SecondViewController
    @objc func getSecond() -> SecondViewController {
        return storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
    }
    //ThirdViewController
    @objc func getThird() -> ThirdViewController {
        return storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
    }

    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
        }
    }
}

SecondViewController

import UIKit
class SecondViewController: UIViewController, UIPageViewControllerDelegate {

    let pageHelper = PageViewController()
    override func viewDidLoad() {
        super.viewDidLoad()

        pageHelper.delegate = self
    }

    @IBAction func toFirstTapped(_ sender: Any) {
        pageHelper.getFirst()
    }
}

何が足りないの?たぶん私はそれをこのように機能させることができません(他のファイルからPageViewControllerを再利用することはできませんか?)。

誰か助けてくれませんか!

ブランドン

まず、PageViewControllerインスタンス化する子コントローラーをインスタンス化しPageViewControllerます..それは本当に良い考えですか?次に、で、toFirstTappedインスタンス化しますがFirstViewController何もしません。

あなたがそれで何もしない場合、あなたはそれがどのように機能することを期待しますか?

いずれにせよ、以下を試してください。

protocol PageNavigationDelegate : class {
    weak var pageController: PageViewController? { get set }
}

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


extension PageViewController : UIPageViewControllerDataSource {

    func getFirst() -> FirstViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
        controller.pageController = self
        return controller
    }

    func getSecond() -> SecondViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
        controller.pageController = self
        return controller
    }

    func getThird() -> ThirdViewController {
        let controller = storyboard!.instantiateViewController(withIdentifier: "ThirdViewController") as! ThirdViewController
        controller.pageController = self
        return controller
    }

    @discardableResult
    func goToPreviousPage() -> Bool {
        let controller = self.viewControllers!.first!
        if controller.isKind(of: SecondViewController.self) {
            self.setViewControllers([getFirst()], direction: .reverse, animated: true, completion: nil)
            return true
        }

        if controller.isKind(of: ThirdViewController.self) {
            self.setViewControllers([getSecond()], direction: .reverse, animated: true, completion: nil)
            return true
        }

        return false
    }

    @discardableResult
    func goToNextPage() -> Bool {
        let controller = self.viewControllers!.first!
        if controller.isKind(of: FirstViewController.self) {
            self.setViewControllers([getSecond()], direction: .forward, animated: true, completion: nil)
            return true
        }

        if controller.isKind(of: SecondViewController.self) {
            self.setViewControllers([getThird()], direction: .forward, animated: true, completion: nil)
            return true
        }

        return false
    }

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

        if viewController.isKind(of: SecondViewController.self) {
            return getFirst()
        }

        if viewController.isKind(of: ThirdViewController.self) {
            return getSecond()
        }

        return nil
    }

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

        if viewController.isKind(of: FirstViewController.self) {
            return getSecond()
        }

        if viewController.isKind(of: SecondViewController.self) {
            return getThird()
        }

        return nil
    }
}

class PageNavigationController : UIViewController, PageNavigationDelegate {
    var pageController: PageViewController?

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

    @IBAction func goToPreviousController(_ sender: Any) {
        pageController?.goToPreviousPage()
    }

    @IBAction func goToNextController(_ sender: Any) {
        pageController?.goToNextPage()
    }
}

class FirstViewController: PageNavigationController {

}

class SecondViewController: PageNavigationController {

}

class ThirdViewController: PageNavigationController {

}

まず、プロトコルを作成しました。PageControllerのすべてのサブコントローラーがそれを実装することを確認しました。このようにして、前のページと次のページに移動できます。

次に、goToPreviousPageandgoToNextPage関数を持つ拡張機能を作成します。各コントローラーページをインスタンス化するときにself、そのプロトコル実装変数に割り当てます。このようにして、コントローラーはPageViewControllerのメソッドにアクセスできます

最後に、私たちの中でFirstSecond、およびThirdコントローラ、私たちは、ボタンを押す上の前方または後方に行くためにそれを伝えます。

個人的には、配列内のコントローラーを追跡し、それらをデリゲートに返すことを好みます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

AndroidのRelativeLayoutのボタンの横にテキストビューをプログラムで表示するにはどうすればよいですか?

分類Dev

AndroidのRelativeLayoutのボタンの横にテキストビューをプログラムで表示するにはどうすればよいですか?

分類Dev

Qtでプログラムによってメインウィンドウにボタンを追加し、cssファイルを使用してボタンのスタイルを変更するにはどうすればよいですか?

分類Dev

プログラムで自動レイアウト制約を追加して、ボタンをスーパービューの下部から50ポイント上に作成するにはどうすればよいですか?

分類Dev

appengine gradleプラグインを使用してカスタムサービスにデプロイするにはどうすればよいですか?

分類Dev

KDEのタスクバーで開いているプログラムのビューを変更するにはどうすればよいですか?

分類Dev

UIPageViewControllerのサブビューの制約をプログラムで設定するにはどうすればよいですか?

分類Dev

UIPageViewControllerのサブビューの制約をプログラムで設定するにはどうすればよいですか?

分類Dev

ブートストラップのボタンの代わりにスパンタグとグリフィコンを使用してドロップダウンメニューを作成するにはどうすればよいですか?

分類Dev

プログラムで新しいResourceManagerモデルを使用して、複数の仮想マシンを単一のクラウドサービスにデプロイするにはどうすればよいですか?

分類Dev

XAMLで別のカスタムコントロール基本クラスを使用して、WPFでビュー内のカスタムコントロールをインスタンス化するにはどうすればよいですか?

分類Dev

スライダーをドラッグしてKivyのスクロールビューを制御するにはどうすればよいですか?

分類Dev

パイプを介してDynamicMapへの(ライブ)データストリームと一緒にホロビューを使用してズームインデータシェーダーで自動リサンプリングを有効にするにはどうすればよいですか?

分類Dev

プログラムでカスタムビューのサイズを変更するにはどうすればよいですか?

分類Dev

boto3を使用して、awsに存在するインスタンスとボリュームおよびロードバランサーの総数を取得するにはどうすればよいですか?

分類Dev

2つのテキストビューを垂直に配置してCardViewをプログラムで作成するにはどうすればよいですか?

分類Dev

フラッター:ボタンを使用して、テキストフィールド内のテキストの配置をプログラムで変更するにはどうすればよいですか?

分類Dev

Fiddlerからのデータをライブで保存して、他のプログラムで使用するにはどうすればよいですか?

分類Dev

文字列プロパティをビューのラジオボタンにバインドするにはどうすればよいですか?

分類Dev

Logstashを使用して既存のインデックスにデータをアップロードするにはどうすればよいですか?

分類Dev

制約レイアウトでプログラムでビュー(ボタン)を移動するにはどうすればよいですか?

分類Dev

XML-RPCを使用してデータを特定のドメインに送信するプログラムからデータをリバースエンジニアリングするにはどうすればよいですか?

分類Dev

ディープリンク用のタブとナビゲーションコントローラーを使用してビューコントローラーをインスタンス化するにはどうすればよいですか?

分類Dev

Python 3の既存のプログラムからargparseを使用してサブパーサーを作成するにはどうすればよいですか?

分類Dev

プログラムでGrailsサービスのインスタンスを取得するにはどうすればよいですか?

分類Dev

Swift 4を使用してXcodeで複数のビューコントローラーを使用してカスタムモデルのインスタンスを作成するにはどうすればよいですか?

分類Dev

ブートストラップビューでボタンのマイナスとプラスを作成するにはどうすればよいですか?

分類Dev

iOSでポリゴンフレームビューをプログラムでカスタマイズするにはどうすればよいですか?

分類Dev

Pythonプログラムのデータセットから既存のポイントを動的に描画するにはどうすればよいですか

Related 関連記事

  1. 1

    AndroidのRelativeLayoutのボタンの横にテキストビューをプログラムで表示するにはどうすればよいですか?

  2. 2

    AndroidのRelativeLayoutのボタンの横にテキストビューをプログラムで表示するにはどうすればよいですか?

  3. 3

    Qtでプログラムによってメインウィンドウにボタンを追加し、cssファイルを使用してボタンのスタイルを変更するにはどうすればよいですか?

  4. 4

    プログラムで自動レイアウト制約を追加して、ボタンをスーパービューの下部から50ポイント上に作成するにはどうすればよいですか?

  5. 5

    appengine gradleプラグインを使用してカスタムサービスにデプロイするにはどうすればよいですか?

  6. 6

    KDEのタスクバーで開いているプログラムのビューを変更するにはどうすればよいですか?

  7. 7

    UIPageViewControllerのサブビューの制約をプログラムで設定するにはどうすればよいですか?

  8. 8

    UIPageViewControllerのサブビューの制約をプログラムで設定するにはどうすればよいですか?

  9. 9

    ブートストラップのボタンの代わりにスパンタグとグリフィコンを使用してドロップダウンメニューを作成するにはどうすればよいですか?

  10. 10

    プログラムで新しいResourceManagerモデルを使用して、複数の仮想マシンを単一のクラウドサービスにデプロイするにはどうすればよいですか?

  11. 11

    XAMLで別のカスタムコントロール基本クラスを使用して、WPFでビュー内のカスタムコントロールをインスタンス化するにはどうすればよいですか?

  12. 12

    スライダーをドラッグしてKivyのスクロールビューを制御するにはどうすればよいですか?

  13. 13

    パイプを介してDynamicMapへの(ライブ)データストリームと一緒にホロビューを使用してズームインデータシェーダーで自動リサンプリングを有効にするにはどうすればよいですか?

  14. 14

    プログラムでカスタムビューのサイズを変更するにはどうすればよいですか?

  15. 15

    boto3を使用して、awsに存在するインスタンスとボリュームおよびロードバランサーの総数を取得するにはどうすればよいですか?

  16. 16

    2つのテキストビューを垂直に配置してCardViewをプログラムで作成するにはどうすればよいですか?

  17. 17

    フラッター:ボタンを使用して、テキストフィールド内のテキストの配置をプログラムで変更するにはどうすればよいですか?

  18. 18

    Fiddlerからのデータをライブで保存して、他のプログラムで使用するにはどうすればよいですか?

  19. 19

    文字列プロパティをビューのラジオボタンにバインドするにはどうすればよいですか?

  20. 20

    Logstashを使用して既存のインデックスにデータをアップロードするにはどうすればよいですか?

  21. 21

    制約レイアウトでプログラムでビュー(ボタン)を移動するにはどうすればよいですか?

  22. 22

    XML-RPCを使用してデータを特定のドメインに送信するプログラムからデータをリバースエンジニアリングするにはどうすればよいですか?

  23. 23

    ディープリンク用のタブとナビゲーションコントローラーを使用してビューコントローラーをインスタンス化するにはどうすればよいですか?

  24. 24

    Python 3の既存のプログラムからargparseを使用してサブパーサーを作成するにはどうすればよいですか?

  25. 25

    プログラムでGrailsサービスのインスタンスを取得するにはどうすればよいですか?

  26. 26

    Swift 4を使用してXcodeで複数のビューコントローラーを使用してカスタムモデルのインスタンスを作成するにはどうすればよいですか?

  27. 27

    ブートストラップビューでボタンのマイナスとプラスを作成するにはどうすればよいですか?

  28. 28

    iOSでポリゴンフレームビューをプログラムでカスタマイズするにはどうすればよいですか?

  29. 29

    Pythonプログラムのデータセットから既存のポイントを動的に描画するにはどうすればよいですか

ホットタグ

アーカイブ