【iOS】FloatingPanelを使ってセミモーダルビューを表示する


今回の目的

セミモーダルビュー

これを表示してみたいって人向けの話です。

環境

Xcode 12.0.1
Swift5
CocoaPods 1.10.0

環境設定

podファイルに下記を追加してinatall

pod 'FloatingPanel'

本題

では早速作っていこう

Storyboard

今回のゴールは先ほどのgifの通りボタンをタップするとセミモーダルビューが出てくるところ。
まずは2画面用意し、片方はボタンを設置する。(segueは不要)

ViewController      : ボタンを配置した方
SemiModalViewController :表示するモーダル。見やすいようにオレンジにした

ViewController

ViewController.swift
import UIKit
import FloatingPanel

class ViewController: UIViewController,FloatingPanelControllerDelegate{
    var floatingPanelController: FloatingPanelController!
    @IBOutlet weak var button: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
        //ここは普段のボタンの処理
        button.addTarget(self,action: #selector(self.tapButton(_ :)),for: .touchUpInside)
        floatingPanelController = FloatingPanelController()
        self.delegate = SemiModalViewController()
    }

    @objc func tapButton(_ sender: UIButton){
        // セミモーダルビューとなるViewControllerを生成し、contentViewControllerとしてセットする
        let semiModalViewController = self.storyboard?.instantiateViewController(withIdentifier: "fpc") as? SemiModalViewController
        floatingPanelController.set(contentViewController: semiModalViewController)
        // セミモーダルビューを表示する
        floatingPanelController.addPanel(toParent: self, belowView: nil, animated: false)
        floatingPanelController.delegate = self
        floatingPanelController.addPanel(toParent: self, belowView: nil, animated: false)
    }
    //画面を去るときにセミモーダルビューを非表示にする
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // セミモーダルビューを非表示にする
        floatingPanelController.removePanelFromParent(animated: true)
    }

    // カスタマイズしたレイアウトに変更(デフォルトで使用する際は不要)
    func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? {
        return CustomFloatingPanelLayout()
    }

    //tipの位置に来たときにセミモーダルビューを非表示にする
    func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) {
        if targetPosition == .tip{
            vc.removePanelFromParent(animated: true)
        }
    }

}

SemiModalViewController

特に記述の必要なし

CustomFloatingPanelLayout

CustomFloatingPanelLayout.swift
import Foundation
import FloatingPanel

class CustomFloatingPanelLayout: FloatingPanelLayout {
    // カスタマイズした高さ
       func insetFor(position: FloatingPanelPosition) -> CGFloat? {
           switch position {
           case .full: return 16.0
           case .half: return 216.0
           case .tip: return 44.0
           default: return nil
           }
       }


   // 初期位置
   var initialPosition: FloatingPanelPosition {
       //half位置から始める
       return .half
   }

   // サポートする位置
   var supportedPositions: Set<FloatingPanelPosition> {
    //full,half.tipの3種類が存在 今回は3種類とも使えるように設定
    return [.full,.half,.tip]
   }
}

まとめ

見事セミモーダルビューを表示することに成功
次はセミモーダルビュー に値渡しする方法を書く

参考