LoginSignup
6

More than 1 year has passed since last update.

TabBarControllerを用いたXLPagerTabStripの実装

Last updated at Posted at 2020-11-08

はじめに

XLPagerTabStripというSwift製のiOSライブラリを使った際に、TabBarControllerと絡めた実装をしました。storyboardでの設定等で少し詰まったりもしましたので、備忘録として投稿します。

動作環境

【Xcode】Version 12.0.1
【Swift】Version 5.3
【CocoaPods】version 1.9.3

実装後の画面

output.gif

実装手順

1. TabBarControllerの用意

  1. Main.storyboardの元々あるViewControllerを削除して、TabBarControllerを追加します。付属のViewControllerも消しておいてください。(storyboard1つに対してViewController1つとする理由です。)
    スクリーンショット 2020-11-08 1.45.48(2).png

  2. Is Initial View Controllerにチェックを入れます。
    スクリーンショット 2020-11-08 1.46.33(2).png

  3. MainTabBarController.swiftを作成し、Main.storyboardClassに割り当ててください。

MainTabBarController.swift
class MainTabBarController: UITabBarController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // 各画面となるViewControllerを格納する変数を用意
        var viewControllers = [UIViewController]()

        // それぞれの画面の設定(tabの画像など)
        let tab1VC = UIStoryboard(name: "Bookmarks", bundle: nil).instantiateInitialViewController()
        tab1VC?.tabBarItem = UITabBarItem(tabBarSystemItem: .bookmarks, tag: 0)
        viewControllers.append(tab1VC!)

        let tab2VC = UIStoryboard(name: "Favorites", bundle: nil).instantiateInitialViewController()
        tab2VC?.tabBarItem = UITabBarItem(tabBarSystemItem: .favorites, tag: 0)
        viewControllers.append(tab2VC!)

        self.setViewControllers(viewControllers, animated: false)
    }
}

2. 各画面となるViewControllerの用意

  • 上記のtab1VCBookmarks.storyboardtab2VCFavorites.storyboardとして用意します。それぞれUINavigationControllerを設定し、見分けがつくようにタイトルを付けます。 スクリーンショット 2020-11-08 2.12.25(2).png

3. XLPagerTabStripを導入

  • CocoaPodsを利用します。
  1. ターミナルを開いてcd 対象ファイルで移動します。
  2. pod initpodfile作成
  3. podfileに下記を追加し保存して、pod installにて完了です。
podfile.rb
pod 'XLPagerTabStrip'

4. 管理元クラスButtonBarPagerTabStripViewControllerの用意

  • ViewControllerたちを管理するButtonBarPagerTabStripViewControllerを継承したクラスを用意します。今回はBookmarksを管理元とします。BookmarksViewController.swiftを作成します。
BookmarksViewController.swift
import UIKit
import XLPagerTabStrip

// 継承元を書き換える ( UIViewController → ButtonBarPagerTabStripViewController )
class BookmarksViewController: ButtonBarPagerTabStripViewController {

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

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        //管理されるViewControllerを返す処理
        let firstVC = UIStoryboard(name: "First", bundle: nil).instantiateViewController(withIdentifier: "First")
        let secondVC = UIStoryboard(name: "Second", bundle: nil).instantiateViewController(withIdentifier: "Second")
        let thirdVC = UIStoryboard(name: "Third", bundle: nil).instantiateViewController(withIdentifier: "Third")
        let childViewControllers:[UIViewController] = [firstVC, secondVC, thirdVC]
        return childViewControllers
    }

}

1. ボタン部分になるCollection Viewの設置

  • ボタン部分になるCollection Viewを配置し、下記画像のようにAutoLayoutを設定します。Cellは消しておきましょう。
  • Collection ViewのクラスをButtonBarViewと結びつけ、ModuleをXLPagerTabStripとします。
    スクリーンショット 2020-11-08 2.33.16(2).png

  • Collection Viewを右クリックします。Referencing OutletsNew Referencing OutletViewControllerにドラッグし、ButtonBarViewを選択します。
    スクリーンショット 2020-11-08 3.15.15(2).png

2. 切り替え部分になるScrollViewの設置

  • 切り替え部分になるScrollViewを配置し、下記画像のようにAutoLayoutを設定します。
  • あいまいなレイアウトと警告がでるのでContent Layout Guidesのチェックを外しましょう。

