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
の.hidden
のreferenceGuide
をsuperviewにしていることに注意。safeAreaにしてしまうとiPhoneX以降でSafeAreaの中にFloatingPanelの中に残ってしまう。
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),
]
}
}