From fedcb42cc3f73709d5a9323883c59cd918a74374 Mon Sep 17 00:00:00 2001 From: nevillco Date: Thu, 10 Nov 2016 14:51:36 -0500 Subject: [PATCH 1/5] Run Swift 3 syntax update --- RIGImageGallery.xcodeproj/project.pbxproj | 6 + .../RIGAutoCenteringScrollView.swift | 12 +- .../RIGImageGalleryViewController.swift | 131 +++++++++--------- .../RIGSingleImageViewController.swift | 6 +- .../ImageGalleryViewControllerTests.swift | 28 ++-- RIGImageGalleryTests/TestingExtensions.swift | 4 +- 6 files changed, 95 insertions(+), 92 deletions(-) diff --git a/RIGImageGallery.xcodeproj/project.pbxproj b/RIGImageGallery.xcodeproj/project.pbxproj index 71160ce..442526a 100644 --- a/RIGImageGallery.xcodeproj/project.pbxproj +++ b/RIGImageGallery.xcodeproj/project.pbxproj @@ -285,6 +285,7 @@ TargetAttributes = { 72060F4F1D2FFA6C001281E0 = { CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 0810; }; 72A828081C68F24500B25CEE = { CreatedOnToolsVersion = 7.2.1; @@ -293,6 +294,7 @@ 72BA26511C6B985900F1FE22 = { CreatedOnToolsVersion = 7.2.1; DevelopmentTeam = 336S848KQ4; + LastSwiftMigration = 0810; }; }; }; @@ -442,6 +444,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.raizlabs.RIGImageGalleryTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -454,6 +457,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = com.raizlabs.RIGImageGalleryTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -595,6 +599,7 @@ PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -614,6 +619,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.raizlabs.RIGImageGallery; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/RIGImageGallery/RIGAutoCenteringScrollView.swift b/RIGImageGallery/RIGAutoCenteringScrollView.swift index 1a7c532..0e78b7d 100644 --- a/RIGImageGallery/RIGAutoCenteringScrollView.swift +++ b/RIGImageGallery/RIGAutoCenteringScrollView.swift @@ -44,7 +44,7 @@ class RIGAutoCenteringScrollView: UIScrollView { } } - private var contentView: UIImageView? + fileprivate var contentView: UIImageView? override init(frame: CGRect) { super.init(frame: frame) @@ -65,7 +65,7 @@ class RIGAutoCenteringScrollView: UIScrollView { extension RIGAutoCenteringScrollView { - func toggleZoom(animated animated: Bool = true) { + func toggleZoom(animated: Bool = true) { if zoomScale != minimumZoomScale { setZoomScale(minimumZoomScale, animated: animated) } @@ -78,7 +78,7 @@ extension RIGAutoCenteringScrollView { private extension RIGAutoCenteringScrollView { - func updateZoomScale(preserveScale preserveScale: Bool) { + func updateZoomScale(preserveScale: Bool) { guard let image = zoomImage else { contentSize = frame.size minimumZoomScale = 1 @@ -113,7 +113,7 @@ private extension RIGAutoCenteringScrollView { // After much fiddling, using insets to correct zoom behavior was found at: http://petersteinberger.com/blog/2013/how-to-center-uiscrollview/ func centerContent() { - guard !CGSizeEqualToSize(contentSize, CGSize()) else { + guard !contentSize.equalTo(CGSize()) else { return } let adjustedSize = UIEdgeInsetsInsetRect(bounds, baseInsets).size @@ -141,11 +141,11 @@ private extension RIGAutoCenteringScrollView { extension RIGAutoCenteringScrollView: UIScrollViewDelegate { - func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? { + func viewForZooming(in scrollView: UIScrollView) -> UIView? { return allowZoom ? contentView : nil } - func scrollViewDidZoom(scrollView: UIScrollView) { + func scrollViewDidZoom(_ scrollView: UIScrollView) { centerContent() } diff --git a/RIGImageGallery/RIGImageGalleryViewController.swift b/RIGImageGallery/RIGImageGalleryViewController.swift index 286c4f7..0259715 100644 --- a/RIGImageGallery/RIGImageGalleryViewController.swift +++ b/RIGImageGallery/RIGImageGalleryViewController.swift @@ -8,72 +8,72 @@ import UIKit -public class RIGImageGalleryViewController: UIPageViewController { +open class RIGImageGalleryViewController: UIPageViewController { - public typealias GalleryPositionUpdateHandler = (gallery: RIGImageGalleryViewController, position: Int, total: Int) -> () - public typealias ActionButtonPressedHandler = (gallery: RIGImageGalleryViewController, item: RIGImageGalleryItem) -> () - public typealias GalleryEventHandler = RIGImageGalleryViewController -> () - public typealias IndexUpdateHandler = Int -> () + public typealias GalleryPositionUpdateHandler = (_ gallery: RIGImageGalleryViewController, _ position: Int, _ total: Int) -> () + public typealias ActionButtonPressedHandler = (_ gallery: RIGImageGalleryViewController, _ item: RIGImageGalleryItem) -> () + public typealias GalleryEventHandler = (RIGImageGalleryViewController) -> () + public typealias IndexUpdateHandler = (Int) -> () /// An optional closure to execute if the action button is tapped - public var actionButtonHandler: ActionButtonPressedHandler? + open var actionButtonHandler: ActionButtonPressedHandler? /// An optional closure to allow cutom trait collection change handling - public var traitCollectionChangeHandler: GalleryEventHandler? { + open var traitCollectionChangeHandler: GalleryEventHandler? { didSet { traitCollectionChangeHandler?(self) } } /// An optional closure to execute when the active index is updated - public var indexUpdateHandler: IndexUpdateHandler? + open var indexUpdateHandler: IndexUpdateHandler? /// An optional closure to handle dismissing the gallery, if this is nil the view will call `dismissViewControllerAnimated(true, completion: nil)`, if this is non-nil, the view controller will not dismiss itself - public var dismissHandler: GalleryEventHandler? + open var dismissHandler: GalleryEventHandler? /// An optional closure to handle updating the count text - public var countUpdateHandler: GalleryPositionUpdateHandler? { + open var countUpdateHandler: GalleryPositionUpdateHandler? { didSet { updateCountText() } } /// The array of images to display. The view controller will automatically handle updates - public var images: [RIGImageGalleryItem] = [] { + open var images: [RIGImageGalleryItem] = [] { didSet { handleImagesUpdate(oldValue: oldValue) } } /// The bar button item to use for the left side of the screen, `didSet` adds the correct target and action to ensure that `dismissHandler` is called when the button is pressed - public var doneButton: UIBarButtonItem? = UIBarButtonItem(barButtonSystemItem: .Done, target: nil, action: nil) { + open var doneButton: UIBarButtonItem? = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: nil) { didSet { configureDoneButton() } } /// The bar button item to use for the right side of the screen, `didSet` adds the correct target and action to ensure that `actionButtonHandler` is called - public var actionButton: UIBarButtonItem? { + open var actionButton: UIBarButtonItem? { didSet { configureActionButton() } } /// The index of the image currently bieng displayed - public private(set) var currentImage: Int = 0 { + open fileprivate(set) var currentImage: Int = 0 { didSet { indexUpdateHandler?(currentImage) updateCountText() } } - private var navigationBarsHidden = false - private var zoomRecognizer = UITapGestureRecognizer() - private var toggleBarRecognizer = UITapGestureRecognizer() - private var currentImageViewController: RIGSingleImageViewController? { + fileprivate var navigationBarsHidden = false + fileprivate var zoomRecognizer = UITapGestureRecognizer() + fileprivate var toggleBarRecognizer = UITapGestureRecognizer() + fileprivate var currentImageViewController: RIGSingleImageViewController? { return viewControllers?.first as? RIGSingleImageViewController } - private var showDoneButton = true + fileprivate var showDoneButton = true /** Changes the current image bieng displayed @@ -81,29 +81,29 @@ public class RIGImageGalleryViewController: UIPageViewController { - parameter currentImage: The index of the image in `images` to display - parameter animated: A flag that determines if this should be an animated or non-animated transition */ - public func setCurrentImage(currentImage: Int, animated: Bool) { + open func setCurrentImage(_ currentImage: Int, animated: Bool) { guard currentImage >= 0 && currentImage < images.count else { self.currentImage = 0 - setViewControllers([UIViewController()], direction: .Forward, animated: animated, completion: nil) + setViewControllers([UIViewController()], direction: .forward, animated: animated, completion: nil) return } let newView = RIGSingleImageViewController(viewerItem: images[currentImage]) let direction: UIPageViewControllerNavigationDirection if self.currentImage < currentImage { - direction = .Forward + direction = .forward } else { - direction = .Reverse + direction = .reverse } self.currentImage = currentImage setViewControllers([newView], direction: direction, animated: animated, completion: nil) } /// The label used to display the current position in the array - public let countLabel: UILabel = { + open let countLabel: UILabel = { let counter = UILabel() - counter.textColor = .whiteColor() - counter.font = UIFont.preferredFontForTextStyle(UIFontTextStyleSubheadline) + counter.textColor = .white + counter.font = UIFont.preferredFont(forTextStyle: UIFontTextStyle.subheadline) return counter }() @@ -120,12 +120,12 @@ public class RIGImageGalleryViewController: UIPageViewController { - parameter images: The images to use in the gallery */ public convenience init(images: [RIGImageGalleryItem]) { - self.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: [UIPageViewControllerOptionInterPageSpacingKey: 20]) + self.init(transitionStyle: .scroll, navigationOrientation: .horizontal, options: [UIPageViewControllerOptionInterPageSpacingKey: 20]) self.images = images } - public override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) { + public override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : Any]?) { super.init(transitionStyle: style, navigationOrientation: navigationOrientation, options: options) dataSource = self delegate = self @@ -139,7 +139,7 @@ public class RIGImageGalleryViewController: UIPageViewController { fatalError("init(coder:) has not been implemented") } - public override func viewDidLoad() { + open override func viewDidLoad() { super.viewDidLoad() configureDoneButton() zoomRecognizer.addTarget(self, action: #selector(toggleZoom(_:))) @@ -149,35 +149,35 @@ public class RIGImageGalleryViewController: UIPageViewController { toggleBarRecognizer.delegate = self view.addGestureRecognizer(zoomRecognizer) view.addGestureRecognizer(toggleBarRecognizer) - view.backgroundColor = UIColor.blackColor() + view.backgroundColor = UIColor.black countLabel.sizeToFit() toolbarItems = [ - UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil), + UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil), UIBarButtonItem(customView: countLabel), - UIBarButtonItem(barButtonSystemItem: .FlexibleSpace, target: nil, action: nil), + UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: nil, action: nil), ] } - public override func viewWillAppear(animated: Bool) { + open override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) updateBarStatus(animated: false) if currentImage < images.count { let photoPage = RIGSingleImageViewController(viewerItem: images[currentImage]) - setViewControllers([photoPage], direction: .Forward, animated: false, completion: nil) + setViewControllers([photoPage], direction: .forward, animated: false, completion: nil) } } - public override func prefersStatusBarHidden() -> Bool { + open override var prefersStatusBarHidden : Bool { return navigationBarsHidden } - public override func viewWillLayoutSubviews() { + open override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() currentImageViewController?.scrollView.baseInsets = scrollViewInset } - public override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) { + open override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) traitCollectionChangeHandler?(self) } @@ -186,14 +186,14 @@ public class RIGImageGalleryViewController: UIPageViewController { extension RIGImageGalleryViewController: UIGestureRecognizerDelegate { - public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailByGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool { if gestureRecognizer == zoomRecognizer { return otherGestureRecognizer == toggleBarRecognizer } return false } - public func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOfGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool { + public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool { if gestureRecognizer == toggleBarRecognizer { return otherGestureRecognizer == zoomRecognizer } @@ -206,27 +206,27 @@ extension RIGImageGalleryViewController: UIGestureRecognizerDelegate { extension RIGImageGalleryViewController { - func toggleBarVisiblity(recognizer: UITapGestureRecognizer) { + func toggleBarVisiblity(_ recognizer: UITapGestureRecognizer) { navigationBarsHidden = !navigationBarsHidden updateBarStatus(animated: true) } - func toggleZoom(recognizer: UITapGestureRecognizer) { + func toggleZoom(_ recognizer: UITapGestureRecognizer) { currentImageViewController?.scrollView.toggleZoom() } - func dismissPhotoView(sender: UIBarButtonItem) { + func dismissPhotoView(_ sender: UIBarButtonItem) { if dismissHandler != nil { dismissHandler?(self) } else { - dismissViewControllerAnimated(true, completion: nil) + dismiss(animated: true, completion: nil) } } - func performAction(sender: UIBarButtonItem) { + func performAction(_ sender: UIBarButtonItem) { if let item = currentImageViewController?.viewerItem { - actionButtonHandler?(gallery: self, item: item) + actionButtonHandler?(self, item) } } @@ -234,22 +234,19 @@ extension RIGImageGalleryViewController { extension RIGImageGalleryViewController: UIPageViewControllerDataSource { - public func pageViewController(pageViewController: UIPageViewController, viewControllerAfterViewController viewController: UIViewController) -> UIViewController? { - - guard let index = indexOf(viewController: viewController)?.successor() - where index < images.count else { + public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { + guard let index = indexOf(viewController: viewController), index < images.count - 1 else { return nil } - let zoomView = RIGSingleImageViewController(viewerItem: images[index]) + let zoomView = RIGSingleImageViewController(viewerItem: images[index + 1]) return zoomView } - public func pageViewController(pageViewController: UIPageViewController, viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? { - guard let index = indexOf(viewController: viewController)?.predecessor() - where index >= 0 else { - return nil + public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { + guard let index = indexOf(viewController: viewController), index > 0 else { + return nil } - let zoomView = RIGSingleImageViewController(viewerItem: images[index]) + let zoomView = RIGSingleImageViewController(viewerItem: images[index - 1]) return zoomView } @@ -257,7 +254,7 @@ extension RIGImageGalleryViewController: UIPageViewControllerDataSource { extension RIGImageGalleryViewController: UIPageViewControllerDelegate { - public func pageViewController(pageViewController: UIPageViewController, willTransitionToViewControllers pendingViewControllers: [UIViewController]) { + public func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { for viewControl in pendingViewControllers { if let imageControl = viewControl as? RIGSingleImageViewController { imageControl.scrollView.baseInsets = scrollViewInset @@ -265,7 +262,7 @@ extension RIGImageGalleryViewController: UIPageViewControllerDelegate { } } - public func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { + public func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { if let index = viewControllers?.first.flatMap({ indexOf(viewController: $0) }) { currentImage = index } @@ -276,11 +273,11 @@ extension RIGImageGalleryViewController: UIPageViewControllerDelegate { private extension RIGImageGalleryViewController { - func indexOf(viewController viewController: UIViewController, imagesArray: [RIGImageGalleryItem]? = nil) -> Int? { + func indexOf(viewController: UIViewController, imagesArray: [RIGImageGalleryItem]? = nil) -> Int? { guard let item = (viewController as? RIGSingleImageViewController)?.viewerItem else { return nil } - return (imagesArray ?? images).indexOf(item) + return (imagesArray ?? images).index(of: item) } func configureDoneButton() { @@ -295,19 +292,19 @@ private extension RIGImageGalleryViewController { navigationItem.rightBarButtonItem = actionButton } - func updateBarStatus(animated animated: Bool) { + func updateBarStatus(animated: Bool) { navigationController?.setToolbarHidden(navigationBarsHidden, animated: animated) navigationController?.setNavigationBarHidden(navigationBarsHidden, animated: animated) setNeedsStatusBarAppearanceUpdate() - UIView.animateWithDuration(0.15) { + UIView.animate(withDuration: 0.15, animations: { self.currentImageViewController?.scrollView.baseInsets = self.scrollViewInset - } + }) } - func handleImagesUpdate(oldValue oldValue: [RIGImageGalleryItem]) { + func handleImagesUpdate(oldValue: [RIGImageGalleryItem]) { for viewController in childViewControllers { if let index = indexOf(viewController: viewController, imagesArray: oldValue), - childView = viewController as? RIGSingleImageViewController where index < images.count { + let childView = viewController as? RIGSingleImageViewController, index < images.count { childView.viewerItem = images[index] childView.scrollView.baseInsets = scrollViewInset } @@ -315,14 +312,14 @@ private extension RIGImageGalleryViewController { updateCountText() } - private var scrollViewInset: UIEdgeInsets { + var scrollViewInset: UIEdgeInsets { loadViewIfNeeded() return UIEdgeInsets(top: topLayoutGuide.length, left: 0, bottom: bottomLayoutGuide.length, right: 0) } - private func updateCountText() { + func updateCountText() { if countUpdateHandler != nil { - countUpdateHandler?(gallery: self, position: currentImage, total: images.count) + countUpdateHandler?(self, currentImage, images.count) } else { countLabel.text = nil diff --git a/RIGImageGallery/RIGSingleImageViewController.swift b/RIGImageGallery/RIGSingleImageViewController.swift index 6f3ad43..3d7cc8c 100644 --- a/RIGImageGallery/RIGSingleImageViewController.swift +++ b/RIGImageGallery/RIGSingleImageViewController.swift @@ -27,15 +27,15 @@ class RIGSingleImageViewController: UIViewController { override func loadView() { automaticallyAdjustsScrollViewInsets = false view = scrollView - view.backgroundColor = .blackColor() + view.backgroundColor = .black view.clipsToBounds = true } - override func viewWillAppear(animated: Bool) { + override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) } - override func viewDidDisappear(animated: Bool) { + override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true) } diff --git a/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift b/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift index 5028105..a5bcd64 100644 --- a/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift +++ b/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift @@ -58,19 +58,19 @@ class ImageGalleryViewControllerTests: XCTestCase { // code coverage of the no delegate dismiss function imageGallery.dismissPhotoView(UIBarButtonItem()) imageGallery.actionButton = UIBarButtonItem() - let actionFired = self.expectationWithDescription("action will fire on completion") + let actionFired = self.expectation(description: "action will fire on completion") imageGallery.actionButtonHandler = { _ in actionFired.fulfill() } - imageGallery.performSelector((imageGallery.navigationItem.rightBarButtonItem?.action)!, withObject: imageGallery) - waitForExpectationsWithTimeout(1.0, handler: nil) + imageGallery.perform((imageGallery.navigationItem.rightBarButtonItem?.action)!, with: imageGallery) + waitForExpectations(timeout: 1.0, handler: nil) imageGallery.doneButton = UIBarButtonItem() - let dismissFired = expectationWithDescription("dismiss handler will fire on completion") + let dismissFired = expectation(description: "dismiss handler will fire on completion") imageGallery.dismissHandler = { _ in dismissFired.fulfill() } - imageGallery.performSelector((imageGallery.navigationItem.leftBarButtonItem?.action)!, withObject: imageGallery) - waitForExpectationsWithTimeout(1.0, handler: nil) + imageGallery.perform((imageGallery.navigationItem.leftBarButtonItem?.action)!, with: imageGallery) + waitForExpectations(timeout: 1.0, handler: nil) } func testStatusBarHidden() { @@ -84,21 +84,21 @@ class ImageGalleryViewControllerTests: XCTestCase { // swiftlint:disable:next force_cast let firstView = imageGallery.viewControllers!.first as! RIGSingleImageViewController XCTAssertEqual(firstView.viewerItem, imageGallery.images.first, "The first view should have the first image in the gallery") - XCTAssertNil(imageGallery.pageViewController(imageGallery, viewControllerBeforeViewController: firstView), "The view before the first view should be nil") + XCTAssertNil(imageGallery.pageViewController(imageGallery, viewControllerBefore: firstView), "The view before the first view should be nil") // swiftlint:disable:next force_cast - let secondView = imageGallery.pageViewController(imageGallery, viewControllerAfterViewController: firstView) as! RIGSingleImageViewController + let secondView = imageGallery.pageViewController(imageGallery, viewControllerAfter: firstView) as! RIGSingleImageViewController XCTAssertEqual(secondView.viewerItem, imageGallery.images[1], "The second view should have the second image in the gallery") // swiftlint:disable:next force_cast - XCTAssertEqual((imageGallery.pageViewController(imageGallery, viewControllerBeforeViewController: secondView) as! RIGSingleImageViewController).viewerItem, firstView.viewerItem, "the view before the second view should be the first view, which is testable by comparing viewer items") - let thirdView = imageGallery.pageViewController(imageGallery, viewControllerAfterViewController: secondView)! - let fourthView = imageGallery.pageViewController(imageGallery, viewControllerAfterViewController: thirdView)! - XCTAssertNil(imageGallery.pageViewController(imageGallery, viewControllerAfterViewController: fourthView), "The view after the end of the list should be nil") + XCTAssertEqual((imageGallery.pageViewController(imageGallery, viewControllerBefore: secondView) as! RIGSingleImageViewController).viewerItem, firstView.viewerItem, "the view before the second view should be the first view, which is testable by comparing viewer items") + let thirdView = imageGallery.pageViewController(imageGallery, viewControllerAfter: secondView)! + let fourthView = imageGallery.pageViewController(imageGallery, viewControllerAfter: thirdView)! + XCTAssertNil(imageGallery.pageViewController(imageGallery, viewControllerAfter: fourthView), "The view after the end of the list should be nil") } } private extension RIGImageGalleryViewController { - static func updateCount(gallery: RIGImageGalleryViewController, position: Int, total: Int) { - gallery.countLabel.text = "\(position.successor()) of \(total)" + static func updateCount(_ gallery: RIGImageGalleryViewController, position: Int, total: Int) { + gallery.countLabel.text = "\((position + 1)) of \(total)" } } diff --git a/RIGImageGalleryTests/TestingExtensions.swift b/RIGImageGalleryTests/TestingExtensions.swift index 65df76d..55e4e23 100644 --- a/RIGImageGalleryTests/TestingExtensions.swift +++ b/RIGImageGalleryTests/TestingExtensions.swift @@ -21,14 +21,14 @@ extension UIImage { return [UIImage.genericImage(.wide), UIImage.genericImage(.tall), UIImage.genericImage(.smallWide), UIImage.genericImage(.smallTall)] } - static func genericImage(size: CGSize) -> UIImage { + static func genericImage(_ size: CGSize) -> UIImage { UIGraphicsBeginImageContextWithOptions(size, true, 0) let fillPath = UIBezierPath(rect: CGRect(origin: CGPoint(), size: size)) fillPath.fill() let genericImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return genericImage + return genericImage! } } From 4b80b02f66b0720c6890025f8fe53b346bd05f43 Mon Sep 17 00:00:00 2001 From: nevillco Date: Thu, 10 Nov 2016 14:53:07 -0500 Subject: [PATCH 2/5] Update recommended build settings --- RIGImageGallery.xcodeproj/project.pbxproj | 15 ++++++++++----- .../xcschemes/RIGImageGallery.xcscheme | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/RIGImageGallery.xcodeproj/project.pbxproj b/RIGImageGallery.xcodeproj/project.pbxproj index 442526a..f55738b 100644 --- a/RIGImageGallery.xcodeproj/project.pbxproj +++ b/RIGImageGallery.xcodeproj/project.pbxproj @@ -280,7 +280,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = Raizlabs; TargetAttributes = { 72060F4F1D2FFA6C001281E0 = { @@ -474,8 +474,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -522,8 +524,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -543,6 +547,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -553,10 +558,10 @@ 72A828191C68F24500B25CEE /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/RIGImageGalleryDemo/Assets/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -569,10 +574,10 @@ 72A8281A1C68F24500B25CEE /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; FRAMEWORK_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "$(SRCROOT)/RIGImageGalleryDemo/Assets/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -587,7 +592,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -608,7 +613,7 @@ buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; diff --git a/RIGImageGallery.xcodeproj/xcshareddata/xcschemes/RIGImageGallery.xcscheme b/RIGImageGallery.xcodeproj/xcshareddata/xcschemes/RIGImageGallery.xcscheme index 01cb3ca..3f86bc1 100644 --- a/RIGImageGallery.xcodeproj/xcshareddata/xcschemes/RIGImageGallery.xcscheme +++ b/RIGImageGallery.xcodeproj/xcshareddata/xcschemes/RIGImageGallery.xcscheme @@ -1,6 +1,6 @@ Date: Thu, 10 Nov 2016 15:17:14 -0500 Subject: [PATCH 3/5] Run Swift 3 syntax update on test project --- RIGImageGallery.xcodeproj/project.pbxproj | 3 + .../RIGImageGalleryViewController.swift | 4 +- .../App Delegate/AppDelegate.swift | 14 +-- .../View Controller/ViewController.swift | 88 ++++++++++--------- 4 files changed, 57 insertions(+), 52 deletions(-) diff --git a/RIGImageGallery.xcodeproj/project.pbxproj b/RIGImageGallery.xcodeproj/project.pbxproj index f55738b..2aac05e 100644 --- a/RIGImageGallery.xcodeproj/project.pbxproj +++ b/RIGImageGallery.xcodeproj/project.pbxproj @@ -290,6 +290,7 @@ 72A828081C68F24500B25CEE = { CreatedOnToolsVersion = 7.2.1; DevelopmentTeam = 336S848KQ4; + LastSwiftMigration = 0810; }; 72BA26511C6B985900F1FE22 = { CreatedOnToolsVersion = 7.2.1; @@ -568,6 +569,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.raizlabs.RigImageGalleryDemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -584,6 +586,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.raizlabs.RigImageGalleryDemo; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/RIGImageGallery/RIGImageGalleryViewController.swift b/RIGImageGallery/RIGImageGalleryViewController.swift index 0259715..4f972ac 100644 --- a/RIGImageGallery/RIGImageGalleryViewController.swift +++ b/RIGImageGallery/RIGImageGalleryViewController.swift @@ -168,7 +168,7 @@ open class RIGImageGalleryViewController: UIPageViewController { } } - open override var prefersStatusBarHidden : Bool { + open override var prefersStatusBarHidden: Bool { return navigationBarsHidden } @@ -298,7 +298,7 @@ private extension RIGImageGalleryViewController { setNeedsStatusBarAppearanceUpdate() UIView.animate(withDuration: 0.15, animations: { self.currentImageViewController?.scrollView.baseInsets = self.scrollViewInset - }) + }) } func handleImagesUpdate(oldValue: [RIGImageGalleryItem]) { diff --git a/RIGImageGalleryDemo/App Delegate/AppDelegate.swift b/RIGImageGalleryDemo/App Delegate/AppDelegate.swift index 5ccfc64..2a46e0c 100644 --- a/RIGImageGalleryDemo/App Delegate/AppDelegate.swift +++ b/RIGImageGalleryDemo/App Delegate/AppDelegate.swift @@ -14,27 +14,27 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { - window = UIWindow(frame: UIScreen.mainScreen().bounds) + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { + window = UIWindow(frame: UIScreen.main.bounds) window?.rootViewController = UINavigationController.init(rootViewController: ViewController()) window?.makeKeyAndVisible() return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { } } diff --git a/RIGImageGalleryDemo/View Controller/ViewController.swift b/RIGImageGalleryDemo/View Controller/ViewController.swift index 4790c14..524cf61 100644 --- a/RIGImageGalleryDemo/View Controller/ViewController.swift +++ b/RIGImageGalleryDemo/View Controller/ViewController.swift @@ -11,51 +11,51 @@ import RIGImageGallery class ViewController: UIViewController { - private let imageSession = NSURLSession(configuration: .defaultSessionConfiguration()) + fileprivate let imageSession = URLSession(configuration: .default) override func loadView() { view = UIView() - view.backgroundColor = .whiteColor() + view.backgroundColor = .white navigationItem.title = NSLocalizedString("RIG Image Gallery", comment: "Main screen title") - let galleryButton = UIButton(type: .System) + let galleryButton = UIButton(type: .system) galleryButton.translatesAutoresizingMaskIntoConstraints = false - galleryButton.addTarget(self, action: #selector(ViewController.showGallery(_:)), forControlEvents: .TouchUpInside) - galleryButton.setTitle(NSLocalizedString("Show Gallery", comment: "Show gallery button title"), forState: .Normal) + galleryButton.addTarget(self, action: #selector(ViewController.showGallery(_:)), for: .touchUpInside) + galleryButton.setTitle(NSLocalizedString("Show Gallery", comment: "Show gallery button title"), for: UIControlState()) let stackView = UIStackView(arrangedSubviews: [galleryButton]) - stackView.alignment = .Center - stackView.axis = .Vertical - stackView.layoutMarginsRelativeArrangement = true + stackView.alignment = .center + stackView.axis = .vertical + stackView.isLayoutMarginsRelativeArrangement = true stackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) - stackView.distribution = .Fill + stackView.distribution = .fill stackView.spacing = 10 view.addSubview(stackView) stackView.translatesAutoresizingMaskIntoConstraints = false let constraints: [NSLayoutConstraint] = [ - stackView.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor), - stackView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor), - stackView.bottomAnchor.constraintLessThanOrEqualToAnchor(bottomLayoutGuide.topAnchor), - stackView.topAnchor.constraintEqualToAnchor(topLayoutGuide.bottomAnchor), + stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + stackView.bottomAnchor.constraint(lessThanOrEqualTo: bottomLayoutGuide.topAnchor), + stackView.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor), ] - NSLayoutConstraint.activateConstraints(constraints) + NSLayoutConstraint.activate(constraints) } } private extension ViewController { - @objc func showGallery(sender: UIButton) { + @objc func showGallery(_ sender: UIButton) { let photoViewController = loadImages() photoViewController.dismissHandler = dismissPhotoViewer photoViewController.actionButtonHandler = actionButtonHandler - photoViewController.actionButton = UIBarButtonItem(barButtonSystemItem: .Action, target: nil, action: nil) + photoViewController.actionButton = UIBarButtonItem(barButtonSystemItem: .action, target: nil, action: nil) photoViewController.traitCollectionChangeHandler = traitCollectionChangeHandler photoViewController.countUpdateHandler = updateCount let navigationController = navBarWrappedViewController(photoViewController) - presentViewController(navigationController, animated: true, completion: nil) + present(navigationController, animated: true, completion: nil) } } @@ -63,37 +63,37 @@ private extension ViewController { private extension ViewController { func dismissPhotoViewer(_ :RIGImageGalleryViewController) { - dismissViewControllerAnimated(true, completion: nil) + dismiss(animated: true, completion: nil) } func actionButtonHandler(_: RIGImageGalleryViewController, galleryItem: RIGImageGalleryItem) { } - func updateCount(gallery: RIGImageGalleryViewController, position: Int, total: Int) { - gallery.countLabel.text = "\(position.successor()) of \(total)" + func updateCount(_ gallery: RIGImageGalleryViewController, position: Int, total: Int) { + gallery.countLabel.text = "\(position + 1) of \(total)" } - func traitCollectionChangeHandler(photoView: RIGImageGalleryViewController) { - let isPhone = UITraitCollection(userInterfaceIdiom: .Phone) - let isCompact = UITraitCollection(verticalSizeClass: .Compact) - let allTraits = UITraitCollection(traitsFromCollections: [isPhone, isCompact]) - photoView.doneButton = photoView.traitCollection.containsTraitsInCollection(allTraits) ? nil : UIBarButtonItem(barButtonSystemItem: .Done, target: nil, action: nil) + func traitCollectionChangeHandler(_ photoView: RIGImageGalleryViewController) { + let isPhone = UITraitCollection(userInterfaceIdiom: .phone) + let isCompact = UITraitCollection(verticalSizeClass: .compact) + let allTraits = UITraitCollection(traitsFrom: [isPhone, isCompact]) + photoView.doneButton = photoView.traitCollection.containsTraits(in: allTraits) ? nil : UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: nil) } } private extension ViewController { - static let urls: [NSURL] = [ - NSURL(string: "https://placehold.it/1920x1080"), - NSURL(string: "https://placehold.it/1080x1920"), - NSURL(string: "https://placehold.it/350x150"), - NSURL(string: "https://placehold.it/150x350"), + static let urls: [URL] = [ + URL(string: "https://placehold.it/1920x1080"), + URL(string: "https://placehold.it/1080x1920"), + URL(string: "https://placehold.it/350x150"), + URL(string: "https://placehold.it/150x350"), ].flatMap { $0 } func loadImages() -> RIGImageGalleryViewController { - let urls = self.dynamicType.urls + let urls = type(of: self).urls let rigItems = urls.map { _ in RIGImageGalleryItem(placeholderImage: UIImage(named: "placeholder") ?? UIImage()) @@ -101,9 +101,9 @@ private extension ViewController { let rigController = RIGImageGalleryViewController(images: rigItems) - for (index, URL) in urls.enumerate() { + for (index, URL) in urls.enumerated() { let completion = rigController.handleImageLoadAtIndex(index) - let request = imageSession.dataTaskWithRequest(NSURLRequest(URL: URL), completionHandler: completion) + let request = imageSession.dataTask(with: URLRequest(url: URL), completionHandler: completion) request.resume() } @@ -111,25 +111,27 @@ private extension ViewController { return rigController } - func navBarWrappedViewController(viewController: UIViewController) -> UINavigationController { + func navBarWrappedViewController(_ viewController: UIViewController) -> UINavigationController { let navigationController = UINavigationController(rootViewController: viewController) - navigationController.navigationBar.barStyle = .BlackTranslucent - navigationController.navigationBar.tintColor = .whiteColor() - navigationController.toolbar.barStyle = .BlackTranslucent - navigationController.toolbar.tintColor = .whiteColor() + navigationController.navigationBar.barStyle = .blackTranslucent + navigationController.navigationBar.tintColor = .white + navigationController.toolbar.barStyle = .blackTranslucent + navigationController.toolbar.tintColor = .white return navigationController } } private extension RIGImageGalleryViewController { - func handleImageLoadAtIndex(index: Int) -> ((NSData?, NSURLResponse?, NSError?) -> ()) { - return { [weak self] (data: NSData?, response: NSURLResponse?, error: NSError?) in - guard let image = data.flatMap(UIImage.init) where error == nil else { - print(error) + func handleImageLoadAtIndex(_ index: Int) -> ((Data?, URLResponse?, Error?) -> ()) { + return { [weak self] (data: Data?, response: URLResponse?, error: Error?) in + guard let image = data.flatMap(UIImage.init), error == nil else { + if let error = error { + print(error) + } return } - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { + DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { self?.images[index].image = image } } From b4b6b7b3bfe769c81886470f93f5612764d1bee6 Mon Sep 17 00:00:00 2001 From: nevillco Date: Thu, 10 Nov 2016 15:34:12 -0500 Subject: [PATCH 4/5] Bump podspec version --- RIGImageGallery.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RIGImageGallery.podspec b/RIGImageGallery.podspec index 8b1d1a1..0bdbaad 100644 --- a/RIGImageGallery.podspec +++ b/RIGImageGallery.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "RIGImageGallery" - s.version = "0.1.0" + s.version = "0.2.0" s.summary = "An image gallery view controller designed to work with the Raizlabs Interface Guidelines for iOS." s.description = <<-DESC From b1976d7658f1d1c1c0ababd8d46cce5900689b5f Mon Sep 17 00:00:00 2001 From: nevillco Date: Thu, 10 Nov 2016 15:48:25 -0500 Subject: [PATCH 5/5] Fix tests --- RIGImageGalleryTests/ImageGalleryViewControllerTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift b/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift index a5bcd64..0fef2ee 100644 --- a/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift +++ b/RIGImageGalleryTests/ImageGalleryViewControllerTests.swift @@ -74,9 +74,9 @@ class ImageGalleryViewControllerTests: XCTestCase { } func testStatusBarHidden() { - XCTAssertFalse(imageGallery.prefersStatusBarHidden()) + XCTAssertFalse(imageGallery.prefersStatusBarHidden) imageGallery.toggleBarVisiblity(UITapGestureRecognizer()) - XCTAssertTrue(imageGallery.prefersStatusBarHidden()) + XCTAssertTrue(imageGallery.prefersStatusBarHidden) } func testPageViewController() {