diff --git a/Sources/Pageboy.xcodeproj/project.pbxproj b/Sources/Pageboy.xcodeproj/project.pbxproj index dd9d824f..51171c02 100644 --- a/Sources/Pageboy.xcodeproj/project.pbxproj +++ b/Sources/Pageboy.xcodeproj/project.pbxproj @@ -30,8 +30,6 @@ 464ADF5F20975E5000929AFB /* UIViewController+Pageboy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464ADF5E20975E5000929AFB /* UIViewController+Pageboy.swift */; }; 464ADF6020975E5000929AFB /* UIViewController+Pageboy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 464ADF5E20975E5000929AFB /* UIViewController+Pageboy.swift */; }; 466A76B61FB38B32000B5C1C /* PageboyViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D623B1D11E1D2DF200527F3D /* PageboyViewController.swift */; }; - 468B6FC020EF66A30038E26C /* ScrollObservationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 468B6FBF20EF66A30038E26C /* ScrollObservationService.swift */; }; - 468B6FC120EF66A30038E26C /* ScrollObservationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 468B6FBF20EF66A30038E26C /* ScrollObservationService.swift */; }; 46ADAAB6208F7E1500974529 /* PageboyAutoScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46ADAAB4208F7E1500974529 /* PageboyAutoScroller.swift */; }; 46ADAAB7208F7E1500974529 /* PageboyAutoScroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46ADAAB4208F7E1500974529 /* PageboyAutoScroller.swift */; }; 46ADAAB8208F7E1500974529 /* PageboyViewController+AutoScrolling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46ADAAB5208F7E1500974529 /* PageboyViewController+AutoScrolling.swift */; }; @@ -87,7 +85,6 @@ 464ADF5820975E3D00929AFB /* PageboyViewControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageboyViewControllerDelegate.swift; sourceTree = ""; }; 464ADF5920975E3D00929AFB /* PageboyViewControllerDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageboyViewControllerDataSource.swift; sourceTree = ""; }; 464ADF5E20975E5000929AFB /* UIViewController+Pageboy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Pageboy.swift"; sourceTree = ""; }; - 468B6FBF20EF66A30038E26C /* ScrollObservationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollObservationService.swift; sourceTree = ""; }; 46ADAAB4208F7E1500974529 /* PageboyAutoScroller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PageboyAutoScroller.swift; sourceTree = ""; }; 46ADAAB5208F7E1500974529 /* PageboyViewController+AutoScrolling.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PageboyViewController+AutoScrolling.swift"; sourceTree = ""; }; 46ADAABB208F7E8500974529 /* PageboyViewController+Transitioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PageboyViewController+Transitioning.swift"; sourceTree = ""; }; @@ -271,7 +268,6 @@ isa = PBXGroup; children = ( 462A65D82000FCAA0051C79C /* Extensions */, - 468B6FBF20EF66A30038E26C /* ScrollObservationService.swift */, ); path = Utilities; sourceTree = ""; @@ -485,7 +481,6 @@ 46ADAAB6208F7E1500974529 /* PageboyAutoScroller.swift in Sources */, 464ADF552097565D00929AFB /* Page.swift in Sources */, 46ADAAB8208F7E1500974529 /* PageboyViewController+AutoScrolling.swift in Sources */, - 468B6FC020EF66A30038E26C /* ScrollObservationService.swift in Sources */, 462A65E32000FCAA0051C79C /* UIPageViewController+ScrollView.swift in Sources */, 46ADAAC2208F7E8500974529 /* TransitionOperation.swift in Sources */, 461D6DF1201795A100E0CDEE /* UIScrollView+ScrollActivity.swift in Sources */, @@ -531,7 +526,6 @@ 46ADAAB7208F7E1500974529 /* PageboyAutoScroller.swift in Sources */, 464ADF562097565D00929AFB /* Page.swift in Sources */, 46ADAAB9208F7E1500974529 /* PageboyViewController+AutoScrolling.swift in Sources */, - 468B6FC120EF66A30038E26C /* ScrollObservationService.swift in Sources */, 462A65E42000FCAA0051C79C /* UIPageViewController+ScrollView.swift in Sources */, 461D6DF2201795A100E0CDEE /* UIScrollView+ScrollActivity.swift in Sources */, 46ADAAC3208F7E8500974529 /* TransitionOperation.swift in Sources */, diff --git a/Sources/Pageboy/PageboyViewController+Management.swift b/Sources/Pageboy/PageboyViewController+Management.swift index 4876dbb6..a23e24d7 100644 --- a/Sources/Pageboy/PageboyViewController+Management.swift +++ b/Sources/Pageboy/PageboyViewController+Management.swift @@ -98,7 +98,10 @@ internal extension PageboyViewController { // if not using a custom transition then animate using UIPageViewController mechanism let animateUpdate = animated ? !isUsingCustomTransition : false - let updateBlock = { [unowned self] in + let updateBlock = { [weak self] in + guard let self = self else { + return + } pageViewController.setViewControllers(viewControllers, direction: direction.layoutNormalized(isRtL: self.view.layoutIsRightToLeft).rawValue, animated: animateUpdate, diff --git a/Sources/Pageboy/Utilities/Extensions/UIView+Localization.swift b/Sources/Pageboy/Utilities/Extensions/UIView+Localization.swift index c8b15601..8189ab93 100644 --- a/Sources/Pageboy/Utilities/Extensions/UIView+Localization.swift +++ b/Sources/Pageboy/Utilities/Extensions/UIView+Localization.swift @@ -12,11 +12,20 @@ extension UIView { /// Whether the layout direction of the view is right to left. var layoutIsRightToLeft: Bool { - if #available(iOS 9.0, *) { - return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft + var layoutDirection: UIUserInterfaceLayoutDirection! + if Thread.isMainThread { + layoutDirection = getUserInterfaceLayoutDirection() } else { - return UIApplication.safeShared?.userInterfaceLayoutDirection == .rightToLeft + DispatchQueue.main.sync { + layoutDirection = getUserInterfaceLayoutDirection() + } } + return layoutDirection == .rightToLeft + } + + private func getUserInterfaceLayoutDirection() -> UIUserInterfaceLayoutDirection { + assert(Thread.isMainThread) + return UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) } } diff --git a/Sources/Pageboy/Utilities/ScrollObservationService.swift b/Sources/Pageboy/Utilities/ScrollObservationService.swift deleted file mode 100644 index 352098f9..00000000 --- a/Sources/Pageboy/Utilities/ScrollObservationService.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// ScrollObservationService.swift -// Pageboy -// -// Created by Merrick Sapsford on 04/03/2018. -// Copyright © 2018 UI At Six. All rights reserved. -// - -import UIKit - -internal protocol ScrollObservationServiceDelegate: class { - - func scrollObservationService(_ service: ScrollObservationService, - didObserveOffsetChangeFor viewController: UIViewController, - on scrollView: UIScrollView, - contentOffset: CGPoint) -} - -internal class ScrollObservationService { - - private(set) lazy var registrations = [Int: UIViewController]() - private var tokens = [Int: NSKeyValueObservation?]() - - weak var delegate: ScrollObservationServiceDelegate? - - // MARK: Registration - - func register(viewController: UIViewController, for index: Int) { - if let existingRegistration = registrations[index], existingRegistration === viewController { - return - } - - registrations[index] = viewController - hook(registration: viewController) - } - - func unregister(index: Int) { - if let viewController = registrations[index] { - unhook(registration: viewController) - registrations.removeValue(forKey: index) - } - } - - // MARK: Evaluation - - private func unhook(registration: UIViewController) { - let viewController = registration - tokens.removeValue(forKey: viewController.hash) - } - - private func hook(registration: UIViewController) { - let viewController = registration - for scrollView in viewController.view.scrollViewSubviews { - let token = scrollView.observe(\.contentOffset, changeHandler: { [weak self] (scrollView, _) in - if let self = self { - self.delegate?.scrollObservationService(self, - didObserveOffsetChangeFor: viewController, - on: scrollView, - contentOffset: scrollView.contentOffset) - } - }) - tokens[viewController.hash] = token - } - } -} - -private extension UIView { - - var scrollViewSubviews: [UIScrollView] { - var scrollViews = [UIScrollView]() - subviews.forEach { (subview) in - if let scrollView = subview as? UIScrollView { - scrollViews.append(scrollView) - } - } - return scrollViews - } -}