スクリーンショット 2020-11-08 2.35.37(2).png

  • ScrollViewを右クリックします。Referencing OutletsNew Referencing OutletViewControllerにドラッグし、containerViewを選択します。
    スクリーンショット 2020-11-08 2.54.55(2).png

  • 正しく繋ぐことができると、ScrollViewの表示がContainerViewに変わります。

5. 管理されるViewControllerたちの用意

  • スワイプやボタンを押されて遷移するViewControllerになります。
  • IndicatorInfoProviderプロトコルを実装したUIViewControllerを下記3つそれぞれ用意します。
  1. First.storyboardFirstViewControllerを用意。( storyboardの背景色は赤色
  2. Second.storyboardSecondViewControllerを用意。( storyboardの背景色は青色
  3. Third.storyboardThirdViewControllerを用意。( storyboardの背景色は緑色
FirstViewController.swift
import UIKit
import XLPagerTabStrip

class FirstViewController: UIViewController {

    //ここがボタンのタイトルに利用されます
    var itemInfo: IndicatorInfo = "First"

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

}

extension FirstViewController: IndicatorInfoProvider {
    func indicatorInfo(for pagerTabStripController: PagerTabStripViewController) -> IndicatorInfo {
        return itemInfo
    }
}
  • Labelを配置し、TextFirstFont24AutoLayoutの設定をします。
    スクリーンショット 2020-11-08 2.59.11(2).png

  • Classの割り当てと、Storyboard IDを設定します。
    スクリーンショット 2020-11-08 3.13.26(2).png

6. buttonBarの見た目と振る舞いを追加

MainTabBarController.swift
import UIKit
import XLPagerTabStrip

class BookmarksViewController: ButtonBarPagerTabStripViewController {

    override func viewDidLoad() {
        // 画面UIについての処理
        setupUI()
        super.viewDidLoad()
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        // 強制的に再選択し、changeCurrentIndexProgressiveを動作させる( 0番目 → 1番目 → 0番目 )
        moveToViewController(at: 1, animated: false)
        moveToViewController(at: 0, animated: false)
    }

    func setupUI() {
        // ButtonBar全体の背景色
        settings.style.buttonBarBackgroundColor = UIColor.white
        // ButtonBarItemの背景色
        settings.style.buttonBarItemBackgroundColor = UIColor.white
        // ButtonBarItemの文字色
        settings.style.buttonBarItemTitleColor = UIColor.lightGray
        // ButtonBarItemのフォントサイズ
        settings.style.buttonBarItemFont = .boldSystemFont(ofSize: 14)
        // 選択中のButtonBarインジケーターの色
        settings.style.selectedBarBackgroundColor = UIColor.black
        // 選択中のButtonBarインジケーターの太さ
        settings.style.selectedBarHeight = 2.0
        // ButtonBarの左端の余白
        settings.style.buttonBarLeftContentInset = 8
        // ButtonBarの右端の余白
        settings.style.buttonBarRightContentInset = 8
        // Button内の余白
        settings.style.buttonBarItemLeftRightMargin = 32
        // スワイプやButtonBarItemタップ等でページを切り替えた時の動作
        changeCurrentIndexProgressive = { oldCell, newCell, progressPercentage, changeCurrentIndex, animated in
            // 変更されたか、選択前後のCellをアンラップ
            guard changeCurrentIndex, let oldCell = oldCell, let newCell = newCell else { return }
            // 選択前のセルの状態を指定
            oldCell.label.textColor = UIColor.lightGray
            // 選択後のセルの状態を指定する
            newCell.label.textColor = UIColor.black
        }
    }

    override func viewControllers(for pagerTabStripController: PagerTabStripViewController) -> [UIViewController] {
        //管理されるViewControllerを返す処理
        let firstVC = UIStoryboard(name: "First", bundle: nil).instantiateViewController(withIdentifier: "First")
        let secondVC = UIStoryboard(name: "Second", bundle: nil).instantiateViewController(withIdentifier: "Second")
        let thirdVC = UIStoryboard(name: "Third", bundle: nil).instantiateViewController(withIdentifier: "Third")
        let childViewControllers:[UIViewController] = [firstVC, secondVC, thirdVC]
        return childViewControllers
    }

}

参考

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
6