diff --git a/DLAutoSlidePageViewController.podspec b/DLAutoSlidePageViewController.podspec index b31cdae..0632f05 100644 --- a/DLAutoSlidePageViewController.podspec +++ b/DLAutoSlidePageViewController.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'DLAutoSlidePageViewController' - s.version = '2.1.0' + s.version = '3.0.0' s.summary = 'An auto slide PageViewController.' s.description = <<-DESC diff --git a/Example/DLAutoSlidePageViewController.xcodeproj/project.pbxproj b/Example/DLAutoSlidePageViewController.xcodeproj/project.pbxproj index 40fd46b..bd2d17f 100644 --- a/Example/DLAutoSlidePageViewController.xcodeproj/project.pbxproj +++ b/Example/DLAutoSlidePageViewController.xcodeproj/project.pbxproj @@ -246,7 +246,7 @@ INFOPLIST_FILE = "$(SRCROOT)/DLAutoSlidePageViewController/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.alonso.DLAutoSlidePageViewControllera; + PRODUCT_BUNDLE_IDENTIFIER = com.alonso.DLAutoSlidePageViewControllers; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; @@ -263,7 +263,7 @@ INFOPLIST_FILE = "$(SRCROOT)/DLAutoSlidePageViewController/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.alonso.DLAutoSlidePageViewControllera; + PRODUCT_BUNDLE_IDENTIFIER = com.alonso.DLAutoSlidePageViewControllers; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; diff --git a/README.md b/README.md index 914b631..810f31a 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ pod "DLAutoSlidePageViewController" To integrate using [Swift Package Manager](https://swift.org/package-manager/), add the following as a dependency to your Package.swift: ```Swift -.package(url: "https://github.com/DeluxeAlonso/DLAutoSlidePageViewController.git", .upToNextMajor(from: "1.2.0")) +.package(url: "https://github.com/DeluxeAlonso/DLAutoSlidePageViewController.git", .upToNextMajor(from: "3.0.0")) ``` ## Usage @@ -101,6 +101,8 @@ let pageViewController = DLAutoSlidePageViewController(pages: pages, configurati | pageControlDirection | UIPageControl.Direction | Decribes the layout direction of a page control’s indicators. Available since iOS 16. | | pageControlPreferredIndicatorImage | UIImage | The preferred image for indicators. Symbol images are recommended. Default is nil. Available since iOS 14. | | pageControlPreferredCurrentPageIndicatorImage | UIImage | The preferred image for the current page indicator. Available since iOS 16. | +| shouldSlideOnTap | Bool | Indicates if the page controller should slide back/forward when the users taps on the left/right side. | +| tappableAreaPercentage | Float | Tappable area percentage used to detect taps on both sides: left and right. Defaults to 20%. Only used if shouldSlideOnTap is set to true. | ## Author diff --git a/Sources/AutoSlideConfiguration.swift b/Sources/AutoSlideConfiguration.swift index fad4c88..373bbea 100644 --- a/Sources/AutoSlideConfiguration.swift +++ b/Sources/AutoSlideConfiguration.swift @@ -57,6 +57,12 @@ public protocol AutoSlideConfiguration { /// Indicates whether the automatic transition is to be animated. var shouldAnimateTransition: Bool { get } + /// Indicates if the page controller should slide back/forward when the users taps on the left/right side. + var shouldSlideOnTap: Bool { get } + + /// Tappable area percentage used to detect taps on both sides: left and right. Defaults to 20%. Only used if shouldSlideOnTap is set to true. + var tappableAreaPercentage: Float { get } + } // MARK: - Default values @@ -83,4 +89,7 @@ public extension AutoSlideConfiguration { var shouldAnimateTransition: Bool { true } + var shouldSlideOnTap: Bool { true } + var tappableAreaPercentage: Float { 20 } + } diff --git a/Sources/DLAutoSlidePageViewController.swift b/Sources/DLAutoSlidePageViewController.swift index be5d409..31d791f 100644 --- a/Sources/DLAutoSlidePageViewController.swift +++ b/Sources/DLAutoSlidePageViewController.swift @@ -17,7 +17,11 @@ open class DLAutoSlidePageViewController: UIPageViewController { private var nextPageIndex: Int = 0 private var timer: Timer? - private var transitionInProgress: Bool = false + private var transitionInProgress: Bool = false { + didSet { + view.isUserInteractionEnabled = !transitionInProgress + } + } // MARK: - Computed properties @@ -85,6 +89,16 @@ open class DLAutoSlidePageViewController: UIPageViewController { delegate = self dataSource = self setupObservers() + + if configuration.shouldSlideOnTap { + setupTapGesture() + } + } + + private func setupTapGesture() { + let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapGestureHandler)) + gestureRecognizer.delegate = self + view.addGestureRecognizer(gestureRecognizer) } // MARK: - Private @@ -143,8 +157,31 @@ open class DLAutoSlidePageViewController: UIPageViewController { setupPageTimer(with: configuration.timeInterval) } + private func movePage(with navigationDirection: NavigationDirection, animated: Bool) { + currentPageIndex = AutoSlideHelper.pageIndex(for: currentPageIndex, + totalPageCount: pages.count, + direction: navigationDirection) + guard let viewController = viewControllerAtIndex(currentPageIndex) as UIViewController? else { return } + if !transitionInProgress { + transitionInProgress = true + setViewControllers([viewController], direction: navigationDirection, animated: animated, completion: { finished in + self.transitionInProgress = false + }) + } + } + // MARK: - Selectors + @objc private func tapGestureHandler(_ sender: UITapGestureRecognizer) { + let point = sender.location(in: self.view) + let tappableArea = view.frame.width * (CGFloat(configuration.tappableAreaPercentage) / 100) + if point.x <= tappableArea { // Tap on left side + movePage(with: .reverse, animated: true) + } else if point.x >= view.frame.width - tappableArea { // Tap on right side + movePage(with: .forward, animated: true) + } + } + @objc private func movedToForeground() { transitionInProgress = false restartTimer() @@ -153,16 +190,7 @@ open class DLAutoSlidePageViewController: UIPageViewController { @objc private func changePage() { let navigationDirection = configuration.navigationDirection let shouldAnimateTransition = configuration.shouldAnimateTransition - currentPageIndex = AutoSlideHelper.pageIndex(for: currentPageIndex, - totalPageCount: pages.count, - direction: navigationDirection) - guard let viewController = viewControllerAtIndex(currentPageIndex) as UIViewController? else { return } - if !transitionInProgress { - transitionInProgress = true - setViewControllers([viewController], direction: navigationDirection, animated: shouldAnimateTransition, completion: { finished in - self.transitionInProgress = false - }) - } + movePage(with: navigationDirection, animated: shouldAnimateTransition) } } @@ -223,3 +251,13 @@ extension DLAutoSlidePageViewController: UIPageViewControllerDataSource { } } + +// MARK: - UIGestureRecognizerDelegate + +extension DLAutoSlidePageViewController: UIGestureRecognizerDelegate { + + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { + return true + } + +} diff --git a/Sources/DefaultAutoSlideConfiguration.swift b/Sources/DefaultAutoSlideConfiguration.swift index 8bfeddc..36959ca 100644 --- a/Sources/DefaultAutoSlideConfiguration.swift +++ b/Sources/DefaultAutoSlideConfiguration.swift @@ -28,5 +28,8 @@ final public class DefaultAutoSlideConfiguration: AutoSlideConfiguration { public var pageControlBackgroundColor: UIColor = UIColor.clear public var shouldAnimateTransition: Bool = true + + public var shouldSlideOnTap: Bool = false + public var tappableAreaPercentage: Float = 20 }