20
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Storyboardを使ってContainerView+PageViewのサンプルを作ってみた

Posted at

#概要
横スクロールするメニュー+メニューに連動してメインビューが切り替わる、
SmartNews等のアプリで見られるような、簡易なサンプルを作ってみました。
ポイントはこんな感じです。
・可能な限りStoryboadを使う(+Swift)
・横スクロールするメニュー⇒ScrollView+StackView
・メインビュー⇒ContainerView+PageView

このあたりの記事を参考にさせていただきました。
http://crossbridge-lab.hatenablog.com/entry/2015/12/26/210600
http://qiita.com/nofrmm/items/5cc122876b6c3af7a21e

#ソース
ざっくりとした内容しか記載していないのでソース見たい方はこちらからどうぞ
https://github.com/koji-nishida/scrollmenu-container-pageview

#完成イメージ

サンプル.gif

#全体図

スクリーンショット 2016-08-19 14.59.16.png

スクリーンショット 2016-08-19 15.01.04.png

#メニュー部の作成
ScrollView、StackView、Buttonを配置
Constraintsは下図のような感じ(Buttonは特に制約なし)
これで端末幅に合わせて横スクロールするメニューが完成
スクリーンショット 2016-08-20 10.32.10.png

スクリーンショット 2016-08-20 10.30.10.png
ScrollViewのConstraints

スクリーンショット 2016-08-20 10.31.53.png
StackViewのConstraints

#メインビュー部の作成
図のようにメニューの下にContainerViewを配置。
配置時点ではUIViewControllerがembedされているので、
UIViewControllerを消して、UIPaveViewControllerを配置しなおします。
ここでUIPaveViewControllerのCustom ClassにPageViewController.swiftを指定しておく。
スクリーンショット 2016-08-20 10.40.06.png
スクリーンショット 2016-08-20 10.39.41.png
ContainerViewのConstraints

#実装部(PageViewにViewControllerをセット)

HomeViewController.swift
    var pageViewController: PageViewController!
    var menuViewControllers: Array<UIViewController> = []
    var selected: Int!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // PageViewControllerを取得する
        for vc in childViewControllers {
            if vc is PageViewController {
                pageViewController = vc as! PageViewController
            }
            
        }
        
        // PageViewにセットするViewControllerを生成して配列に入れる
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let firstViewController = storyboard.instantiateViewControllerWithIdentifier("FirstViewController") as! FirstViewController
        let secondViewController = storyboard.instantiateViewControllerWithIdentifier("SecondViewController") as! SecondViewController
        let thirdViewController = storyboard.instantiateViewControllerWithIdentifier("ThirdViewController") as! ThirdViewController
        let fourthViewController = storyboard.instantiateViewControllerWithIdentifier("FourthViewController") as! FourthViewController
        menuViewControllers.append(firstViewController)
        menuViewControllers.append(secondViewController)
        menuViewControllers.append(thirdViewController)
        menuViewControllers.append(fourthViewController)
        
        // 初期表示をメニュー2(SecondViewController)にする
        pageViewController.setViewControllers([menuViewControllers[1]], direction: .Forward, animated: false, completion: nil)
        selected = 1
    }


puts 'The best way to log and share programmers knowledge.'

ポイント
・childViewControllersからPageViewControllerを探す
 もっといい方法があれば誰か教えて下さい
・各ViewControllerをStoryboardから生成して配列で保持しておく
・初期表示するViewControllerをセット

#実装部(メニュー切り替え部)

HomeViewController.swift
@IBAction func actionMenu1(sender: AnyObject) {
        self.btnMenu1.enabled = false
        self.btnMenu2.enabled = true
        self.btnMenu3.enabled = true
        self.btnMenu4.enabled = true
        
        // 一番左までスクロール
        scrollViewMenu.setContentOffset(CGPointMake(0, 0), animated: true);
        
        // 表示切り替え
        pageViewController!.setViewControllers([menuViewControllers[0]], direction: .Reverse, animated: true, completion: nil)
        
        selected = 0
        
    }
    
    @IBAction func actionMenu2(sender: AnyObject) {
        self.btnMenu1.enabled = true
        self.btnMenu2.enabled = false
        self.btnMenu3.enabled = true
        self.btnMenu4.enabled = true
        
        // 一番左までスクロール
        scrollViewMenu.setContentOffset(CGPointMake(0, 0), animated: true);
        
        // 表示切り替え(前回選択していたメニューの位置に応じてアニメーションの向きを設定)
        if (selected < 1) {
            pageViewController!.setViewControllers([menuViewControllers[1]], direction: .Forward, animated: true, completion: nil)
        } else {
            pageViewController!.setViewControllers([menuViewControllers[1]], direction: .Reverse, animated: true, completion: nil)
        }
        
        selected = 1
        
    }
    
    @IBAction func actionMenu3(sender: AnyObject) {
        self.btnMenu1.enabled = true
        self.btnMenu2.enabled = true
        self.btnMenu3.enabled = false
        self.btnMenu4.enabled = true

        // 一番右までスクロール
        let scrollWidth = scrollViewMenu.contentSize.width - scrollViewMenu.frame.size.width
        scrollViewMenu.setContentOffset(CGPointMake(scrollWidth, 0), animated: true);
        
        // 表示切り替え(前回選択していたメニューの位置に応じてアニメーションの向きを設定)
        if (selected < 2) {
            pageViewController!.setViewControllers([menuViewControllers[2]], direction: .Forward, animated: true, completion: nil)
        } else {
            pageViewController!.setViewControllers([menuViewControllers[2]], direction: .Reverse, animated: true, completion: nil)
        }
        
        selected = 2
        
    }
    
    @IBAction func actionMenu4(sender: AnyObject) {
        self.btnMenu1.enabled = true
        self.btnMenu2.enabled = true
        self.btnMenu3.enabled = true
        self.btnMenu4.enabled = false

        // 一番右までスクロール
        let scrollWidth = scrollViewMenu.contentSize.width - scrollViewMenu.frame.size.width
        scrollViewMenu.setContentOffset(CGPointMake(scrollWidth, 0), animated: true);
 
        // 表示切り替え
        pageViewController!.setViewControllers([menuViewControllers[3]], direction: .Forward, animated: true, completion: nil)
        
        selected = 3
        
    }

ポイント
・特になし笑

#最後に
Storyboardもずいぶん便利になったなーというのが一番の感想ですかね。
一昔前ではコードをがりがり書かないとできなかったようなことが、
Storyboardでこんなに簡単に作れるようになったなーという印象です。

今回は、メニューボタンのアクションによる画面切り替えしか対応していないので、
メインビュー部分をスクロールさせることでも画面がスライドするようにしないとですね。
ContainerViewのジェスチャーをとって、画面を切り替えるという感じでしょうか。

以上

20
23
0

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
  3. You can use dark theme
What you can do with signing up
20
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?