見出し画像

【徒然iOS】気ままにUIKit102〜Page View Controller ページをめくって画面遷移〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

 ハイ、レッツゴ🕺

ここは、

で軽くやった内容だね〜〜〜👀

前準備

念の為、

  1. バックアップ

をいつも通りやってから本題へ💃

てな感じで〜〜〜

本題

ページビューコントローラーとは、

めくる、または、ドラッグで画面を遷移させるコントローラー

⒈事前準備

ビューを3つ用意
内容は、イメージではなく今回は永井荷風の『濹東綺譚』の冒頭に〜〜〜
てな感じで、
Storyboard IDをつけて〜〜〜

⒉ページビューコントローラを配置

選んで〜〜〜
配置🕺

⒊コード組み込み

//
//  TestPageViewController.swift
//
import UIKit
class TestPageViewController: UIPageViewController,UIPageViewControllerDataSource {
    let idList = ["Morning", "Evening", "Night"]
    //最初からあるメソッド
    override func viewDidLoad() {
        //最初のビューコントローラーを取得する。
        let controller = storyboard!.instantiateViewControllerWithIdentifier(idList.first!)
        //ビューコントローラーを表示する。
        self.setViewControllers([controller], direction: .Forward, animated: true, completion:nil)
        //データ提供元に自分を設定する。
        self.dataSource = self
    }
    //右ドラッグ時の呼び出しメソッド
    func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        //現在のビューコントローラーのインデックス番号を取得する。
        let index = idList.indexOf(viewController.restorationIdentifier!)!
        if (index > 0) {
            //前ページのビューコントローラーを返す。
            return storyboard!.instantiateViewControllerWithIdentifier(idList[index-1])
        }
        return nil
    }
    //左ドラッグ時の呼び出しメソッド
    func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        //現在のビューコントローラーのインデックス番号を取得する。
        let index = idList.indexOf(viewController.restorationIdentifier!)!
        if (index < idList.count-1) {
            //次ページのビューコントローラーを返す。
            return storyboard!.instantiateViewControllerWithIdentifier(idList[index+1])
        }
        return nil
    }
}

を参考にやってみたんだけど、

てな感じでエラーになる

👉サイト記事のコード当時と、nilの許容の仕方の違いが原因の様子👀
なので、

なんかを参考に、、、

今回のコード(基本)

class PageViewStandardController: UIPageViewController,UIPageViewControllerDataSource {
    func newVC(viewControllerID: String) -> UIViewController {
        return storyboard!.instantiateViewController(withIdentifier: viewControllerID)
    }
    lazy var idList:[UIViewController] = {
        return [
            self.newVC(viewControllerID: "1頁"),
            self.newVC(viewControllerID: "2頁"),
            self.newVC(viewControllerID: "3頁")
        ]
    }()
    var showingIndex = 0

    //最初からあるメソッド
    override func viewDidLoad() {
        //最初のビューコントローラーを取得する。
        let controller: [UIViewController] = [idList.first!]
        //ビューコントローラーを表示する。
        self.setViewControllers(controller, direction: .forward, animated: false, completion: nil)
        //データ提供元に自分を設定する。
        self.dataSource = self
    }
    //右ドラッグ時の呼び出しメソッド
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = idList.firstIndex(of: viewController) else {
            return nil
        }
        let previousIndex = viewControllerIndex - 1
        guard previousIndex >= 0 else {
            return nil
        }
        guard idList.count > previousIndex else {
            return nil
        }
        showingIndex -= 1

        return idList[previousIndex]
    }
    //左ドラッグ時の呼び出しメソッド
    func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = idList.firstIndex(of: viewController) else {
            return nil
        }
        let nextIndex = viewControllerIndex + 1
        let controllersCount = idList.count
        guard controllersCount != nextIndex else {
            return nil
        }
        guard controllersCount > nextIndex else {
            return nil
        }
        showingIndex += 1

        return idList[nextIndex]
    }

    func viewController(at index: Int) -> UIViewController {
        return idList[index]
    }
    func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        return showingIndex
    }
    func presentationCount(for pageViewController: UIPageViewController) -> Int {
        return idList.count
    }
}

に書き換え〜〜〜〜

⒋シミュレータで実行

こんな
感じで
実現できた〜〜〜〜

ページコントロールの色を変更する

については、
前回、

AppDelegateは下手に触ると影響がデカすぎる!!!

と書いたんだけど、ここはページコントロールの状態を変更する程度なので〜〜〜

//
//  AppDelegate.swift
//
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    //アプリ起動時の呼び出しメソッド
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        //ページコントロールのカラーを変更する。
        let pageControl = UIPageControl.appearance()
        pageControl.backgroundColor = UIColor.whiteColor()
        pageControl.pageIndicatorTintColor = UIColor.blueColor()
        pageControl.currentPageIndicatorTintColor = UIColor.greenColor()
        return true
    }
}

を参考に〜〜〜
元々ある

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   // Override point for customization after application launch.
  return true
}

てコードの中身に

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
   // Override point for customization after application launch.
  //ページコントロールのカラーを変更する。
  let pageControl = UIPageControl.appearance()
  pageControl.backgroundColor = UIColor.black
  pageControl.pageIndicatorTintColor = UIColor.orange
  pageControl.currentPageIndicatorTintColor = UIColor.green
        
  return true
}

てな感じで追記して、

てな感じで、色変更できた〜〜〜

ビューコントローラで繋いだ後も、

てな感じで、問題なし🕺

今回のポイント

ページコントロール

でやった箇所を見てみると〜〜〜

てな感じで、ここの色も変わってる👀

AppDelegateって

にもあるとおり、

アプリ全体のライフタイムイベントを管理するためにAppDelegateクラス

👉起動直後に、同一の部品に色なんかを変更するコマンドを書き込んでしまうと、予想しない動きになる可能性がある

意識的に使う分には問題ないけど、無意識で安易に使うと前回も書いたとおりなんだけど、、、

全体に大きな影響を与える可能性が高い=危険

まあ、このプロジェクトは、

学び直しがてら、標準機能をひとつのプロジェクト内に網羅する

てコンセプトでやってるから、こんなにビューが増えてるだけで、
普通のアプリでは中々、起きないって思うけど。

意識してるのと意識してないのでは大きな違い

ライフサイクルイベントはすごく大事だから、

今回や前回のサイト記事の変更よりも、

//
//  AppDelegate.swift
//

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    //アプリ起動時の呼び出しメソッド
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
    }
    
    func applicationWillResignActive(application: UIApplication) {
    }
    
    func applicationDidEnterBackground(application: UIApplication) {
    }
    
    func applicationWillEnterForeground(application: UIApplication) {
    }
    
    func applicationDidBecomeActive(application: UIApplication) {
    }
    
    func applicationWillTerminate(application: UIApplication) {
    }
}

の関数名の意味を理解して使いこなせる方が大事かなあ🤔
と、

「アプリ起動と同時に音楽が掛かるようにしたい」
「アプリが非アクティブになったら、音楽や動画を一時停止したい」

みたいなことをやりたくなると思うからね〜〜〜〜🕺

どんなライフサイクルイベントがあるかは、

青くしてるUIApplicationDelegateプロトコルでたしか管理してるはず
JumptoDefinitionで調べてみてね〜〜〜

ブラッシュアップ

今回も、ここまででしれっとAutoLayoutなんかはやったので〜〜〜
🌐ボタンだけ〜〜〜

てな感じで〜〜〜

記事公開後、

ハイ、完了💃
実機も問題無し🕺

Apple公式

さてと次回は、

をレッツゴする🕺

この記事が気に入ったらサポートをしてみませんか?