iOS 앱에서 이제 세미 모달 뷰를 사용하고 싶은 사람에게 "FloatingPanel"을 추천

전단



iOS의 맵 앱이나 뮤직 앱 등에서 볼 수 있는 세미모달 뷰.

iPhone의 대화면화에 의해, 한 손 조작이라고 화면 상부의 입력을 원활하게 실시할 수 없다고 하는 기회가 많아졌습니다.iPhone X 이나 iPhone XS 의 홈 바와 같이, 화면 하부에 동선을 배치해 조작을 실시할 수 있는 세미모달을 사용한 UI도 보급해 가는 것이 아닐까 생각합니다.


세미 모달 뷰 예제(iOS 지도 앱에서)





그러나 현재(2018년 11월 시점)에서는 세미모달 뷰를 간편하게 실현할 수 있는 컴퍼넌트는 UIKit에서는 제공되고 있지 않고, 실현하기 위해서는 UIScrollView등을 커스텀해서 자체적으로 구현할 필요가 있습니다.

제품 개발에서 세미 모달 뷰를 사용해보고 싶다고 생각했을 때 찾아낸, 간편하게 세미 모달 뷰를 만들 수 있다 "FloatingPanel" 라는 멋진 라이브러리를 소개합니다.

FloatingPanel을 사용하여 세미 모달 뷰 만들기



1. 도입


CocoaPodsCarthage 에 대응하고 있으므로 적절히 인스톨 합니다.
// Podfile

pod 'FloatingPanel'
// Cartfile

github "scenee/FloatingPanel"

2. 기본적인 사용법



2.1 세미 모달 뷰가되는 ViewController 정의



세미모달 뷰가 되는 ViewController는 UIViewController 를 계승하고 있으면 뭐든지 OK입니다만, 외형상의 알기 쉬움 때문에 배경색만 설정해 둡니다.
class SemiModalViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // わかりやすくするため背景色だけ設定
        self.view.backgroundColor = UIColor.orange
    }
}

2.2 호출자의 ViewController에서 FloatingPanel을 사용하여 세미 모달 뷰 표시


import UIKit
import FloatingPanel

class ViewController: UIViewController {

    var floatingPanelController: FloatingPanelController!

    override func viewDidLoad() {
        super.viewDidLoad()

        floatingPanelController = FloatingPanelController()

        // セミモーダルビューとなるViewControllerを生成し、contentViewControllerとしてセットする
        let semiModalViewController = SemiModalViewController()
        floatingPanelController.set(contentViewController: semiModalViewController)

        // セミモーダルビューを表示する
        floatingPanelController.addPanel(toParent: self, belowView: nil, animated: false)
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        // セミモーダルビューを非表示にする
        floatingPanelController.removePanelFromParent(animated: true)
    }
}

여기까지의 기본적인 사용법으로 👇와 같은 세미 모달 뷰를 할 수 있습니다. 간단!


세미 모달 뷰(기본 버전)





3. 세미모달 뷰 사용자 정의



더 세밀하게 사용자 정의할 수 있습니다.

세미모달 뷰를 둥근


floatingPanelController = FloatingPanelController()
floatingPanelController.surfaceView.cornerRadius = 24.0

세미 모달 뷰의 높이 위치 맞춤설정


FloatingPanelController의 Delegate를 설정하고 FloatingPanelLayout를 상속하여 사용자 정의 레이아웃을 반환합니다.
// ViewController.Swift

    override func viewDidLoad() {
        super.viewDidLoad()

        floatingPanelController = FloatingPanelController()

        // Delegateを設定
        floatingPanelController.delegate = self

        ...
    }

    // FloatingPanelControllerDelegate を実装してカスタマイズしたレイアウトを返す
    extension ViewController: FloatingPanelControllerDelegate {
        func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? {
            return CustomFloatingPanelLayout()
        }
    }


// CustomFloatingPanelLayout.Swift

class CustomFloatingPanelLayout: FloatingPanelLayout {

    // セミモーダルビューの初期位置
    var initialPosition: FloatingPanelPosition {
        return .half
    }

    var topInteractionBuffer: CGFloat { return 0.0 }
    var bottomInteractionBuffer: CGFloat { return 0.0 }

    // セミモーダルビューの各表示パターンの高さを決定するためのInset
    func insetFor(position: FloatingPanelPosition) -> CGFloat? {
        switch position {
        case .full: return 56.0
        case .half: return 262.0
        case .tip: return 100.0
        }
    }

    // セミモーダルビューの背景Viewの透明度
    func backdropAlphaFor(position: FloatingPanelPosition) -> CGFloat {
        return 0.0
    }
}


세미모달 뷰를 각 패턴(full/half/tip)의 높이로 변경



floatingPanelController.move(to: .full, animated: true)

세미모달 뷰 높이 변경 후 처리 수행



레이아웃의 커스터마이즈와 같이 FloatingPanelController 의 Delegate 를 설정해, 드래그 조작 완료시의 이벤트등을 취득해 처리를 실행할 수가 있습니다.
// ViewController.Swift

    override func viewDidLoad() {
        super.viewDidLoad()

        floatingPanelController = FloatingPanelController()

        // Delegateを設定
        floatingPanelController.delegate = self

        ...
    }

    extension ViewController: FloatingPanelControllerDelegate {

        func floatingPanelDidEndDragging(_ vc: FloatingPanelController, withVelocity velocity: CGPoint, targetPosition: FloatingPanelPosition) {

            // セミモーダルビューの各表示パターンの高さに応じて処理を実行する
            switch targetPosition {
            case .tip:
                print("tip")
            case .half:
                print("half")
            case .full:
                print("full")
            }
        }
    }

맞춤형 세미 모달 뷰 샘플



다음과 같은 기능을 추가해 보았습니다.
  • tip 위치로 드래그 할 때 세미 모달 뷰를 닫습니다
  • 키보드 표시/숨기기에 맞게 세미 모달 뷰의 높이를 변경합니다
  • 입력이 완료되면 세미 모달을 닫고 입력 된 값을 호출자에게 반환합니다.



    세미모달 뷰(사용자 정의 버전)





    요약



    "FloatingPanel" 을 사용하면 매우 쉽게 세미 모달 뷰를 추가 할 수있었습니다.

    iOS의 표준 기능으로 실현되면, , , 그리고 2개의 발을 밟고 있는 분도, 검증만으로도 사용해 볼 가치가 있다고 생각합니다.

    또 사용해 보고 눈치챈 것은, 통상의 전체화면 모달에서는, 모달로 표시하고 있는 이외의 조작을 블록 하지만, 세미모달에서는 유저의 조작은 블록 되지 않는다고 하는 차이가 있다고 하는 것입니다.

    실제 제품의 UI에 가져올 때 전체 화면 모달로 표시하고 있는 화면을 단순히 세미 모달로 바꾸면 여러가지 파탄해 버릴 가능성이 있습니다. "FloatingPanel" 을 사용하여 실제로 시도해 보는 것이 좋습니다!
  • 좋은 웹페이지 즐겨찾기