Commit fd4b56bc by Daniel Dahan

development: added FABButton to BottomSheet

parent 886ee171
...@@ -9,7 +9,6 @@ ...@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
961730361E0E156400A9A297 /* SpringMotion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730351E0E156400A9A297 /* SpringMotion.swift */; }; 961730361E0E156400A9A297 /* SpringMotion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730351E0E156400A9A297 /* SpringMotion.swift */; };
9617305A1E145DE900A9A297 /* CollectionViewCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730591E145DE900A9A297 /* CollectionViewCard.swift */; }; 9617305A1E145DE900A9A297 /* CollectionViewCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730591E145DE900A9A297 /* CollectionViewCard.swift */; };
961730701E16EFFF00A9A297 /* BottomSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9617306F1E16EFFF00A9A297 /* BottomSheet.swift */; };
961730721E16F00C00A9A297 /* BottomSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730711E16F00C00A9A297 /* BottomSheetController.swift */; }; 961730721E16F00C00A9A297 /* BottomSheetController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 961730711E16F00C00A9A297 /* BottomSheetController.swift */; };
9617B07D1DFCA8CF00410F8F /* Application.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961E6BDE1DDA2A95004E6C93 /* Application.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 9617B07D1DFCA8CF00410F8F /* Application.swift in Headers */ = {isa = PBXBuildFile; fileRef = 961E6BDE1DDA2A95004E6C93 /* Application.swift */; settings = {ATTRIBUTES = (Public, ); }; };
9617B07E1DFCA8CF00410F8F /* Card.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB75D1CB40DC500C806FE /* Card.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 9617B07E1DFCA8CF00410F8F /* Card.swift in Headers */ = {isa = PBXBuildFile; fileRef = 96BCB75D1CB40DC500C806FE /* Card.swift */; settings = {ATTRIBUTES = (Public, ); }; };
...@@ -230,7 +229,6 @@ ...@@ -230,7 +229,6 @@
961276621DCD8B1800A7D920 /* CharacterAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterAttribute.swift; sourceTree = "<group>"; }; 961276621DCD8B1800A7D920 /* CharacterAttribute.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CharacterAttribute.swift; sourceTree = "<group>"; };
961730351E0E156400A9A297 /* SpringMotion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpringMotion.swift; sourceTree = "<group>"; }; 961730351E0E156400A9A297 /* SpringMotion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpringMotion.swift; sourceTree = "<group>"; };
961730591E145DE900A9A297 /* CollectionViewCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCard.swift; sourceTree = "<group>"; }; 961730591E145DE900A9A297 /* CollectionViewCard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCard.swift; sourceTree = "<group>"; };
9617306F1E16EFFF00A9A297 /* BottomSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheet.swift; sourceTree = "<group>"; };
961730711E16F00C00A9A297 /* BottomSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheetController.swift; sourceTree = "<group>"; }; 961730711E16F00C00A9A297 /* BottomSheetController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BottomSheetController.swift; sourceTree = "<group>"; };
961DED451DCC40C500F425B6 /* Editor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = "<group>"; }; 961DED451DCC40C500F425B6 /* Editor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Editor.swift; sourceTree = "<group>"; };
961DED4A1DCC546100F425B6 /* EditorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorController.swift; sourceTree = "<group>"; }; 961DED4A1DCC546100F425B6 /* EditorController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EditorController.swift; sourceTree = "<group>"; };
...@@ -393,7 +391,6 @@ ...@@ -393,7 +391,6 @@
9617306E1E16EFE300A9A297 /* BottomSheet */ = { 9617306E1E16EFE300A9A297 /* BottomSheet */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9617306F1E16EFFF00A9A297 /* BottomSheet.swift */,
961730711E16F00C00A9A297 /* BottomSheetController.swift */, 961730711E16F00C00A9A297 /* BottomSheetController.swift */,
); );
name = BottomSheet; name = BottomSheet;
...@@ -1214,7 +1211,6 @@ ...@@ -1214,7 +1211,6 @@
965E80E51DD4C53300D61E4B /* PulseMotion.swift in Sources */, 965E80E51DD4C53300D61E4B /* PulseMotion.swift in Sources */,
965E80FE1DD4D59500D61E4B /* ToolbarController.swift in Sources */, 965E80FE1DD4D59500D61E4B /* ToolbarController.swift in Sources */,
96328B971E05C0BB009A4C90 /* TableView.swift in Sources */, 96328B971E05C0BB009A4C90 /* TableView.swift in Sources */,
961730701E16EFFF00A9A297 /* BottomSheet.swift in Sources */,
965E80C81DD4C50600D61E4B /* Motion.swift in Sources */, 965E80C81DD4C50600D61E4B /* Motion.swift in Sources */,
965E80C91DD4C50600D61E4B /* TransitionMotion.swift in Sources */, 965E80C91DD4C50600D61E4B /* TransitionMotion.swift in Sources */,
965E80CA1DD4C50600D61E4B /* KeyframeMotion.swift in Sources */, 965E80CA1DD4C50600D61E4B /* KeyframeMotion.swift in Sources */,
......
/*
* Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of CosmicMind nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import UIKit
class BottomSheet: CollectionViewCard {
}
...@@ -36,6 +36,49 @@ public enum BottomSheetPosition: Int { ...@@ -36,6 +36,49 @@ public enum BottomSheetPosition: Int {
case right case right
} }
open class BottomSheet: View {
/// A reference to a FABButton.
open var fabButton: FABButton? {
didSet {
layoutSubviews()
}
}
open override func layoutSubviews() {
super.layoutSubviews()
if let v = fabButton {
if nil == v.superview {
v.removeFromSuperview()
addSubview(v)
}
v.center = CGPoint(x: 20, y: 0)
}
}
}
extension BottomSheet {
/**
Handles the hit test for the fabButton.
- Parameter _ point: A CGPoint.
- Parameter with event: An optional UIEvent.
- Returns: An optional UIView.
*/
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
guard let v = fabButton else {
return super.hitTest(point, with: event)
}
let p = v.convert(point, from: self)
if v.bounds.contains(p) {
return v.hitTest(p, with: event)
}
return super.hitTest(point, with: event)
}
}
extension UIViewController { extension UIViewController {
/** /**
A convenience property that provides access to the BottomSheetController. A convenience property that provides access to the BottomSheetController.
...@@ -125,6 +168,12 @@ public protocol BottomSheetControllerDelegate { ...@@ -125,6 +168,12 @@ public protocol BottomSheetControllerDelegate {
optional func bottomSheetController(bottomSheetController: BottomSheetController, didTapAt point: CGPoint) optional func bottomSheetController(bottomSheetController: BottomSheetController, didTapAt point: CGPoint)
} }
@objc(BottomSheetLayoutStyle)
public enum BottomSheetLayoutStyle: Int {
case flat
case hover
}
@objc(BottomSheetController) @objc(BottomSheetController)
open class BottomSheetController: RootController { open class BottomSheetController: RootController {
/** /**
...@@ -176,12 +225,10 @@ open class BottomSheetController: RootController { ...@@ -176,12 +225,10 @@ open class BottomSheetController: RootController {
@IBInspectable @IBInspectable
open var isEnabled: Bool { open var isEnabled: Bool {
get { get {
return isBottomViewEnabled return isBottomSheetEnabled
} }
set(value) { set(value) {
if nil != bottomView { isBottomSheetEnabled = value
isBottomViewEnabled = value
}
} }
} }
...@@ -190,10 +237,10 @@ open class BottomSheetController: RootController { ...@@ -190,10 +237,10 @@ open class BottomSheetController: RootController {
opening and closing. Defaults to true. opening and closing. Defaults to true.
*/ */
@IBInspectable @IBInspectable
open var isBottomViewEnabled = false { open var isBottomSheetEnabled = false {
didSet { didSet {
isBottomPanGestureEnabled = isBottomViewEnabled isBottomPanGestureEnabled = isBottomSheetEnabled
isBottomTapGestureEnabled = isBottomViewEnabled isBottomTapGestureEnabled = isBottomSheetEnabled
} }
} }
...@@ -232,19 +279,16 @@ open class BottomSheetController: RootController { ...@@ -232,19 +279,16 @@ open class BottomSheetController: RootController {
bottomViewController. It is very rare that this property will bottomViewController. It is very rare that this property will
need to be accessed externally. need to be accessed externally.
*/ */
open fileprivate(set) var bottomView: UIView? open let bottomSheet = BottomSheet()
/// Indicates whether the bottomView or rightView is opened. /// Indicates whether the bottomView or rightView is opened.
open var isOpened: Bool { open var isOpened: Bool {
return isBottomViewOpened return isBottomSheetOpened
} }
/// indicates if the bottomView is opened. /// indicates if the bottomView is opened.
open var isBottomViewOpened: Bool { open var isBottomSheetOpened: Bool {
guard let v = bottomView else { return bottomSheet.y != Screen.height
return false
}
return v.y != Screen.height
} }
/** /**
...@@ -260,6 +304,20 @@ open class BottomSheetController: RootController { ...@@ -260,6 +304,20 @@ open class BottomSheetController: RootController {
@IBInspectable @IBInspectable
open fileprivate(set) var bottomViewHeight: CGFloat! open fileprivate(set) var bottomViewHeight: CGFloat!
/// Determines the layout style for the bottomSheet.
open var bottomSheetLayoutStyle = BottomSheetLayoutStyle.hover {
didSet {
switch bottomSheetLayoutStyle {
case .hover:
depthPreset = .depth1
case .flat:
depthPreset = .none
openBottomSheet()
isBottomSheetEnabled = false
}
}
}
/** /**
An initializer that initializes the object with a NSCoder object. An initializer that initializes the object with a NSCoder object.
- Parameter aDecoder: A NSCoder instance. - Parameter aDecoder: A NSCoder instance.
...@@ -293,21 +351,17 @@ open class BottomSheetController: RootController { ...@@ -293,21 +351,17 @@ open class BottomSheetController: RootController {
/// Layout subviews. /// Layout subviews.
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
guard let v = bottomView else { bottomSheet.width = view.bounds.width
return bottomSheet.height = bottomViewHeight
}
v.width = view.bounds.width
v.height = bottomViewHeight
bottomViewThreshold = view.bounds.height - bottomViewHeight / 2 bottomViewThreshold = view.bounds.height - bottomViewHeight / 2
guard let vc = bottomViewController else { guard let vc = bottomViewController else {
return return
} }
vc.view.width = v.bounds.width vc.view.width = bottomSheet.bounds.width
vc.view.height = bottomViewHeight vc.view.height = bottomViewHeight
vc.view.center = CGPoint(x: v.bounds.width / 2, y: bottomViewHeight / 2) vc.view.center = CGPoint(x: bottomSheet.bounds.width / 2, y: bottomViewHeight / 2)
} }
/** /**
...@@ -319,7 +373,7 @@ open class BottomSheetController: RootController { ...@@ -319,7 +373,7 @@ open class BottomSheetController: RootController {
*/ */
open override func prepare() { open override func prepare() {
super.prepare() super.prepare()
prepareBottomView() prepareBottomSheet()
} }
/** /**
...@@ -332,19 +386,15 @@ open class BottomSheetController: RootController { ...@@ -332,19 +386,15 @@ open class BottomSheetController: RootController {
- Parameter animated: A Boolean value that indicates to animate - Parameter animated: A Boolean value that indicates to animate
the bottomView width change. the bottomView width change.
*/ */
open func setBottomViewHeight(height: CGFloat, isHidden: Bool, animated: Bool, duration: TimeInterval = 0.5) { open func setBottomSheetHeight(height: CGFloat, isHidden: Bool, animated: Bool, duration: TimeInterval = 0.5) {
guard let v = bottomView else {
return
}
bottomViewHeight = height bottomViewHeight = height
if animated { if animated {
v.isShadowPathAutoSizing = false bottomSheet.isShadowPathAutoSizing = false
if isHidden { if isHidden {
UIView.animate(withDuration: duration, UIView.animate(withDuration: duration,
animations: { [weak self, v = v] in animations: { [weak self, v = bottomSheet] in
guard let s = self else { guard let s = self else {
return return
} }
...@@ -352,7 +402,7 @@ open class BottomSheetController: RootController { ...@@ -352,7 +402,7 @@ open class BottomSheetController: RootController {
v.bounds.size.height = height v.bounds.size.height = height
v.position.y = -height / 2 v.position.y = -height / 2
s.rootViewController.view.alpha = 1 s.rootViewController.view.alpha = 1
}) { [weak self, v = v] _ in }) { [weak self, v = bottomSheet] _ in
guard let s = self else { guard let s = self else {
return return
} }
...@@ -363,7 +413,7 @@ open class BottomSheetController: RootController { ...@@ -363,7 +413,7 @@ open class BottomSheetController: RootController {
} }
} else { } else {
UIView.animate(withDuration: duration, UIView.animate(withDuration: duration,
animations: { [weak self, v = v] in animations: { [weak self, v = bottomSheet] in
guard let s = self else { guard let s = self else {
return return
} }
...@@ -371,7 +421,7 @@ open class BottomSheetController: RootController { ...@@ -371,7 +421,7 @@ open class BottomSheetController: RootController {
v.bounds.size.height = height v.bounds.size.height = height
v.position.y = height / 2 v.position.y = height / 2
s.rootViewController.view.alpha = 0.5 s.rootViewController.view.alpha = 0.5
}) { [weak self, v = v] _ in }) { [weak self, v = bottomSheet] _ in
guard let s = self else { guard let s = self else {
return return
} }
...@@ -382,19 +432,19 @@ open class BottomSheetController: RootController { ...@@ -382,19 +432,19 @@ open class BottomSheetController: RootController {
} }
} }
} else { } else {
v.bounds.size.height = height bottomSheet.bounds.size.height = height
if isHidden { if isHidden {
hideView(container: v) hideView(container: bottomSheet)
v.position.y = -v.bounds.height / 2 bottomSheet.position.y = -bottomSheet.bounds.height / 2
rootViewController.view.alpha = 1 rootViewController.view.alpha = 1
} else { } else {
v.isShadowPathAutoSizing = false bottomSheet.isShadowPathAutoSizing = false
showView(container: v) showView(container: bottomSheet)
v.position.y = height / 2 bottomSheet.position.y = height / 2
rootViewController.view.alpha = 0.5 rootViewController.view.alpha = 0.5
v.isShadowPathAutoSizing = true bottomSheet.isShadowPathAutoSizing = true
} }
layoutSubviews() layoutSubviews()
...@@ -408,8 +458,8 @@ open class BottomSheetController: RootController { ...@@ -408,8 +458,8 @@ open class BottomSheetController: RootController {
velocity of the user interaction when animating the velocity of the user interaction when animating the
bottomView. Defaults to 0. bottomView. Defaults to 0.
*/ */
open func toggleBottomView(velocity: CGFloat = 0) { open func toggleBottomSheet(velocity: CGFloat = 0) {
isBottomViewOpened ? closeBottomView(velocity: velocity) : openBottomView(velocity: velocity) isBottomSheetOpened ? closeBottomSheet(velocity: velocity) : openBottomSheet(velocity: velocity)
} }
/** /**
...@@ -418,29 +468,28 @@ open class BottomSheetController: RootController { ...@@ -418,29 +468,28 @@ open class BottomSheetController: RootController {
velocity of the user interaction when animating the velocity of the user interaction when animating the
bottomView. Defaults to 0. bottomView. Defaults to 0.
*/ */
open func openBottomView(velocity: CGFloat = 0) { open func openBottomSheet(velocity: CGFloat = 0) {
guard isBottomViewEnabled else { guard isBottomSheetEnabled else {
return return
} }
guard let v = bottomView else { showView(container: bottomSheet)
return
}
showView(container: v)
isUserInteractionEnabled = false isUserInteractionEnabled = false
delegate?.bottomSheetControllerWillOpen?(bottomSheetController: self) delegate?.bottomSheetControllerWillOpen?(bottomSheetController: self)
UIView.animate(withDuration: TimeInterval(0 == velocity ? animationDuration : fmax(0.1, fmin(1, Double(v.y / velocity)))), UIView.animate(withDuration: TimeInterval(0 == velocity ? animationDuration : fmax(0.1, fmin(1, Double(bottomSheet.y / velocity)))),
animations: { [weak self, v = v] in animations: { [weak self, v = bottomSheet] in
guard let s = self else { guard let s = self else {
return return
} }
v.position.y = s.view.bounds.height - v.bounds.height / 2 v.position.y = s.view.bounds.height - v.bounds.height / 2
if .hover == s.bottomSheetLayoutStyle {
s.rootViewController.view.alpha = 0.5 s.rootViewController.view.alpha = 0.5
}
}) { [weak self] _ in }) { [weak self] _ in
guard let s = self else { guard let s = self else {
return return
...@@ -456,12 +505,8 @@ open class BottomSheetController: RootController { ...@@ -456,12 +505,8 @@ open class BottomSheetController: RootController {
velocity of the user interaction when animating the velocity of the user interaction when animating the
bottomView. Defaults to 0. bottomView. Defaults to 0.
*/ */
open func closeBottomView(velocity: CGFloat = 0) { open func closeBottomSheet(velocity: CGFloat = 0) {
guard isBottomViewEnabled else { guard isBottomSheetEnabled else {
return
}
guard let v = bottomView else {
return return
} }
...@@ -469,15 +514,18 @@ open class BottomSheetController: RootController { ...@@ -469,15 +514,18 @@ open class BottomSheetController: RootController {
delegate?.bottomSheetControllerWillClose?(bottomSheetController: self) delegate?.bottomSheetControllerWillClose?(bottomSheetController: self)
UIView.animate(withDuration: TimeInterval(0 == velocity ? animationDuration : fmax(0.1, fmin(1, Double(v.y / velocity)))), UIView.animate(withDuration: TimeInterval(0 == velocity ? animationDuration : fmax(0.1, fmin(1, Double(bottomSheet.y / velocity)))),
animations: { [weak self, v = v] in animations: { [weak self, v = bottomSheet] in
guard let s = self else { guard let s = self else {
return return
} }
v.position.y = s.view.bounds.height + v.bounds.height / 2 v.position.y = s.view.bounds.height + v.bounds.height / 2
if .hover == s.bottomSheetLayoutStyle {
s.rootViewController.view.alpha = 1 s.rootViewController.view.alpha = 1
}) { [weak self, v = v] _ in }
}) { [weak self, v = bottomSheet] _ in
guard let s = self else { guard let s = self else {
return return
} }
...@@ -489,7 +537,7 @@ open class BottomSheetController: RootController { ...@@ -489,7 +537,7 @@ open class BottomSheetController: RootController {
} }
/// A method that removes the passed in pan and bottomView tap gesture recognizers. /// A method that removes the passed in pan and bottomView tap gesture recognizers.
fileprivate func removeBottomViewGestures() { fileprivate func removeBottomSheetGestures() {
removeBottomPanGesture() removeBottomPanGesture()
removeBottomTapGesture() removeBottomTapGesture()
} }
...@@ -562,32 +610,27 @@ open class BottomSheetController: RootController { ...@@ -562,32 +610,27 @@ open class BottomSheetController: RootController {
extension BottomSheetController { extension BottomSheetController {
/// A method that prepares the bottomViewController. /// A method that prepares the bottomViewController.
fileprivate func prepareBottomViewController() { fileprivate func prepareBottomSheetController() {
guard let v = bottomView else { prepare(viewController: bottomViewController, withContainer: bottomSheet)
return
}
prepare(viewController: bottomViewController, withContainer: v)
} }
/// A method that prepares the bottomView. /// A method that prepares the bottomView.
fileprivate func prepareBottomView() { fileprivate func prepareBottomSheet() {
bottomViewHeight = .phone == Device.userInterfaceIdiom ? 280 : 320
view.addSubview(bottomSheet)
bottomSheet.isHidden = true
bottomSheet.width = view.bounds.width
bottomSheet.height = bottomViewHeight
bottomSheet.position.y = view.bounds.height + bottomViewHeight / 2
bottomSheet.zPosition = 2000
guard nil != bottomViewController else { guard nil != bottomViewController else {
return return
} }
isBottomViewEnabled = true isBottomSheetEnabled = true
prepareBottomSheetController()
bottomViewHeight = .phone == Device.userInterfaceIdiom ? 280 : 320
bottomView = UIView()
bottomView!.frame = CGRect(x: 0, y: 0, width: view.bounds.width, height: bottomViewHeight)
bottomView!.backgroundColor = Color.green.base
view.addSubview(bottomView!)
bottomView!.isHidden = true
bottomView!.position.y = view.bounds.height + bottomViewHeight / 2
bottomView!.zPosition = 2000
prepareBottomViewController()
} }
/// Prepare the left pan gesture. /// Prepare the left pan gesture.
...@@ -596,7 +639,7 @@ extension BottomSheetController { ...@@ -596,7 +639,7 @@ extension BottomSheetController {
return return
} }
bottomPanGesture = UIPanGestureRecognizer(target: self, action: #selector(handleBottomViewPanGesture(recognizer:))) bottomPanGesture = UIPanGestureRecognizer(target: self, action: #selector(handleBottomSheetPanGesture(recognizer:)))
bottomPanGesture!.delegate = self bottomPanGesture!.delegate = self
view.addGestureRecognizer(bottomPanGesture!) view.addGestureRecognizer(bottomPanGesture!)
} }
...@@ -607,7 +650,7 @@ extension BottomSheetController { ...@@ -607,7 +650,7 @@ extension BottomSheetController {
return return
} }
bottomTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleBottomViewTapGesture(recognizer:))) bottomTapGesture = UITapGestureRecognizer(target: self, action: #selector(handleBottomSheetTapGesture(recognizer:)))
bottomTapGesture!.delegate = self bottomTapGesture!.delegate = self
bottomTapGesture!.cancelsTouchesInView = false bottomTapGesture!.cancelsTouchesInView = false
view.addGestureRecognizer(bottomTapGesture!) view.addGestureRecognizer(bottomTapGesture!)
...@@ -623,11 +666,11 @@ extension BottomSheetController: UIGestureRecognizerDelegate { ...@@ -623,11 +666,11 @@ extension BottomSheetController: UIGestureRecognizerDelegate {
*/ */
@objc @objc
open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { open func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if gestureRecognizer == bottomPanGesture && (isBottomViewOpened || isPointContainedWithinBottomThreshold(point: touch.location(in: view))) { if gestureRecognizer == bottomPanGesture && (isBottomSheetOpened || isPointContainedWithinBottomThreshold(point: touch.location(in: view))) {
return true return true
} }
if isBottomViewOpened && gestureRecognizer == bottomTapGesture { if isBottomSheetOpened && gestureRecognizer == bottomTapGesture {
return true return true
} }
...@@ -641,12 +684,8 @@ extension BottomSheetController: UIGestureRecognizerDelegate { ...@@ -641,12 +684,8 @@ extension BottomSheetController: UIGestureRecognizerDelegate {
passed to the handler when recognized. passed to the handler when recognized.
*/ */
@objc @objc
fileprivate func handleBottomViewPanGesture(recognizer: UIPanGestureRecognizer) { fileprivate func handleBottomSheetPanGesture(recognizer: UIPanGestureRecognizer) {
guard isBottomViewEnabled && (isBottomViewOpened || isPointContainedWithinBottomThreshold(point: recognizer.location(in: view))) else { guard isBottomSheetEnabled && (isBottomSheetOpened || isPointContainedWithinBottomThreshold(point: recognizer.location(in: view))) else {
return
}
guard let v = bottomView else {
return return
} }
...@@ -655,18 +694,18 @@ extension BottomSheetController: UIGestureRecognizerDelegate { ...@@ -655,18 +694,18 @@ extension BottomSheetController: UIGestureRecognizerDelegate {
// Animate the panel. // Animate the panel.
switch recognizer.state { switch recognizer.state {
case .began: case .began:
originalY = v.position.y originalY = bottomSheet.position.y
showView(container: v) showView(container: bottomSheet)
delegate?.bottomSheetController?(bottomSheetController: self, didBeginPanAt: point) delegate?.bottomSheetController?(bottomSheetController: self, didBeginPanAt: point)
case .changed: case .changed:
let h = v.bounds.height let h = bottomSheet.bounds.height
let translationY = recognizer.translation(in: v).y let translationY = recognizer.translation(in: bottomSheet).y
v.position.y = originalY + translationY < view.bounds.height - (h / 2) ? view.bounds.height - (h / 2) : originalY + translationY bottomSheet.position.y = originalY + translationY < view.bounds.height - (h / 2) ? view.bounds.height - (h / 2) : originalY + translationY
let a = 1 - (view.bounds.height - v.position.y) / v.bounds.height let a = 1 - (view.bounds.height - bottomSheet.position.y) / bottomSheet.bounds.height
rootViewController.view.alpha = 0.5 < a && v.position.y >= v.bounds.height / 2 ? a : 0.5 rootViewController.view.alpha = 0.5 < a && bottomSheet.position.y >= bottomSheet.bounds.height / 2 ? a : 0.5
delegate?.bottomSheetController?(bottomSheetController: self, didChangePanAt: point) delegate?.bottomSheetController?(bottomSheetController: self, didChangePanAt: point)
case .ended, .cancelled, .failed: case .ended, .cancelled, .failed:
...@@ -675,10 +714,10 @@ extension BottomSheetController: UIGestureRecognizerDelegate { ...@@ -675,10 +714,10 @@ extension BottomSheetController: UIGestureRecognizerDelegate {
delegate?.bottomSheetController?(bottomSheetController: self, didEndPanAt: point) delegate?.bottomSheetController?(bottomSheetController: self, didEndPanAt: point)
if v.y >= bottomViewThreshold || y > 1000 { if bottomSheet.y >= bottomViewThreshold || y > 1000 {
closeBottomView(velocity: y) closeBottomSheet(velocity: y)
} else { } else {
openBottomView(velocity: y) openBottomSheet(velocity: y)
} }
case .possible:break case .possible:break
} }
...@@ -691,21 +730,17 @@ extension BottomSheetController: UIGestureRecognizerDelegate { ...@@ -691,21 +730,17 @@ extension BottomSheetController: UIGestureRecognizerDelegate {
passed to the handler when recognized. passed to the handler when recognized.
*/ */
@objc @objc
fileprivate func handleBottomViewTapGesture(recognizer: UITapGestureRecognizer) { fileprivate func handleBottomSheetTapGesture(recognizer: UITapGestureRecognizer) {
guard isBottomViewOpened else { guard isBottomSheetOpened else {
return
}
guard let v = bottomView else {
return return
} }
delegate?.bottomSheetController?(bottomSheetController: self, didTapAt: recognizer.location(in: view)) delegate?.bottomSheetController?(bottomSheetController: self, didTapAt: recognizer.location(in: view))
guard isBottomViewEnabled && isBottomViewOpened && !isPointContainedWithinView(container: v, point: recognizer.location(in: v)) else { guard isBottomSheetEnabled && isBottomSheetOpened && !isPointContainedWithinView(container: bottomSheet, point: recognizer.location(in: bottomSheet)) else {
return return
} }
closeBottomView() closeBottomSheet()
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment