2
1

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 3 years have passed since last update.

FloatingPanelのaddPanelとpresentModallyの使い分け

Last updated at Posted at 2020-12-27

FloatingPanel
https://github.com/SCENEE/FloatingPanel#add-a-floating-panel-as-a-child-view-controller

主にFloatingPanelを出した状態でpush遷移をしたいときは子ビューとして使うのが正解だと思う。そもそもModality(モーダル的に)というのは「別モードとして画面を起動する遷移方法だから、モーダルビューの処理が終わるまでは前のモード(self.presentingViewController)の処理は受け付けないよ」という遷移方法なので、この形式で遷移したのに前のVCをいじれないのは当たり前。

そう考えるとModalytiでfpcを開くメリットってあるんだろうか?

Add a floating panel as a child view controller

import UIKit
import FloatingPanel

class ViewController: UIViewController, ContentViewControllerDelegate {
	var fpc: FloatingPanelController!
	
	override func viewDidLoad() {
		super.viewDidLoad()
		setupFloatingPanel()
	}

	func setupFloatingPanel() {
		fpc = FloatingPanelController(delegate: self)
		fpc.layout = MyFloatingPanelLayout()
		let contentVC = ContentViewController()
		fpc.set(contentViewController: contentVC)
		fpc.track(scrollView: contentVC.tableView)
		fpc.addPanel(toParent: self)
	}

	@IBAction func didTapCommentButton(_ sender: Any) {
		self.fpc.move(to: .half, animated: true)
	}
	
    // ContentVCのcloseButtonがタップされたらDelegateであるViewControllerのhideFpc()を呼ぶようにしている
	func hideFpc() {
		self.fpc.move(to: .hidden, animated: true)
	}
}

class MyFloatingPanelLayout: FloatingPanelLayout {
	let position: FloatingPanelPosition = .bottom
	let initialState: FloatingPanelState = .hidden
	var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] {
		return [
			.half: FloatingPanelLayoutAnchor(fractionalInset: 0.75, edge: .bottom, referenceGuide: .safeArea),
            // .hiddenのreferenceGuideが.superviewであることに注意
			.hidden: FloatingPanelLayoutAnchor(fractionalInset: 0, edge: .bottom, referenceGuide: .superview)
		]
	}
}

FloatingPanelLayoutをカスタマイズした独自のものにするとき、anchors.hiddenreferenceGuideをsuperviewにしていることに注意。safeAreaにしてしまうとiPhoneX以降でSafeAreaの中にFloatingPanelの中に残ってしまう。

ContentViewController.swift
protocol ContentViewControllerDelegate: FloatingPanelControllerDelegate {
	func hideFpc()
}

class ContentViewController: UIViewController {

	@IBAction func didTapCloseButton(_ sender: Any) {
		self.delegate.hideFpc()
	}
}

ちなみにこっちでfpc.isRemovalInteractionEnabled = trueを書いてしまうとスクロール時に背面の親Viewがスクロールしてしまったり、下スワイプで閉じたら再度fpc.move(to:animated:)を読んでもFloatingPanelが表示されなかったりと不具合がでた。

Present a floating panel as a modality

import FloatingPanel

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
		fpc = FloatingPanelController(delegate: self)
		fpc.layout = MyFloatingPanelLayout()
        let contentVC == CommentViewController()
		// or let contentVC = CommentViewController.fromStoryboard()
		fpc.set(contentViewController: contentVC)
		fpc.isRemovalInteractionEnabled = true // Let it removable by a swipe-down
		fpc.track(scrollView: contentVC.tableView) // .fullになったらcontentVCのtableViewをスクロール可能にする
	}

    @IBAction func didTapCommentButton(_ sender: Any) {
		self.present(fpc, animated: true, completion: nil)
	}
		
}

class MyFloatingPanelLayout: FloatingPanelLayout {
	let position: FloatingPanelPosition = .bottom
	let initialState: FloatingPanelState = .half
    var anchors: [FloatingPanelState: FloatingPanelLayoutAnchoring] {
        return [
            .half: FloatingPanelLayoutAnchor(fractionalInset: 0.5, edge: .bottom, referenceGuide: .safeArea),
        ]
    }
}
2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?