diff --git a/.travis.yml b/.travis.yml index 0a40e649..40a74940 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: swift branches: only: - master - - next cache: directories: - /usr/local/Homebrew @@ -19,15 +18,20 @@ jobs: - stage: Build framework(swift 4.1) osx_image: xcode9.4 script: - - xcodebuild -scheme FloatingPanel clean build + - xcodebuild -scheme FloatingPanel SWIFT_VERSION=4.1 clean build - stage: Build framework(swift 4.2) osx_image: xcode10 script: - - xcodebuild -scheme FloatingPanel clean build + - xcodebuild -scheme FloatingPanel SWIFT_VERSION=4.2 clean build + + - stage: Build framework(swift 5.0) + osx_image: xcode10.2 + script: + - xcodebuild -scheme FloatingPanel SWIFT_VERSION=5.0 clean build - stage: Carthage - osx_image: xcode10 + osx_image: xcode10.2 before_install: - brew update - brew outdated carthage || brew upgrade carthage @@ -35,21 +39,21 @@ jobs: - carthage build --no-skip-current - stage: Podspec - osx_image: xcode10 + osx_image: xcode10.2 script: - pod spec lint - stage: Build maps example - osx_image: xcode10 + osx_image: xcode10.2 script: - xcodebuild -scheme Maps -sdk iphonesimulator clean build - stage: Build stocks example - osx_image: xcode10 + osx_image: xcode10.2 script: - xcodebuild -scheme Stocks -sdk iphonesimulator clean build - stage: Build samples example - osx_image: xcode10 + osx_image: xcode10.2 script: - xcodebuild -scheme Samples -sdk iphonesimulator clean build diff --git a/Examples/Maps/Maps.xcodeproj/project.pbxproj b/Examples/Maps/Maps.xcodeproj/project.pbxproj index c22ac05a..c78d4b2a 100644 --- a/Examples/Maps/Maps.xcodeproj/project.pbxproj +++ b/Examples/Maps/Maps.xcodeproj/project.pbxproj @@ -312,7 +312,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.Maps; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -331,7 +331,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.Maps; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Examples/Samples/Samples.xcodeproj/project.pbxproj b/Examples/Samples/Samples.xcodeproj/project.pbxproj index efc2909b..f18d65c9 100644 --- a/Examples/Samples/Samples.xcodeproj/project.pbxproj +++ b/Examples/Samples/Samples.xcodeproj/project.pbxproj @@ -499,7 +499,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.FloatingPanelSample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -518,7 +518,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.FloatingPanelSample; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Examples/Stocks/Stocks.xcodeproj/project.pbxproj b/Examples/Stocks/Stocks.xcodeproj/project.pbxproj index 6490673b..7cb3fb21 100644 --- a/Examples/Stocks/Stocks.xcodeproj/project.pbxproj +++ b/Examples/Stocks/Stocks.xcodeproj/project.pbxproj @@ -312,7 +312,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.Stocks; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -331,7 +331,7 @@ ); PRODUCT_BUNDLE_IDENTIFIER = com.scenee.Stocks; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 4.2; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; diff --git a/Framework/Sources/FloatingPanel.swift b/Framework/Sources/FloatingPanel.swift index 8b76f7c3..bf88c927 100644 --- a/Framework/Sources/FloatingPanel.swift +++ b/Framework/Sources/FloatingPanel.swift @@ -307,7 +307,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate self.animator = nil // A user can stop a panel at the nearest Y of a target position - if fabs(surfaceView.frame.minY - layoutAdapter.topY) < 1 { + if abs(surfaceView.frame.minY - layoutAdapter.topY) < 1 { surfaceView.frame.origin.y = layoutAdapter.topY } } @@ -502,7 +502,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate if isRemovalInteractionEnabled, isBottomState { let velocityVector = (distance != 0) ? CGVector(dx: 0, - dy: min(fabs(velocity.y)/distance, behavior.removalVelocity)) : .zero + dy: min(abs(velocity.y)/distance, behavior.removalVelocity)) : .zero if shouldStartRemovalAnimation(with: velocityVector) { @@ -619,7 +619,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate isDecelerating = true viewcontroller.delegate?.floatingPanelWillBeginDecelerating(viewcontroller) - let velocityVector = (distance != 0) ? CGVector(dx: 0, dy: min(fabs(velocity.y)/distance, 30.0)) : .zero + let velocityVector = (distance != 0) ? CGVector(dx: 0, dy: min(abs(velocity.y)/distance, 30.0)) : .zero let animator = behavior.interactionAnimator(self.viewcontroller, to: targetPosition, with: velocityVector) animator.addAnimations { [weak self] in guard let `self` = self else { return } @@ -660,11 +660,11 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate switch targetPosition { case .full: - return CGFloat(fabs(currentY - topY)) + return CGFloat(abs(currentY - topY)) case .half: - return CGFloat(fabs(currentY - middleY)) + return CGFloat(abs(currentY - middleY)) case .tip: - return CGFloat(fabs(currentY - bottomY)) + return CGFloat(abs(currentY - bottomY)) case .hidden: fatalError("Now .hidden must not be used for a user interaction") } @@ -703,7 +703,7 @@ class FloatingPanel: NSObject, UIGestureRecognizerDelegate, UIScrollViewDelegate // Distance travelled after decelerating to zero velocity at a constant rate. // Refer to the slides p176 of [Designing Fluid Interfaces](https://developer.apple.com/videos/play/wwdc2018/803/) - private func project(initialVelocity: CGFloat, decelerationRate: CGFloat = UIScrollViewDecelerationRateNormal) -> CGFloat { + private func project(initialVelocity: CGFloat, decelerationRate: CGFloat) -> CGFloat { return (initialVelocity / 1000.0) * decelerationRate / (1.0 - decelerationRate) } diff --git a/Framework/Sources/FloatingPanelBehavior.swift b/Framework/Sources/FloatingPanelBehavior.swift index a59d1274..d8504c3f 100644 --- a/Framework/Sources/FloatingPanelBehavior.swift +++ b/Framework/Sources/FloatingPanelBehavior.swift @@ -72,14 +72,18 @@ public extension FloatingPanelBehavior { } func momentumProjectionRate(_ fpc: FloatingPanelController) -> CGFloat { + #if swift(>=4.2) + return UIScrollView.DecelerationRate.normal.rawValue + #else return UIScrollViewDecelerationRateNormal + #endif } func redirectionalProgress(_ fpc: FloatingPanelController, from: FloatingPanelPosition, to: FloatingPanelPosition) -> CGFloat { return 0.5 } - public func interactionAnimator(_ fpc: FloatingPanelController, to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator { + func interactionAnimator(_ fpc: FloatingPanelController, to targetPosition: FloatingPanelPosition, with velocity: CGVector) -> UIViewPropertyAnimator { return defaultBehavior.interactionAnimator(fpc, to: targetPosition, with: velocity) } diff --git a/Framework/Sources/FloatingPanelController.swift b/Framework/Sources/FloatingPanelController.swift index 8fb1ce60..370cc910 100644 --- a/Framework/Sources/FloatingPanelController.swift +++ b/Framework/Sources/FloatingPanelController.swift @@ -351,7 +351,11 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI parent.view.addSubview(self.view) } + #if swift(>=4.2) + parent.addChild(self) + #else parent.addChildViewController(self) + #endif view.frame = parent.view.bounds // Needed for a correct safe area configuration view.translatesAutoresizingMaskIntoConstraints = false @@ -364,7 +368,11 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI show(animated: animated) { [weak self] in guard let `self` = self else { return } + #if swift(>=4.2) + self.didMove(toParent: self) + #else self.didMove(toParentViewController: self) + #endif } } @@ -380,9 +388,20 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI hide(animated: animated) { [weak self] in guard let `self` = self else { return } + #if swift(>=4.2) + self.willMove(toParent: nil) + #else self.willMove(toParentViewController: nil) + #endif + self.view.removeFromSuperview() + + #if swift(>=4.2) + self.removeFromParent() + #else self.removeFromParentViewController() + #endif + completion?() } } @@ -400,16 +419,36 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI /// Sets the view controller responsible for the content portion of the floating panel. public func set(contentViewController: UIViewController?) { if let vc = _contentViewController { + #if swift(>=4.2) + vc.willMove(toParent: nil) + #else vc.willMove(toParentViewController: nil) + #endif + vc.view.removeFromSuperview() + + #if swift(>=4.2) + vc.removeFromParent() + #else vc.removeFromParentViewController() + #endif } if let vc = contentViewController { + #if swift(>=4.2) + addChild(vc) + #else addChildViewController(vc) + #endif + let surfaceView = floatingPanel.surfaceView surfaceView.add(contentView: vc.view) + + #if swift(>=4.2) + vc.didMove(toParent: self) + #else vc.didMove(toParentViewController: self) + #endif } _contentViewController = contentViewController @@ -448,9 +487,15 @@ public class FloatingPanelController: UIViewController, UIScrollViewDelegate, UI if #available(iOS 11.0, *) { scrollView.contentInsetAdjustmentBehavior = .never } else { + #if swift(>=4.2) + children.forEach { (vc) in + vc.automaticallyAdjustsScrollViewInsets = false + } + #else childViewControllers.forEach { (vc) in vc.automaticallyAdjustsScrollViewInsets = false } + #endif } default: break @@ -504,10 +549,10 @@ extension FloatingPanelController { } public extension UIViewController { - @objc public func fp_original_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + @objc func fp_original_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // Implementation will be replaced by IMP of self.dismiss(animated:completion:) } - @objc public func fp_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + @objc func fp_dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { // Call dismiss(animated:completion:) to a content view controller if let fpc = parent as? FloatingPanelController { if fpc.presentingViewController != nil { diff --git a/Framework/Sources/FloatingPanelLayout.swift b/Framework/Sources/FloatingPanelLayout.swift index cc133813..c0774766 100644 --- a/Framework/Sources/FloatingPanelLayout.swift +++ b/Framework/Sources/FloatingPanelLayout.swift @@ -270,7 +270,11 @@ class FloatingPanelLayoutAdapter { } func updateIntrinsicHeight() { + #if swift(>=4.2) + let fittingSize = UIView.layoutFittingCompressedSize + #else let fittingSize = UILayoutFittingCompressedSize + #endif var intrinsicHeight = surfaceView.contentView?.systemLayoutSizeFitting(fittingSize).height ?? 0.0 var safeAreaBottom: CGFloat = 0.0 if #available(iOS 11.0, *) { diff --git a/Framework/Sources/UIExtensions.swift b/Framework/Sources/UIExtensions.swift index 1e510581..afa0a4b2 100644 --- a/Framework/Sources/UIExtensions.swift +++ b/Framework/Sources/UIExtensions.swift @@ -74,6 +74,20 @@ extension UIView { } #if __FP_LOG +#if swift(>=4.2) +extension UIGestureRecognizer.State: CustomDebugStringConvertible { + public var debugDescription: String { + switch self { + case .began: return "began" + case .changed: return "changed" + case .failed: return "failed" + case .cancelled: return "cancelled" + case .ended: return "endeded" + case .possible: return "possible" + } + } +} +#else extension UIGestureRecognizerState: CustomDebugStringConvertible { public var debugDescription: String { switch self { @@ -87,6 +101,7 @@ extension UIGestureRecognizerState: CustomDebugStringConvertible { } } #endif +#endif extension UIScrollView { var contentOffsetZero: CGPoint { diff --git a/README.md b/README.md index 75bc778a..66cba303 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Platform](https://img.shields.io/cocoapods/p/FloatingPanel.svg)](https://cocoapods.org/pods/FloatingPanel) [![Swift 4.1](https://img.shields.io/badge/Swift-4.1-orange.svg?style=flat)](https://swift.org/) [![Swift 4.2](https://img.shields.io/badge/Swift-4.2-orange.svg?style=flat)](https://swift.org/) +[![Swift 5.0](https://img.shields.io/badge/Swift-5.0-orange.svg?style=flat)](https://swift.org/) # FloatingPanel