From 6851e3b0725907053148cc9555c1bf4ecf39375a Mon Sep 17 00:00:00 2001 From: Shin Yamamoto Date: Fri, 29 Mar 2019 10:43:54 +0900 Subject: [PATCH] Support both of Swift 5 and 4.2 The default Swift version leaves 4.0. Because it avoids build errors with Carthage on each Xcode version from the source compatibility between Swift 4.0, 4.2 and 5.0. With regard to CocoaPods, the pod spec is going to support `swift_versions` introduced in CocoaPods v1.7.0. For now, a user needs to override `SWIFT_VERSION` appropriately in Podfile. --- .travis.yml | 20 +++++--- Examples/Maps/Maps.xcodeproj/project.pbxproj | 4 +- .../Samples/Samples.xcodeproj/project.pbxproj | 4 +- .../Stocks/Stocks.xcodeproj/project.pbxproj | 4 +- Framework/Sources/FloatingPanel.swift | 14 +++--- Framework/Sources/FloatingPanelBehavior.swift | 6 ++- .../Sources/FloatingPanelController.swift | 49 ++++++++++++++++++- Framework/Sources/FloatingPanelLayout.swift | 4 ++ Framework/Sources/UIExtensions.swift | 15 ++++++ README.md | 1 + 10 files changed, 97 insertions(+), 24 deletions(-) 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