From d6310d39eda95ea41dacef2482bbb9e30c18d0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Schneider?= Date: Sun, 8 Feb 2015 11:58:39 +0100 Subject: [PATCH 1/3] Add a custom Transition Manger. --- DesignerNewsApp.xcodeproj/project.pbxproj | 4 + DesignerNewsApp/CustomTransitionManager.swift | 87 +++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 DesignerNewsApp/CustomTransitionManager.swift diff --git a/DesignerNewsApp.xcodeproj/project.pbxproj b/DesignerNewsApp.xcodeproj/project.pbxproj index 462a0e7..e7f191d 100644 --- a/DesignerNewsApp.xcodeproj/project.pbxproj +++ b/DesignerNewsApp.xcodeproj/project.pbxproj @@ -43,6 +43,7 @@ 96AF96151A5EAA41003926E2 /* StoriesTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AF96141A5EAA41003926E2 /* StoriesTableViewController.swift */; }; 96AF96171A5EABC9003926E2 /* StoryTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96AF96161A5EABC9003926E2 /* StoryTableViewCell.swift */; }; B773D86F1A7BC101008E8A65 /* LocalStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B773D86E1A7BC101008E8A65 /* LocalStore.swift */; }; + B788C5801A8778500011A1A1 /* CustomTransitionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B788C57F1A8778500011A1A1 /* CustomTransitionManager.swift */; }; B78F90381A6EF75800883A5B /* DesignerNewsService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B78F90371A6EF75800883A5B /* DesignerNewsService.swift */; }; B78F903E1A6EFAAA00883A5B /* JSONParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = B78F903D1A6EFAAA00883A5B /* JSONParser.swift */; }; B78F90411A6EFBAF00883A5B /* Story.swift in Sources */ = {isa = PBXBuildFile; fileRef = B78F90401A6EFBAF00883A5B /* Story.swift */; }; @@ -227,6 +228,7 @@ 96AF96141A5EAA41003926E2 /* StoriesTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoriesTableViewController.swift; sourceTree = ""; }; 96AF96161A5EABC9003926E2 /* StoryTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StoryTableViewCell.swift; sourceTree = ""; }; B773D86E1A7BC101008E8A65 /* LocalStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalStore.swift; sourceTree = ""; }; + B788C57F1A8778500011A1A1 /* CustomTransitionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTransitionManager.swift; sourceTree = ""; }; B78F90371A6EF75800883A5B /* DesignerNewsService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DesignerNewsService.swift; sourceTree = ""; }; B78F903D1A6EFAAA00883A5B /* JSONParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONParser.swift; sourceTree = ""; }; B78F90401A6EFBAF00883A5B /* Story.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Story.swift; sourceTree = ""; }; @@ -435,6 +437,7 @@ children = ( 1A7D789F1A70F8FE0061D6F6 /* DragDropBehavior.swift */, 1A935E3B1A837C640059BCBC /* SoundPlayer+DesignerNewsApp.swift */, + B788C57F1A8778500011A1A1 /* CustomTransitionManager.swift */, ); name = Behaviours; sourceTree = ""; @@ -716,6 +719,7 @@ 1A9183091A75EE1900606F35 /* CoreTextView.swift in Sources */, 1A935E3C1A837C640059BCBC /* SoundPlayer+DesignerNewsApp.swift in Sources */, B7E4D3371A719855001DC9B6 /* CommentTableViewCell.swift in Sources */, + B788C5801A8778500011A1A1 /* CustomTransitionManager.swift in Sources */, 1A2331D21A78E1AF002F8D80 /* StoriesLoader.swift in Sources */, 967CFD061A5C10700044B4E3 /* LoginViewController.swift in Sources */, 9694F2051A5FF13900A6376A /* CommentsTableViewController.swift in Sources */, diff --git a/DesignerNewsApp/CustomTransitionManager.swift b/DesignerNewsApp/CustomTransitionManager.swift new file mode 100644 index 0000000..1ff14cf --- /dev/null +++ b/DesignerNewsApp/CustomTransitionManager.swift @@ -0,0 +1,87 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015 Meng To (meng@designcode.io) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit +import Spring + +public class CustomTransitionManager: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { + + var isPresenting = true + var duration = 0.3 + + public func animateTransition(transitionContext: UIViewControllerContextTransitioning) { + let container = transitionContext.containerView() + let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! + let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! + + if isPresenting { + toView.frame = container.bounds + toView.transform = CGAffineTransformMakeTranslation(0, container.frame.size.height) + container.addSubview(fromView) + container.addSubview(toView) + springEaseInOut(duration) { + fromView.transform = CGAffineTransformMakeScale(0.8, 0.8) + fromView.alpha = 0.5 + toView.transform = CGAffineTransformIdentity + } + } + else { + + // 1. Rotating will change the bounds + // 2. we have to properly reset toView + // to the actual container's bounds, at + // the same time take consideration of + // previous transformation when presenting + let transform = toView.transform + toView.transform = CGAffineTransformIdentity + toView.frame = container.bounds + toView.transform = transform + + container.addSubview(toView) + container.addSubview(fromView) + + springEaseInOut(duration) { + fromView.transform = CGAffineTransformMakeTranslation(0, fromView.frame.size.height) + toView.transform = CGAffineTransformIdentity + toView.alpha = 1 + } + } + + delay(duration, { + transitionContext.completeTransition(true) + }) + } + + public func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { + return duration + } + + public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + isPresenting = true + return self + } + + public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + isPresenting = false + return self + } +} From d1869d15cc47e5ac9a4240a1a1e45e56bac55b15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Schneider?= Date: Sun, 8 Feb 2015 12:01:40 +0100 Subject: [PATCH 2/3] Change Access Control. --- DesignerNewsApp/CustomTransitionManager.swift | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/DesignerNewsApp/CustomTransitionManager.swift b/DesignerNewsApp/CustomTransitionManager.swift index 1ff14cf..6076fb7 100644 --- a/DesignerNewsApp/CustomTransitionManager.swift +++ b/DesignerNewsApp/CustomTransitionManager.swift @@ -23,12 +23,12 @@ import UIKit import Spring -public class CustomTransitionManager: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { +class CustomTransitionManager: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { - var isPresenting = true - var duration = 0.3 + private var isPresenting = true + private let duration = 0.3 - public func animateTransition(transitionContext: UIViewControllerContextTransitioning) { + func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let container = transitionContext.containerView() let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! @@ -71,16 +71,16 @@ public class CustomTransitionManager: NSObject, UIViewControllerTransitioningDel }) } - public func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { + func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { return duration } - public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = true return self } - public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = false return self } From 68a1ec36eba8c290abd5d2e2cc3de571b6657c4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Schneider?= Date: Sun, 8 Feb 2015 12:07:20 +0100 Subject: [PATCH 3/3] Use IBOutlet to set the transitioning delegate. --- DesignerNewsApp/Base.lproj/Main.storyboard | 14 ++++++++++++-- DesignerNewsApp/CommentsTableViewController.swift | 3 --- DesignerNewsApp/CustomTransitionManager.swift | 6 ++++++ DesignerNewsApp/StoriesTableViewController.swift | 5 +---- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/DesignerNewsApp/Base.lproj/Main.storyboard b/DesignerNewsApp/Base.lproj/Main.storyboard index d0f3078..52e50f8 100644 --- a/DesignerNewsApp/Base.lproj/Main.storyboard +++ b/DesignerNewsApp/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -565,6 +565,11 @@ + + + + + @@ -1270,6 +1275,11 @@ + + + + + diff --git a/DesignerNewsApp/CommentsTableViewController.swift b/DesignerNewsApp/CommentsTableViewController.swift index 8e12b9e..a38d292 100644 --- a/DesignerNewsApp/CommentsTableViewController.swift +++ b/DesignerNewsApp/CommentsTableViewController.swift @@ -12,7 +12,6 @@ import Spring class CommentsTableViewController: UITableViewController, StoryTableViewCellDelegate, CommentTableViewCellDelegate, ReplyViewControllerDelegate { var story: Story! - private let transitionManager = TransitionManager() override func viewDidLoad() { super.viewDidLoad() @@ -44,7 +43,6 @@ class CommentsTableViewController: UITableViewController, StoryTableViewCellDele } toView.delegate = self - toView.transitioningDelegate = self.transitionManager } else if segue.identifier == "WebSegue" { UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.Slide) @@ -57,7 +55,6 @@ class CommentsTableViewController: UITableViewController, StoryTableViewCellDele webViewController.shareTitle = story.title webViewController.url = NSURL(string: story.url) } - webViewController.transitioningDelegate = self.transitionManager } } diff --git a/DesignerNewsApp/CustomTransitionManager.swift b/DesignerNewsApp/CustomTransitionManager.swift index 6076fb7..2f55592 100644 --- a/DesignerNewsApp/CustomTransitionManager.swift +++ b/DesignerNewsApp/CustomTransitionManager.swift @@ -25,6 +25,12 @@ import Spring class CustomTransitionManager: NSObject, UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning { + @IBOutlet weak var viewController: UIViewController! { + didSet { + viewController.transitioningDelegate = self + } + } + private var isPresenting = true private let duration = 0.3 diff --git a/DesignerNewsApp/StoriesTableViewController.swift b/DesignerNewsApp/StoriesTableViewController.swift index b71c577..59d3e32 100644 --- a/DesignerNewsApp/StoriesTableViewController.swift +++ b/DesignerNewsApp/StoriesTableViewController.swift @@ -10,8 +10,7 @@ import UIKit import Spring class StoriesTableViewController: UITableViewController, StoryTableViewCellDelegate, LoginViewControllerDelegate, MenuViewControllerDelegate { - - private let transitionManager = TransitionManager() + private var stories = [Story]() private var firstTime = true private var storiesLoader = StoriesLoader() @@ -226,8 +225,6 @@ class StoriesTableViewController: UITableViewController, StoryTableViewCellDeleg webViewController.url = url } - webViewController.transitioningDelegate = self.transitionManager - UIApplication.sharedApplication().setStatusBarHidden(true, withAnimation: UIStatusBarAnimation.Slide) } else if segue.identifier == "LoginSegue" {