diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +4 diff --git a/README.md b/README.md index a0502c5..34f1430 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ -![](http://cl.ly/image/012R0D3R3x2g/download/springswift2.jpg) - -## Updated for Swift 2 -Requires Xcode 7 and Swift 2. +## Updated for Swift 4.2 +Requires Xcode 10 and Swift 4.2. ## Installation Drop in the Spring folder to your Xcode project (make sure to enable "Copy items if needed" and "Create groups"). @@ -9,7 +7,7 @@ Drop in the Spring folder to your Xcode project (make sure to enable "Copy items Or via CocoaPods: ``` use_frameworks! -pod 'Spring', :git => 'https://github.com/MengTo/Spring.git', :branch => 'swift2' +pod 'Spring', :git => 'https://github.com/MengTo/Spring.git' ``` ## Usage with Storyboard @@ -88,7 +86,7 @@ In Identity Inspector, connect the UIView to SpringView Class and set the animat ## Autostart -Allows you to animate without code. Don't need to use this is if you plan to start the animation in code. +Allows you to animate without code. Don't need to use this if you plan to start the animation in code. ## Autohide Saves you the hassle of adding a line "layer.alpha = 0" in viewDidLoad(). diff --git a/Spring.podspec b/Spring.podspec index a381019..a43ed30 100644 --- a/Spring.podspec +++ b/Spring.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'Spring' - s.version = '1.0.3' + s.version = '1.0.6' s.license = 'MIT' s.summary = 'A library to simplify iOS animations in Swift.' s.homepage = 'https://github.com/MengTo/Spring' @@ -8,6 +8,8 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/MengTo/Spring.git', :tag => s.version.to_s } s.requires_arc = true s.ios.deployment_target = '8.0' + s.tvos.deployment_target = '11.0' s.source_files = 'Spring/*.swift' - s.resources = ['Spring/*.xib', 'SpringApp/*.xcassets'] + s.ios.resources = ['Spring/*.xib', 'SpringApp/*.xcassets'] + s.tvos.resources = ['SpringApp/*.xcassets'] end diff --git a/Spring/AsyncButton.swift b/Spring/AsyncButton.swift index d92937c..6e03ac9 100644 --- a/Spring/AsyncButton.swift +++ b/Spring/AsyncButton.swift @@ -23,28 +23,29 @@ import UIKit public class AsyncButton: UIButton { - + private var imageURL = [UInt:NSURL]() private var placeholderImage = [UInt:UIImage]() - - - public func setImageURL(url: NSURL?, placeholderImage placeholder:UIImage?, forState state:UIControlState) { - + + + public func setImageURL(url: NSURL?, placeholderImage placeholder:UIImage?, forState state:UIControl.State) { + imageURL[state.rawValue] = url placeholderImage[state.rawValue] = placeholder - + if let urlString = url?.absoluteString { - ImageLoader.sharedLoader.imageForUrl(urlString) { [weak self] image, url in - + ImageLoader.sharedLoader.imageForUrl(urlString: urlString) { [weak self] image, url in + if let strongSelf = self { - dispatch_async(dispatch_get_main_queue(), { () -> Void in + + DispatchQueue.main.async(execute: { () -> Void in if strongSelf.imageURL[state.rawValue]?.absoluteString == url { - strongSelf.setImage(image, forState: state) + strongSelf.setImage(image, for: state) } }) } } } } - + } diff --git a/Spring/AsyncImageView.swift b/Spring/AsyncImageView.swift index f3ac178..aa2f7e8 100644 --- a/Spring/AsyncImageView.swift +++ b/Spring/AsyncImageView.swift @@ -30,9 +30,9 @@ public class AsyncImageView: UIImageView { didSet { self.image = placeholderImage if let urlString = url?.absoluteString { - ImageLoader.sharedLoader.imageForUrl(urlString) { [weak self] image, url in + ImageLoader.sharedLoader.imageForUrl(urlString: urlString) { [weak self] image, url in if let strongSelf = self { - dispatch_async(dispatch_get_main_queue(), { () -> Void in + DispatchQueue.main.async(execute: { () -> Void in if strongSelf.url?.absoluteString == url { strongSelf.image = image ?? strongSelf.placeholderImage } diff --git a/Spring/AutoTextView.swift b/Spring/AutoTextView.swift index 3abced4..1d0c7e6 100644 --- a/Spring/AutoTextView.swift +++ b/Spring/AutoTextView.swift @@ -9,16 +9,19 @@ import UIKit public class AutoTextView: UITextView { - override public func intrinsicContentSize() -> CGSize { - var size = self.sizeThatFits(CGSizeMake(self.frame.size.width, CGFloat.max)) - size.width = self.frame.size.width - if text.length == 0 { - size.height = 0 + + public override var intrinsicContentSize: CGSize { + get { + var size = self.sizeThatFits(CGSize(width: self.frame.size.width, height: CGFloat.greatestFiniteMagnitude)) + size.width = self.frame.size.width + if text.length == 0 { + size.height = 0 + } + + contentInset = UIEdgeInsets(top: -4, left: -4, bottom: -4, right: -4) + layoutIfNeeded() + + return size } - - contentInset = UIEdgeInsetsMake(-4, -4, -4, -4) - layoutIfNeeded() - - return size } -} \ No newline at end of file +} diff --git a/Spring/BlurView.swift b/Spring/BlurView.swift index d7871ee..8de1611 100644 --- a/Spring/BlurView.swift +++ b/Spring/BlurView.swift @@ -22,12 +22,12 @@ import UIKit -public func insertBlurView (view: UIView, style: UIBlurEffectStyle) -> UIVisualEffectView { - view.backgroundColor = UIColor.clearColor() +public func insertBlurView (view: UIView, style: UIBlurEffect.Style) -> UIVisualEffectView { + view.backgroundColor = UIColor.clear let blurEffect = UIBlurEffect(style: style) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = view.bounds - view.insertSubview(blurEffectView, atIndex: 0) + view.insertSubview(blurEffectView, at: 0) return blurEffectView -} \ No newline at end of file +} diff --git a/Spring/DesignableButton.swift b/Spring/DesignableButton.swift index 5b0a9c7..0612083 100644 --- a/Spring/DesignableButton.swift +++ b/Spring/DesignableButton.swift @@ -24,9 +24,9 @@ import UIKit @IBDesignable public class DesignableButton: SpringButton { - @IBInspectable public var borderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var borderColor: UIColor = UIColor.clear { didSet { - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor } } @@ -42,9 +42,9 @@ import UIKit } } - @IBInspectable public var shadowColor: UIColor = UIColor.clearColor() { + @IBInspectable public var shadowColor: UIColor = UIColor.clear { didSet { - layer.shadowColor = shadowColor.CGColor + layer.shadowColor = shadowColor.cgColor } } diff --git a/Spring/DesignableImageView.swift b/Spring/DesignableImageView.swift index 60c5a16..32a90a2 100644 --- a/Spring/DesignableImageView.swift +++ b/Spring/DesignableImageView.swift @@ -24,9 +24,9 @@ import UIKit @IBDesignable public class DesignableImageView: SpringImageView { - @IBInspectable public var borderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var borderColor: UIColor = UIColor.clear { didSet { - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor } } diff --git a/Spring/DesignableLabel.swift b/Spring/DesignableLabel.swift index 146174b..8d6994b 100644 --- a/Spring/DesignableLabel.swift +++ b/Spring/DesignableLabel.swift @@ -27,14 +27,14 @@ import UIKit @IBInspectable public var lineHeight: CGFloat = 1.5 { didSet { let font = UIFont(name: self.font.fontName, size: self.font.pointSize) - let text = self.text + guard let text = self.text else { return } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineHeight - let attributedString = NSMutableAttributedString(string: text!) - attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) - attributedString.addAttribute(NSFontAttributeName, value: font!, range: NSMakeRange(0, attributedString.length)) + let attributedString = NSMutableAttributedString(string: text) + attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.font, value: font!, range: NSMakeRange(0, attributedString.length)) self.attributedText = attributedString } diff --git a/Spring/DesignableTabBarController.swift b/Spring/DesignableTabBarController.swift index 16e9887..6c81095 100644 --- a/Spring/DesignableTabBarController.swift +++ b/Spring/DesignableTabBarController.swift @@ -24,31 +24,31 @@ import UIKit @IBDesignable class DesignableTabBarController: UITabBarController { - @IBInspectable var normalTint: UIColor = UIColor.clearColor() { + @IBInspectable var normalTint: UIColor = UIColor.clear { didSet { UITabBar.appearance().tintColor = normalTint - UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: normalTint], forState: UIControlState.Normal) + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalTint], for: UIControl.State()) } } - @IBInspectable var selectedTint: UIColor = UIColor.clearColor() { + @IBInspectable var selectedTint: UIColor = UIColor.clear { didSet { UITabBar.appearance().tintColor = selectedTint - UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: selectedTint], forState:UIControlState.Selected) + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: selectedTint], for:UIControl.State.selected) } } @IBInspectable var fontName: String = "" { didSet { - UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName: normalTint, NSFontAttributeName: UIFont(name: fontName, size: 11)!], forState: UIControlState.Normal) + UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: normalTint, NSAttributedString.Key.font: UIFont(name: fontName, size: 11)!], for: UIControl.State()) } } @IBInspectable var firstSelectedImage: UIImage? { didSet { if let image = firstSelectedImage { - var tabBarItems = self.tabBar.items as [UITabBarItem]! - tabBarItems[0].selectedImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) + var tabBarItems = self.tabBar.items as [UITabBarItem]? + tabBarItems?[0].selectedImage = image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) } } } @@ -56,8 +56,8 @@ import UIKit @IBInspectable var secondSelectedImage: UIImage? { didSet { if let image = secondSelectedImage { - var tabBarItems = self.tabBar.items as [UITabBarItem]! - tabBarItems[1].selectedImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) + var tabBarItems = self.tabBar.items as [UITabBarItem]? + tabBarItems?[1].selectedImage = image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) } } } @@ -65,8 +65,8 @@ import UIKit @IBInspectable var thirdSelectedImage: UIImage? { didSet { if let image = thirdSelectedImage { - var tabBarItems = self.tabBar.items as [UITabBarItem]! - tabBarItems[2].selectedImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) + var tabBarItems = self.tabBar.items as [UITabBarItem]? + tabBarItems?[2].selectedImage = image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) } } } @@ -74,8 +74,8 @@ import UIKit @IBInspectable var fourthSelectedImage: UIImage? { didSet { if let image = fourthSelectedImage { - var tabBarItems = self.tabBar.items as [UITabBarItem]! - tabBarItems[3].selectedImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) + var tabBarItems = self.tabBar.items as [UITabBarItem]? + tabBarItems?[3].selectedImage = image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) } } } @@ -83,18 +83,19 @@ import UIKit @IBInspectable var fifthSelectedImage: UIImage? { didSet { if let image = fifthSelectedImage { - var tabBarItems = self.tabBar.items as [UITabBarItem]! - tabBarItems[4].selectedImage = image.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate) + var tabBarItems = self.tabBar.items as [UITabBarItem]? + tabBarItems?[4].selectedImage = image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate) } } } override func viewDidLoad() { super.viewDidLoad() - - for item in self.tabBar.items as [UITabBarItem]! { - if let image = item.image { - item.image = image.imageWithColor(self.normalTint).imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal) + if let items = self.tabBar.items { + for item in items { + if let image = item.image { + item.image = image.imageWithColor(tintColor: self.normalTint).withRenderingMode(UIImage.RenderingMode.alwaysOriginal) + } } } } @@ -105,18 +106,18 @@ extension UIImage { UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale) let context = UIGraphicsGetCurrentContext() - CGContextTranslateCTM(context, 0, self.size.height) - CGContextScaleCTM(context, 1.0, -1.0); - CGContextSetBlendMode(context, CGBlendMode.Normal) + context!.translateBy(x: 0, y: self.size.height) + context!.scaleBy(x: 1.0, y: -1.0); + context!.setBlendMode(CGBlendMode.normal) - let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect - CGContextClipToMask(context, rect, self.CGImage) + let rect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height) + context?.clip(to: rect, mask: self.cgImage!) tintColor.setFill() - CGContextFillRect(context, rect) + context!.fill(rect) - let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage + let newImage = UIGraphicsGetImageFromCurrentImageContext()! as UIImage UIGraphicsEndImageContext() return newImage } -} \ No newline at end of file +} diff --git a/Spring/DesignableTextField.swift b/Spring/DesignableTextField.swift index 2a60b53..e334a8e 100644 --- a/Spring/DesignableTextField.swift +++ b/Spring/DesignableTextField.swift @@ -24,9 +24,10 @@ import UIKit @IBDesignable public class DesignableTextField: SpringTextField { - @IBInspectable public var placeholderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var placeholderColor: UIColor = UIColor.clear { didSet { - attributedPlaceholder = NSAttributedString(string: placeholder!, attributes: [NSForegroundColorAttributeName: placeholderColor]) + guard let placeholder = placeholder else { return } + attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor: placeholderColor]) layoutSubviews() } @@ -34,37 +35,37 @@ import UIKit @IBInspectable public var sidePadding: CGFloat = 0 { didSet { - let padding = UIView(frame: CGRectMake(0, 0, sidePadding, sidePadding)) + let padding = UIView(frame: CGRect(x: 0, y: 0, width: sidePadding, height: sidePadding)) - leftViewMode = UITextFieldViewMode.Always + leftViewMode = UITextField.ViewMode.always leftView = padding - rightViewMode = UITextFieldViewMode.Always + rightViewMode = UITextField.ViewMode.always rightView = padding } } @IBInspectable public var leftPadding: CGFloat = 0 { didSet { - let padding = UIView(frame: CGRectMake(0, 0, leftPadding, 0)) + let padding = UIView(frame: CGRect(x: 0, y: 0, width: leftPadding, height: 0)) - leftViewMode = UITextFieldViewMode.Always + leftViewMode = UITextField.ViewMode.always leftView = padding } } @IBInspectable public var rightPadding: CGFloat = 0 { didSet { - let padding = UIView(frame: CGRectMake(0, 0, rightPadding, 0)) + let padding = UIView(frame: CGRect(x: 0, y: 0, width: rightPadding, height: 0)) - rightViewMode = UITextFieldViewMode.Always + rightViewMode = UITextField.ViewMode.always rightView = padding } } - @IBInspectable public var borderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var borderColor: UIColor = UIColor.clear { didSet { - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor } } @@ -83,14 +84,14 @@ import UIKit @IBInspectable public var lineHeight: CGFloat = 1.5 { didSet { let font = UIFont(name: self.font!.fontName, size: self.font!.pointSize) - let text = self.text + guard let text = self.text else { return } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineHeight - let attributedString = NSMutableAttributedString(string: text!) - attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) - attributedString.addAttribute(NSFontAttributeName, value: font!, range: NSMakeRange(0, attributedString.length)) + let attributedString = NSMutableAttributedString(string: text) + attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.font, value: font!, range: NSRange(location: 0, length: attributedString.length)) self.attributedText = attributedString } diff --git a/Spring/DesignableTextView.swift b/Spring/DesignableTextView.swift index 27fe285..779298a 100644 --- a/Spring/DesignableTextView.swift +++ b/Spring/DesignableTextView.swift @@ -24,9 +24,9 @@ import UIKit @IBDesignable public class DesignableTextView: SpringTextView { - @IBInspectable public var borderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var borderColor: UIColor = UIColor.clear { didSet { - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor } } @@ -41,21 +41,21 @@ import UIKit layer.cornerRadius = cornerRadius } } - + @IBInspectable public var lineHeight: CGFloat = 1.5 { didSet { let font = UIFont(name: self.font!.fontName, size: self.font!.pointSize) - let text = self.text + guard let text = self.text else { return } let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = lineHeight - let attributedString = NSMutableAttributedString(string: text!) - attributedString.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedString.length)) - attributedString.addAttribute(NSFontAttributeName, value: font!, range: NSMakeRange(0, attributedString.length)) + let attributedString = NSMutableAttributedString(string: text) + attributedString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: attributedString.length)) + attributedString.addAttribute(NSAttributedString.Key.font, value: font!, range: NSRange(location: 0, length: attributedString.length)) self.attributedText = attributedString } } - + } diff --git a/Spring/DesignableView.swift b/Spring/DesignableView.swift index 62cca91..a82d23f 100644 --- a/Spring/DesignableView.swift +++ b/Spring/DesignableView.swift @@ -24,9 +24,9 @@ import UIKit @IBDesignable public class DesignableView: SpringView { - @IBInspectable public var borderColor: UIColor = UIColor.clearColor() { + @IBInspectable public var borderColor: UIColor = UIColor.clear { didSet { - layer.borderColor = borderColor.CGColor + layer.borderColor = borderColor.cgColor } } @@ -42,9 +42,9 @@ import UIKit } } - @IBInspectable public var shadowColor: UIColor = UIColor.clearColor() { + @IBInspectable public var shadowColor: UIColor = UIColor.clear { didSet { - layer.shadowColor = shadowColor.CGColor + layer.shadowColor = shadowColor.cgColor } } @@ -65,4 +65,4 @@ import UIKit layer.shadowOffset.height = shadowOffsetY } } -} \ No newline at end of file +} diff --git a/Spring/ImageLoader.swift b/Spring/ImageLoader.swift index eacd05e..bcb626d 100755 --- a/Spring/ImageLoader.swift +++ b/Spring/ImageLoader.swift @@ -26,45 +26,61 @@ import Foundation public class ImageLoader { - var cache = NSCache() + var cache = NSCache() public class var sharedLoader : ImageLoader { - struct Static { - static let instance : ImageLoader = ImageLoader() + struct Static { + static let instance : ImageLoader = ImageLoader() } return Static.instance } - public func imageForUrl(urlString: String, completionHandler:(image: UIImage?, url: String) -> ()) { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {()in - let data: NSData? = self.cache.objectForKey(urlString) as? NSData + public func imageForUrl(urlString: String, completionHandler: @escaping(_ image: UIImage?, _ url: String) -> ()) { + DispatchQueue.global(qos: DispatchQoS.QoSClass.background).async { + var data: NSData? + + if let dataCache = self.cache.object(forKey: urlString as NSString){ + data = (dataCache) as NSData + + }else{ + if (URL(string: urlString) != nil) + { + data = NSData(contentsOf: URL(string: urlString)!) + if data != nil { + self.cache.setObject(data!, forKey: urlString as NSString) + } + }else{ + return + } + } if let goodData = data { - let image = UIImage(data: goodData) - dispatch_async(dispatch_get_main_queue(), {() in - completionHandler(image: image, url: urlString) + let image = UIImage(data: goodData as Data) + DispatchQueue.main.async(execute: {() in + completionHandler(image, urlString) }) return } - let downloadTask: NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(NSURL(string: urlString)!, completionHandler: { (data, response, error) -> Void in + let downloadTask: URLSessionDataTask = URLSession.shared.dataTask(with: URL(string: urlString)!, completionHandler: { (data, response, error) -> Void in + if (error != nil) { - completionHandler(image: nil, url: urlString) + completionHandler(nil, urlString) return } if data != nil { let image = UIImage(data: data!) - self.cache.setObject(data!, forKey: urlString) - dispatch_async(dispatch_get_main_queue(), {() in - completionHandler(image: image, url: urlString) + self.cache.setObject(data! as NSData, forKey: urlString as NSString) + DispatchQueue.main.async(execute: {() in + completionHandler(image, urlString) }) return } }) downloadTask.resume() - }) + } } -} \ No newline at end of file +} diff --git a/Spring/KeyboardLayoutConstraint.swift b/Spring/KeyboardLayoutConstraint.swift index 1fad0b5..1b45a56 100644 --- a/Spring/KeyboardLayoutConstraint.swift +++ b/Spring/KeyboardLayoutConstraint.swift @@ -22,74 +22,77 @@ import UIKit +#if !os(tvOS) +@available(tvOS, unavailable) public class KeyboardLayoutConstraint: NSLayoutConstraint { - + private var offset : CGFloat = 0 private var keyboardVisibleHeight : CGFloat = 0 - + + @available(tvOS, unavailable) override public func awakeFromNib() { super.awakeFromNib() - + offset = constant - - NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShowNotification:", name: UIKeyboardWillShowNotification, object: nil) - NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHideNotification:", name: UIKeyboardWillHideNotification, object: nil) + + NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillShowNotification(_:)), name: UIWindow.keyboardWillShowNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(KeyboardLayoutConstraint.keyboardWillHideNotification(_:)), name: UIWindow.keyboardWillHideNotification, object: nil) } - + deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) + NotificationCenter.default.removeObserver(self) } - + // MARK: Notification - - func keyboardWillShowNotification(notification: NSNotification) { + + @objc func keyboardWillShowNotification(_ notification: Notification) { if let userInfo = notification.userInfo { - if let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue { - let frame = frameValue.CGRectValue() + if let frameValue = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue { + let frame = frameValue.cgRectValue keyboardVisibleHeight = frame.size.height } - + self.updateConstant() - switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) { - case let (.Some(duration), .Some(curve)): - - let options = UIViewAnimationOptions(rawValue: curve.unsignedLongValue) - - UIView.animateWithDuration( - NSTimeInterval(duration.doubleValue), + switch (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber) { + case let (.some(duration), .some(curve)): + + let options = UIView.AnimationOptions(rawValue: curve.uintValue) + + UIView.animate( + withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: { - UIApplication.sharedApplication().keyWindow?.layoutIfNeeded() + UIApplication.shared.keyWindow?.layoutIfNeeded() return }, completion: { finished in }) default: - + break } - + } - + } - - func keyboardWillHideNotification(notification: NSNotification) { + + @objc func keyboardWillHideNotification(_ notification: NSNotification) { keyboardVisibleHeight = 0 self.updateConstant() - + if let userInfo = notification.userInfo { - - switch (userInfo[UIKeyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIKeyboardAnimationCurveUserInfoKey] as? NSNumber) { - case let (.Some(duration), .Some(curve)): - - let options = UIViewAnimationOptions(rawValue: curve.unsignedLongValue) - - UIView.animateWithDuration( - NSTimeInterval(duration.doubleValue), + + switch (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber, userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber) { + case let (.some(duration), .some(curve)): + + let options = UIView.AnimationOptions(rawValue: curve.uintValue) + + UIView.animate( + withDuration: TimeInterval(duration.doubleValue), delay: 0, options: options, animations: { - UIApplication.sharedApplication().keyWindow?.layoutIfNeeded() + UIApplication.shared.keyWindow?.layoutIfNeeded() return }, completion: { finished in }) @@ -98,9 +101,10 @@ public class KeyboardLayoutConstraint: NSLayoutConstraint { } } } - + func updateConstant() { self.constant = offset + keyboardVisibleHeight } - + } +#endif diff --git a/Spring/LoadingView.swift b/Spring/LoadingView.swift index 8ef23be..5f62ce8 100644 --- a/Spring/LoadingView.swift +++ b/Spring/LoadingView.swift @@ -22,6 +22,8 @@ import UIKit +#if !os(tvOS) +@available(tvOS, unavailable) public class LoadingView: UIView { @IBOutlet public weak var indicatorView: SpringView! @@ -29,15 +31,16 @@ public class LoadingView: UIView { override public func awakeFromNib() { let animation = CABasicAnimation() animation.keyPath = "transform.rotation.z" - animation.fromValue = degreesToRadians(0) - animation.toValue = degreesToRadians(360) + animation.fromValue = degreesToRadians(degrees: 0) + animation.toValue = degreesToRadians(degrees: 360) animation.duration = 0.9 animation.repeatCount = HUGE - indicatorView.layer.addAnimation(animation, forKey: "") + indicatorView.layer.add(animation, forKey: "") } class func designCodeLoadingView() -> UIView { - return NSBundle(forClass: self).loadNibNamed("LoadingView", owner: self, options: nil)[0] as! UIView + + return Bundle(for: self).loadNibNamed("LoadingView", owner: self, options: nil)![0] as! UIView } } @@ -60,7 +63,7 @@ public extension UIView { self.addSubview(loadingXibView) loadingXibView.alpha = 0 - SpringAnimation.spring(0.7, animations: { + SpringAnimation.spring(duration: 0.7, animations: { loadingXibView.alpha = 1 }) } @@ -70,9 +73,9 @@ public extension UIView { if let loadingXibView = self.viewWithTag(LoadingViewConstants.Tag) { loadingXibView.alpha = 1 - SpringAnimation.springWithCompletion(0.7, animations: { + SpringAnimation.springWithCompletion(duration: 0.7, animations: { loadingXibView.alpha = 0 - loadingXibView.transform = CGAffineTransformMakeScale(3, 3) + loadingXibView.transform = CGAffineTransform(scaleX: 3, y: 3) }, completion: { (completed) -> Void in loadingXibView.removeFromSuperview() }) @@ -80,3 +83,4 @@ public extension UIView { } } +#endif diff --git a/Spring/Misc.swift b/Spring/Misc.swift index a2aa327..96024b8 100644 --- a/Spring/Misc.swift +++ b/Spring/Misc.swift @@ -23,18 +23,19 @@ import UIKit public extension String { - public var length: Int { return self.characters.count } - - public func toURL() -> NSURL? { + var length: Int { return self.count } + + func toURL() -> NSURL? { return NSURL(string: self) } } public func htmlToAttributedString(text: String) -> NSAttributedString! { - let htmlData = text.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) + guard let htmlData = text.data(using: String.Encoding.utf8, allowLossyConversion: false) else { + return NSAttributedString() } let htmlString: NSAttributedString? do { - htmlString = try NSAttributedString(data: htmlData!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) + htmlString = try NSAttributedString(data: htmlData, options: [NSAttributedString.DocumentReadingOptionKey.documentType:NSAttributedString.DocumentType.html], documentAttributes: nil) } catch _ { htmlString = nil } @@ -43,21 +44,16 @@ public func htmlToAttributedString(text: String) -> NSAttributedString! { } public func degreesToRadians(degrees: CGFloat) -> CGFloat { - return degrees * CGFloat(M_PI / 180) + return degrees * CGFloat(CGFloat.pi / 180) } -public func delay(delay:Double, closure:()->()) { - dispatch_after( - dispatch_time( - DISPATCH_TIME_NOW, - Int64(delay * Double(NSEC_PER_SEC)) - ), - dispatch_get_main_queue(), closure) +public func delay(delay:Double, closure: @escaping ()->()) { + DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure) } -public func imageFromURL(URL: String) -> UIImage { - let url = NSURL(string: URL) - let data = NSData(contentsOfURL: url!) +public func imageFromURL(_ Url: String) -> UIImage { + let url = Foundation.URL(string: Url) + let data = try? Data(contentsOf: url!) return UIImage(data: data!)! } @@ -70,14 +66,14 @@ public extension UIColor { var hex: String = hex if hex.hasPrefix("#") { - let index = hex.startIndex.advancedBy(1) - hex = hex.substringFromIndex(index) + let index = hex.index(hex.startIndex, offsetBy: 1) + hex = String(hex[index...]) } - - let scanner = NSScanner(string: hex) + + let scanner = Scanner(string: hex) var hexValue: CUnsignedLongLong = 0 - if scanner.scanHexLongLong(&hexValue) { - switch (hex.characters.count) { + if scanner.scanHexInt64(&hexValue) { + switch (hex.count) { case 3: red = CGFloat((hexValue & 0xF00) >> 8) / 15.0 green = CGFloat((hexValue & 0x0F0) >> 4) / 15.0 @@ -121,18 +117,18 @@ public func UIColorFromRGB(rgbValue: UInt) -> UIColor { } public func stringFromDate(date: NSDate, format: String) -> String { - let dateFormatter = NSDateFormatter() + let dateFormatter = DateFormatter() dateFormatter.dateFormat = format - return dateFormatter.stringFromDate(date) + return dateFormatter.string(from: date as Date) } -public func dateFromString(date: String, format: String) -> NSDate { - let dateFormatter = NSDateFormatter() +public func dateFromString(date: String, format: String) -> Date { + let dateFormatter = DateFormatter() dateFormatter.dateFormat = format - if let date = dateFormatter.dateFromString(date) { + if let date = dateFormatter.date(from: date) { return date } else { - return NSDate(timeIntervalSince1970: 0) + return Date(timeIntervalSince1970: 0) } } @@ -142,75 +138,126 @@ public func randomStringWithLength (len : Int) -> NSString { let randomString : NSMutableString = NSMutableString(capacity: len) - for (var i=0; i < len; i++){ + for _ in 0 ..< len { let length = UInt32 (letters.length) let rand = arc4random_uniform(length) - randomString.appendFormat("%C", letters.characterAtIndex(Int(rand))) + randomString.appendFormat("%C", letters.character(at: Int(rand))) } return randomString } -public func timeAgoSinceDate(date:NSDate, numericDates:Bool) -> String { - let calendar = NSCalendar.currentCalendar() - let unitFlags: NSCalendarUnit = [NSCalendarUnit.Minute, NSCalendarUnit.Hour, NSCalendarUnit.Day, NSCalendarUnit.WeekOfYear, NSCalendarUnit.Month, NSCalendarUnit.Year, NSCalendarUnit.Second] - let now = NSDate() - let earliest = now.earlierDate(date) - let latest = (earliest == now) ? date : now - let components: NSDateComponents = calendar.components(unitFlags, fromDate: earliest, toDate: latest, options: []) +public func timeAgoSinceDate(date: Date, numericDates: Bool) -> String { + let calendar = Calendar.current + let unitFlags = Set(arrayLiteral: Calendar.Component.minute, Calendar.Component.hour, Calendar.Component.day, Calendar.Component.weekOfYear, Calendar.Component.month, Calendar.Component.year, Calendar.Component.second) + let now = Date() + let dateComparison = now.compare(date) + var earliest: Date + var latest: Date + + switch dateComparison { + case .orderedAscending: + earliest = now + latest = date + default: + earliest = date + latest = now + } + + let components: DateComponents = calendar.dateComponents(unitFlags, from: earliest, to: latest) + + guard + let year = components.year, + let month = components.month, + let weekOfYear = components.weekOfYear, + let day = components.day, + let hour = components.hour, + let minute = components.minute, + let second = components.second + else { + fatalError() + } - if (components.year >= 2) { - return "\(components.year)y" - } else if (components.year >= 1){ + if (year >= 2) { + return "\(year)y" + } else if (year >= 1) { if (numericDates){ return "1y" } else { return "1y" } - } else if (components.month >= 2) { - return "\(components.month * 4)w" - } else if (components.month >= 1){ + } else if (month >= 2) { + return "\(month * 4)w" + } else if (month >= 1) { if (numericDates){ return "4w" } else { return "4w" } - } else if (components.weekOfYear >= 2) { - return "\(components.weekOfYear)w" - } else if (components.weekOfYear >= 1){ + } else if (weekOfYear >= 2) { + return "\(weekOfYear)w" + } else if (weekOfYear >= 1){ if (numericDates){ return "1w" } else { return "1w" } - } else if (components.day >= 2) { - return "\(components.day)d" - } else if (components.day >= 1){ + } else if (day >= 2) { + return "\(components.day ?? 2)d" + } else if (day >= 1){ if (numericDates){ return "1d" } else { return "1d" } - } else if (components.hour >= 2) { - return "\(components.hour)h" - } else if (components.hour >= 1){ + } else if (hour >= 2) { + return "\(hour)h" + } else if (hour >= 1){ if (numericDates){ return "1h" } else { return "1h" } - } else if (components.minute >= 2) { - return "\(components.minute)m" - } else if (components.minute >= 1){ + } else if (minute >= 2) { + return "\(minute)m" + } else if (minute >= 1){ if (numericDates){ return "1m" } else { return "1m" } - } else if (components.second >= 3) { - return "\(components.second)s" + } else if (second >= 3) { + return "\(second)s" } else { return "now" } -} \ No newline at end of file +} + +extension UIImageView { + func setImage(url: URL, contentMode mode: UIView.ContentMode = .scaleAspectFit, placeholderImage: UIImage?) { + contentMode = mode + URLSession.shared.dataTask(with: url) { (data, response, error) in + guard + let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, + let mimeType = response?.mimeType, mimeType.hasPrefix("image"), + let data = data, error == nil, + let image = UIImage(data: data) + else { + self.image = placeholderImage + return + } + DispatchQueue.main.async() { () -> Void in + self.image = image + + } + }.resume() + } + func setImage(urlString: String, contentMode mode: UIView.ContentMode = .scaleAspectFit, placeholderImage: UIImage?) { + guard let url = URL(string: urlString) else { + image = placeholderImage + return + } + setImage(url: url, contentMode: mode, placeholderImage: placeholderImage) + } +} diff --git a/Spring/SoundPlayer.swift b/Spring/SoundPlayer.swift index e29fc18..d2451d9 100644 --- a/Spring/SoundPlayer.swift +++ b/Spring/SoundPlayer.swift @@ -23,27 +23,27 @@ import UIKit import AudioToolbox -struct SoundPlayer { +public struct SoundPlayer { static var filename : String? static var enabled : Bool = true private struct Internal { - static var cache = [NSURL:SystemSoundID]() + static var cache = [URL:SystemSoundID]() } - static func playSound(soundFile: String) { + public static func playSound(soundFile: String) { if !enabled { return } - if let url = NSBundle.mainBundle().URLForResource(soundFile, withExtension: nil) { + if let url = Bundle.main.url(forResource: soundFile, withExtension: nil) { var soundID : SystemSoundID = Internal.cache[url] ?? 0 if soundID == 0 { - AudioServicesCreateSystemSoundID(url, &soundID) + AudioServicesCreateSystemSoundID(url as CFURL, &soundID) Internal.cache[url] = soundID } @@ -55,6 +55,6 @@ struct SoundPlayer { } static func play(file: String) { - self.playSound(file) + self.playSound(soundFile: file) } } diff --git a/Spring/Spring.swift b/Spring/Spring.swift index 06c7bf7..cf86e1a 100644 --- a/Spring/Spring.swift +++ b/Spring/Spring.swift @@ -40,46 +40,46 @@ import UIKit var opacity: CGFloat { get set } var animateFrom: Bool { get set } var curve: String { get set } - + // UIView var layer : CALayer { get } var transform : CGAffineTransform { get set } var alpha : CGFloat { get set } func animate() - func animateNext(completion: () -> ()) + func animateNext(completion: @escaping () -> ()) func animateTo() - func animateToNext(completion: () -> ()) + func animateToNext(completion: @escaping () -> ()) } public class Spring : NSObject { - + private unowned var view : Springable private var shouldAnimateAfterActive = false private var shouldAnimateInLayoutSubviews = true - + init(_ view: Springable) { self.view = view super.init() commonInit() } - + func commonInit() { - NSNotificationCenter.defaultCenter().addObserver(self, selector: "didBecomeActiveNotification:", name: UIApplicationDidBecomeActiveNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(Spring.didBecomeActiveNotification(_:)), name: UIApplication.didBecomeActiveNotification, object: nil) } - - func didBecomeActiveNotification(notification: NSNotification) { + + @objc func didBecomeActiveNotification(_ notification: NSNotification) { if shouldAnimateAfterActive { alpha = 0 animate() shouldAnimateAfterActive = false } } - + deinit { - NSNotificationCenter.defaultCenter().removeObserver(self, name: UIApplicationDidBecomeActiveNotification, object: nil) + NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil) } - + private var autostart: Bool { set { self.view.autostart = newValue } get { return self.view.autostart }} private var autohide: Bool { set { self.view.autohide = newValue } get { return self.view.autohide }} private var animation: String { set { self.view.animation = newValue } get { return self.view.animation }} @@ -97,12 +97,12 @@ public class Spring : NSObject { private var opacity: CGFloat { set { self.view.opacity = newValue } get { return self.view.opacity }} private var animateFrom: Bool { set { self.view.animateFrom = newValue } get { return self.view.animateFrom }} private var curve: String { set { self.view.curve = newValue } get { return self.view.curve }} - + // UIView private var layer : CALayer { return view.layer } private var transform : CGAffineTransform { get { return view.transform } set { view.transform = newValue }} private var alpha: CGFloat { get { return view.alpha } set { view.alpha = newValue } } - + public enum AnimationPreset: String { case SlideLeft = "slideLeft" case SlideRight = "slideRight" @@ -132,7 +132,7 @@ public class Spring : NSObject { case Wobble = "wobble" case Swing = "swing" } - + public enum AnimationCurve: String { case EaseIn = "easeIn" case EaseOut = "easeOut" @@ -164,7 +164,7 @@ public class Spring : NSObject { case EaseOutBack = "easeOutBack" case EaseInOutBack = "easeInOutBack" } - + func animatePreset() { alpha = 0.99 if let animation = AnimationPreset(rawValue: animation) { @@ -199,11 +199,11 @@ public class Spring : NSObject { animation.keyPath = "opacity" animation.fromValue = 1 animation.toValue = 0 - animation.timingFunction = getTimingFunction(curve) + animation.timingFunction = getTimingFunction(curve: curve) animation.duration = CFTimeInterval(duration) animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) animation.autoreverses = true - layer.addAnimation(animation, forKey: "fade") + layer.add(animation, forKey: "fade") case .FadeInLeft: opacity = 0 x = 300*force @@ -227,101 +227,102 @@ public class Spring : NSObject { scaleY = 2*force case .Fall: animateFrom = false - rotate = 15 * CGFloat(M_PI/180) + rotate = 15 * CGFloat(CGFloat.pi/180) y = 600*force case .Shake: let animation = CAKeyframeAnimation() animation.keyPath = "position.x" animation.values = [0, 30*force, -30*force, 30*force, 0] animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - animation.timingFunction = getTimingFunction(curve) + animation.timingFunction = getTimingFunction(curve: curve) animation.duration = CFTimeInterval(duration) - animation.additive = true + animation.isAdditive = true animation.repeatCount = repeatCount animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(animation, forKey: "shake") + layer.add(animation, forKey: "shake") case .Pop: let animation = CAKeyframeAnimation() animation.keyPath = "transform.scale" animation.values = [0, 0.2*force, -0.2*force, 0.2*force, 0] animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - animation.timingFunction = getTimingFunction(curve) + animation.timingFunction = getTimingFunction(curve: curve) animation.duration = CFTimeInterval(duration) - animation.additive = true + animation.isAdditive = true animation.repeatCount = repeatCount animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(animation, forKey: "pop") + layer.add(animation, forKey: "pop") case .FlipX: rotate = 0 scaleX = 1 scaleY = 1 var perspective = CATransform3DIdentity perspective.m34 = -1.0 / layer.frame.size.width/2 - + let animation = CABasicAnimation() animation.keyPath = "transform" - animation.fromValue = NSValue(CATransform3D: - CATransform3DMakeRotation(0, 0, 0, 0)) - animation.toValue = NSValue(CATransform3D: - CATransform3DConcat(perspective, CATransform3DMakeRotation(CGFloat(M_PI), 0, 1, 0))) + animation.fromValue = NSValue(caTransform3D: CATransform3DMakeRotation(0, 0, 0, 0)) + animation.toValue = NSValue(caTransform3D: + CATransform3DConcat(perspective, CATransform3DMakeRotation(CGFloat(CGFloat.pi), 0, 1, 0))) animation.duration = CFTimeInterval(duration) + animation.repeatCount = repeatCount animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - animation.timingFunction = getTimingFunction(curve) - layer.addAnimation(animation, forKey: "3d") + animation.timingFunction = getTimingFunction(curve: curve) + layer.add(animation, forKey: "3d") case .FlipY: var perspective = CATransform3DIdentity perspective.m34 = -1.0 / layer.frame.size.width/2 - + let animation = CABasicAnimation() animation.keyPath = "transform" - animation.fromValue = NSValue(CATransform3D: + animation.fromValue = NSValue(caTransform3D: CATransform3DMakeRotation(0, 0, 0, 0)) - animation.toValue = NSValue(CATransform3D: - CATransform3DConcat(perspective,CATransform3DMakeRotation(CGFloat(M_PI), 1, 0, 0))) + animation.toValue = NSValue(caTransform3D: + CATransform3DConcat(perspective,CATransform3DMakeRotation(CGFloat(CGFloat.pi), 1, 0, 0))) animation.duration = CFTimeInterval(duration) + animation.repeatCount = repeatCount animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - animation.timingFunction = getTimingFunction(curve) - layer.addAnimation(animation, forKey: "3d") + animation.timingFunction = getTimingFunction(curve: curve) + layer.add(animation, forKey: "3d") case .Morph: let morphX = CAKeyframeAnimation() morphX.keyPath = "transform.scale.x" morphX.values = [1, 1.3*force, 0.7, 1.3*force, 1] morphX.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - morphX.timingFunction = getTimingFunction(curve) + morphX.timingFunction = getTimingFunction(curve: curve) morphX.duration = CFTimeInterval(duration) morphX.repeatCount = repeatCount morphX.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(morphX, forKey: "morphX") - + layer.add(morphX, forKey: "morphX") + let morphY = CAKeyframeAnimation() morphY.keyPath = "transform.scale.y" morphY.values = [1, 0.7, 1.3*force, 0.7, 1] morphY.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - morphY.timingFunction = getTimingFunction(curve) + morphY.timingFunction = getTimingFunction(curve: curve) morphY.duration = CFTimeInterval(duration) morphY.repeatCount = repeatCount morphY.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(morphY, forKey: "morphY") + layer.add(morphY, forKey: "morphY") case .Squeeze: let morphX = CAKeyframeAnimation() morphX.keyPath = "transform.scale.x" morphX.values = [1, 1.5*force, 0.5, 1.5*force, 1] morphX.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - morphX.timingFunction = getTimingFunction(curve) + morphX.timingFunction = getTimingFunction(curve: curve) morphX.duration = CFTimeInterval(duration) morphX.repeatCount = repeatCount morphX.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(morphX, forKey: "morphX") - + layer.add(morphX, forKey: "morphX") + let morphY = CAKeyframeAnimation() morphY.keyPath = "transform.scale.y" morphY.values = [1, 0.5, 1, 0.5, 1] morphY.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - morphY.timingFunction = getTimingFunction(curve) + morphY.timingFunction = getTimingFunction(curve: curve) morphY.duration = CFTimeInterval(duration) morphY.repeatCount = repeatCount morphY.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(morphY, forKey: "morphY") + layer.add(morphY, forKey: "morphY") case .Flash: let animation = CABasicAnimation() animation.keyPath = "opacity" @@ -331,47 +332,48 @@ public class Spring : NSObject { animation.repeatCount = repeatCount * 2.0 animation.autoreverses = true animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(animation, forKey: "flash") + layer.add(animation, forKey: "flash") case .Wobble: let animation = CAKeyframeAnimation() animation.keyPath = "transform.rotation" animation.values = [0, 0.3*force, -0.3*force, 0.3*force, 0] animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] animation.duration = CFTimeInterval(duration) - animation.additive = true + animation.isAdditive = true animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(animation, forKey: "wobble") - + layer.add(animation, forKey: "wobble") + let x = CAKeyframeAnimation() x.keyPath = "position.x" x.values = [0, 30*force, -30*force, 30*force, 0] x.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] - x.timingFunction = getTimingFunction(curve) + x.timingFunction = getTimingFunction(curve: curve) x.duration = CFTimeInterval(duration) - x.additive = true + x.isAdditive = true x.repeatCount = repeatCount x.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(x, forKey: "x") + layer.add(x, forKey: "x") case .Swing: let animation = CAKeyframeAnimation() animation.keyPath = "transform.rotation" animation.values = [0, 0.3*force, -0.3*force, 0.3*force, 0] animation.keyTimes = [0, 0.2, 0.4, 0.6, 0.8, 1] animation.duration = CFTimeInterval(duration) - animation.additive = true + animation.isAdditive = true + animation.repeatCount = repeatCount animation.beginTime = CACurrentMediaTime() + CFTimeInterval(delay) - layer.addAnimation(animation, forKey: "swing") + layer.add(animation, forKey: "swing") } } } - + func getTimingFunction(curve: String) -> CAMediaTimingFunction { if let curve = AnimationCurve(rawValue: curve) { switch curve { - case .EaseIn: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) - case .EaseOut: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) - case .EaseInOut: return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) - case .Linear: return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + case .EaseIn: return CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn) + case .EaseOut: return CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) + case .EaseInOut: return CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + case .Linear: return CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) case .Spring: return CAMediaTimingFunction(controlPoints: 0.5, 1.1+Float(force/3), 1, 1) case .EaseInSine: return CAMediaTimingFunction(controlPoints: 0.47, 0, 0.745, 0.715) case .EaseOutSine: return CAMediaTimingFunction(controlPoints: 0.39, 0.575, 0.565, 1) @@ -399,42 +401,42 @@ public class Spring : NSObject { case .EaseInOutBack: return CAMediaTimingFunction(controlPoints: 0.68, -0.55, 0.265, 1.55) } } - return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault) + return CAMediaTimingFunction(name: CAMediaTimingFunctionName.default) } - - func getAnimationOptions(curve: String) -> UIViewAnimationOptions { + + func getAnimationOptions(curve: String) -> UIView.AnimationOptions { if let curve = AnimationCurve(rawValue: curve) { switch curve { - case .EaseIn: return UIViewAnimationOptions.CurveEaseIn - case .EaseOut: return UIViewAnimationOptions.CurveEaseOut - case .EaseInOut: return UIViewAnimationOptions.CurveEaseInOut + case .EaseIn: return UIView.AnimationOptions.curveEaseIn + case .EaseOut: return UIView.AnimationOptions.curveEaseOut + case .EaseInOut: return UIView.AnimationOptions() default: break } } - return UIViewAnimationOptions.CurveLinear + return UIView.AnimationOptions.curveLinear } - + public func animate() { animateFrom = true animatePreset() setView {} } - - public func animateNext(completion: () -> ()) { + + public func animateNext(completion: @escaping () -> ()) { animateFrom = true animatePreset() setView { completion() } } - + public func animateTo() { animateFrom = false animatePreset() setView {} } - - public func animateToNext(completion: () -> ()) { + + public func animateToNext(completion: @escaping () -> ()) { animateFrom = false animatePreset() setView { @@ -452,7 +454,7 @@ public class Spring : NSObject { if shouldAnimateInLayoutSubviews { shouldAnimateInLayoutSubviews = false if autostart { - if UIApplication.sharedApplication().applicationState != .Active { + if UIApplication.shared.applicationState != .active { shouldAnimateAfterActive = true return } @@ -461,57 +463,57 @@ public class Spring : NSObject { } } } - - func setView(completion: () -> ()) { + + func setView(completion: @escaping () -> ()) { if animateFrom { - let translate = CGAffineTransformMakeTranslation(self.x, self.y) - let scale = CGAffineTransformMakeScale(self.scaleX, self.scaleY) - let rotate = CGAffineTransformMakeRotation(self.rotate) - let translateAndScale = CGAffineTransformConcat(translate, scale) - self.transform = CGAffineTransformConcat(rotate, translateAndScale) - + let translate = CGAffineTransform(translationX: self.x, y: self.y) + let scale = CGAffineTransform(scaleX: self.scaleX, y: self.scaleY) + let rotate = CGAffineTransform(rotationAngle: self.rotate) + let translateAndScale = translate.concatenating(scale) + self.transform = rotate.concatenating(translateAndScale) + self.alpha = self.opacity } - - UIView.animateWithDuration( NSTimeInterval(duration), - delay: NSTimeInterval(delay), - usingSpringWithDamping: damping, - initialSpringVelocity: velocity, - options: [getAnimationOptions(curve), UIViewAnimationOptions.AllowUserInteraction], - animations: { [weak self] in - if let _self = self - { - if _self.animateFrom { - _self.transform = CGAffineTransformIdentity - _self.alpha = 1 - } - else { - let translate = CGAffineTransformMakeTranslation(_self.x, _self.y) - let scale = CGAffineTransformMakeScale(_self.scaleX, _self.scaleY) - let rotate = CGAffineTransformMakeRotation(_self.rotate) - let translateAndScale = CGAffineTransformConcat(translate, scale) - _self.transform = CGAffineTransformConcat(rotate, translateAndScale) - - _self.alpha = _self.opacity - } - - } - + + UIView.animate( withDuration: TimeInterval(duration), + delay: TimeInterval(delay), + usingSpringWithDamping: damping, + initialSpringVelocity: velocity, + options: [getAnimationOptions(curve: curve), UIView.AnimationOptions.allowUserInteraction], + animations: { [weak self] in + if let _self = self + { + if _self.animateFrom { + _self.transform = CGAffineTransform.identity + _self.alpha = 1 + } + else { + let translate = CGAffineTransform(translationX: _self.x, y: _self.y) + let scale = CGAffineTransform(scaleX: _self.scaleX, y: _self.scaleY) + let rotate = CGAffineTransform(rotationAngle: _self.rotate) + let translateAndScale = translate.concatenating(scale) + _self.transform = rotate.concatenating(translateAndScale) + + _self.alpha = _self.opacity + } + + } + }, completion: { [weak self] finished in completion() self?.resetAll() - }) + }) } - + func reset() { x = 0 y = 0 opacity = 1 } - + func resetAll() { x = 0 y = 0 @@ -526,5 +528,5 @@ public class Spring : NSObject { delay = 0 duration = 0.7 } - -} \ No newline at end of file + +} diff --git a/Spring/SpringAnimation.swift b/Spring/SpringAnimation.swift index 51038c3..998882b 100644 --- a/Spring/SpringAnimation.swift +++ b/Spring/SpringAnimation.swift @@ -23,9 +23,9 @@ import UIKit @objc public class SpringAnimation: NSObject { - public class func spring(duration: NSTimeInterval, animations: () -> Void) { - UIView.animateWithDuration( - duration, + public class func spring(duration: TimeInterval, animations: @escaping () -> Void) { + UIView.animate( + withDuration: duration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, @@ -37,11 +37,11 @@ import UIKit ) } - public class func springEaseIn(duration: NSTimeInterval, animations: (() -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springEaseIn(duration: TimeInterval, animations: (() -> Void)!) { + UIView.animate( + withDuration: duration, delay: 0, - options: .CurveEaseIn, + options: .curveEaseIn, animations: { animations() }, @@ -49,42 +49,42 @@ import UIKit ) } - public class func springEaseOut(duration: NSTimeInterval, animations: (() -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springEaseOut(duration: TimeInterval, animations: (() -> Void)!) { + UIView.animate( + withDuration: duration, delay: 0, - options: .CurveEaseOut, + options: .curveEaseOut, animations: { animations() }, completion: nil ) } - public class func springEaseInOut(duration: NSTimeInterval, animations: (() -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springEaseInOut(duration: TimeInterval, animations: (() -> Void)!) { + UIView.animate( + withDuration: duration, delay: 0, - options: .CurveEaseInOut, + options: UIView.AnimationOptions(), animations: { animations() }, completion: nil ) } - public class func springLinear(duration: NSTimeInterval, animations: (() -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springLinear(duration: TimeInterval, animations: (() -> Void)!) { + UIView.animate( + withDuration: duration, delay: 0, - options: .CurveLinear, + options: .curveLinear, animations: { animations() }, completion: nil ) } - public class func springWithDelay(duration: NSTimeInterval, delay: NSTimeInterval, animations: (() -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springWithDelay(duration: TimeInterval, delay: TimeInterval, animations: (() -> Void)!) { + UIView.animate( + withDuration: duration, delay: delay, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, @@ -95,9 +95,9 @@ import UIKit ) } - public class func springWithCompletion(duration: NSTimeInterval, animations: (() -> Void)!, completion: (Bool -> Void)!) { - UIView.animateWithDuration( - duration, + public class func springWithCompletion(duration: TimeInterval, animations: (() -> Void)!, completion: ((Bool) -> Void)!) { + UIView.animate( + withDuration: duration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.7, diff --git a/Spring/SpringButton.swift b/Spring/SpringButton.swift index 7851c14..92124ea 100644 --- a/Spring/SpringButton.swift +++ b/Spring/SpringButton.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringButton: UIButton, Springable { +open class SpringButton: UIButton, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringButton: UIButton, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,15 +57,15 @@ public class SpringButton: UIButton, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/SpringImageView.swift b/Spring/SpringImageView.swift index 1ba3904..85ad61f 100644 --- a/Spring/SpringImageView.swift +++ b/Spring/SpringImageView.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringImageView: UIImageView, Springable { +open class SpringImageView: UIImageView, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringImageView: UIImageView, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,16 +57,16 @@ public class SpringImageView: UIImageView, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/SpringLabel.swift b/Spring/SpringLabel.swift index 6a70b6c..c105a48 100644 --- a/Spring/SpringLabel.swift +++ b/Spring/SpringLabel.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringLabel: UILabel, Springable { +open class SpringLabel: UILabel, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringLabel: UILabel, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,16 +57,16 @@ public class SpringLabel: UILabel, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/SpringTextField.swift b/Spring/SpringTextField.swift index ea30597..966b6f7 100644 --- a/Spring/SpringTextField.swift +++ b/Spring/SpringTextField.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringTextField: UITextField, Springable { +open class SpringTextField: UITextField, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringTextField: UITextField, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,15 +57,15 @@ public class SpringTextField: UITextField, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/SpringTextView.swift b/Spring/SpringTextView.swift index 5b8f5f7..55d4e4a 100644 --- a/Spring/SpringTextView.swift +++ b/Spring/SpringTextView.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringTextView: UITextView, Springable { +open class SpringTextView: UITextView, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringTextView: UITextView, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,16 +57,16 @@ public class SpringTextView: UITextView, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/SpringView.swift b/Spring/SpringView.swift index 405e2af..a00c12a 100644 --- a/Spring/SpringView.swift +++ b/Spring/SpringView.swift @@ -22,7 +22,7 @@ import UIKit -public class SpringView: UIView, Springable { +open class SpringView: UIView, Springable { @IBInspectable public var autostart: Bool = false @IBInspectable public var autohide: Bool = false @IBInspectable public var animation: String = "" @@ -43,12 +43,12 @@ public class SpringView: UIView, Springable { lazy private var spring : Spring = Spring(self) - override public func awakeFromNib() { + override open func awakeFromNib() { super.awakeFromNib() self.spring.customAwakeFromNib() } - public override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() spring.customLayoutSubviews() } @@ -57,15 +57,15 @@ public class SpringView: UIView, Springable { self.spring.animate() } - public func animateNext(completion: () -> ()) { - self.spring.animateNext(completion) + public func animateNext(completion: @escaping () -> ()) { + self.spring.animateNext(completion: completion) } public func animateTo() { self.spring.animateTo() } - public func animateToNext(completion: () -> ()) { - self.spring.animateToNext(completion) + public func animateToNext(completion: @escaping () -> ()) { + self.spring.animateToNext(completion: completion) } -} \ No newline at end of file +} diff --git a/Spring/TransitionManager.swift b/Spring/TransitionManager.swift index 1aee7c5..388edac 100644 --- a/Spring/TransitionManager.swift +++ b/Spring/TransitionManager.swift @@ -27,20 +27,20 @@ public class TransitionManager: NSObject, UIViewControllerTransitioningDelegate, 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)! + public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + let container = transitionContext.containerView + let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from)! + let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)! if isPresenting { toView.frame = container.bounds - toView.transform = CGAffineTransformMakeTranslation(0, container.frame.size.height) + toView.transform = CGAffineTransform(translationX: 0, y: container.frame.size.height) container.addSubview(fromView) container.addSubview(toView) - SpringAnimation.springEaseInOut(duration) { - fromView.transform = CGAffineTransformMakeScale(0.8, 0.8) + SpringAnimation.springEaseInOut(duration: duration) { + fromView.transform = CGAffineTransform(scaleX: 0.8, y: 0.8) fromView.alpha = 0.5 - toView.transform = CGAffineTransformIdentity + toView.transform = CGAffineTransform.identity } } else { @@ -51,35 +51,35 @@ public class TransitionManager: NSObject, UIViewControllerTransitioningDelegate, // the same time take consideration of // previous transformation when presenting let transform = toView.transform - toView.transform = CGAffineTransformIdentity + toView.transform = CGAffineTransform.identity toView.frame = container.bounds toView.transform = transform container.addSubview(toView) container.addSubview(fromView) - SpringAnimation.springEaseInOut(duration) { - fromView.transform = CGAffineTransformMakeTranslation(0, fromView.frame.size.height) - toView.transform = CGAffineTransformIdentity + SpringAnimation.springEaseInOut(duration: duration) { + fromView.transform = CGAffineTransform(translationX: 0, y: fromView.frame.size.height) + toView.transform = CGAffineTransform.identity toView.alpha = 1 } } - delay(duration, closure: { + delay(delay: duration, closure: { transitionContext.completeTransition(true) }) } - public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { + public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } - public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + public func animationController(forPresentedController presented: UIViewController, presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = true return self } - public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = false return self } diff --git a/Spring/TransitionZoom.swift b/Spring/TransitionZoom.swift index 92c43de..6cf5301 100644 --- a/Spring/TransitionZoom.swift +++ b/Spring/TransitionZoom.swift @@ -27,22 +27,22 @@ public class TransitionZoom: NSObject, UIViewControllerTransitioningDelegate, UI var isPresenting = true var duration = 0.4 - public func animateTransition(transitionContext: UIViewControllerContextTransitioning) { - let container = transitionContext.containerView()! - let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! - let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! + public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + let container = transitionContext.containerView + let fromView = transitionContext.view(forKey: UITransitionContextViewKey.from)! + let toView = transitionContext.view(forKey: UITransitionContextViewKey.to)! if isPresenting { container.addSubview(fromView) container.addSubview(toView) toView.alpha = 0 - toView.transform = CGAffineTransformMakeScale(2, 2) + toView.transform = CGAffineTransform(scaleX: 2, y: 2) - SpringAnimation.springEaseInOut(duration) { - fromView.transform = CGAffineTransformMakeScale(0.5, 0.5) + SpringAnimation.springEaseInOut(duration: duration) { + fromView.transform = CGAffineTransform(scaleX: 0.5, y: 0.5) fromView.alpha = 0 - toView.transform = CGAffineTransformIdentity + toView.transform = CGAffineTransform.identity toView.alpha = 1 } } @@ -50,30 +50,30 @@ public class TransitionZoom: NSObject, UIViewControllerTransitioningDelegate, UI container.addSubview(toView) container.addSubview(fromView) - SpringAnimation.springEaseInOut(duration) { - fromView.transform = CGAffineTransformMakeScale(2, 2) + SpringAnimation.springEaseInOut(duration: duration) { + fromView.transform = CGAffineTransform(scaleX: 2, y: 2) fromView.alpha = 0 - toView.transform = CGAffineTransformMakeScale(1, 1) + toView.transform = CGAffineTransform(scaleX: 1, y: 1) toView.alpha = 1 } } - delay(duration, closure: { + delay(delay: duration, closure: { transitionContext.completeTransition(true) }) } - public func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { + public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } - public func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + public func animationController(forPresentedController presented: UIViewController, presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = true return self } - public func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { isPresenting = false return self } -} \ No newline at end of file +} diff --git a/Spring/UnwindSegue.swift b/Spring/UnwindSegue.swift index a9aae71..53a71cb 100644 --- a/Spring/UnwindSegue.swift +++ b/Spring/UnwindSegue.swift @@ -23,5 +23,5 @@ import UIKit public extension UIViewController { - @IBAction public func unwindToViewController (sender: UIStoryboardSegue){} -} \ No newline at end of file + @IBAction public func unwindToViewController (_ segue: UIStoryboardSegue){} +} diff --git a/SpringApp.xcodeproj/project.pbxproj b/SpringApp.xcodeproj/project.pbxproj index 8ac99e0..a0e8956 100644 --- a/SpringApp.xcodeproj/project.pbxproj +++ b/SpringApp.xcodeproj/project.pbxproj @@ -408,21 +408,25 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0700; - LastUpgradeCheck = 0700; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = "Meng To"; TargetAttributes = { 1A4FDA321A6E44780099D309 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 1020; }; 1A4FDA3C1A6E44780099D309 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 1020; TestTargetID = 9641173A1A5BE90A000E3A5A; }; 9641173A1A5BE90A000E3A5A = { CreatedOnToolsVersion = 6.2; + LastSwiftMigration = 1020; }; 9641174F1A5BE90A000E3A5A = { CreatedOnToolsVersion = 6.2; + LastSwiftMigration = 1020; TestTargetID = 9641173A1A5BE90A000E3A5A; }; }; @@ -432,6 +436,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, ); @@ -594,6 +599,7 @@ 1A4FDA4D1A6E44780099D309 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -610,6 +616,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -619,6 +626,7 @@ 1A4FDA4E1A6E44780099D309 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; CURRENT_PROJECT_VERSION = 1; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; @@ -631,6 +639,8 @@ PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -649,6 +659,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamztang.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpringApp.app/SpringApp"; }; name = Debug; @@ -661,6 +672,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "com.jamztang.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpringApp.app/SpringApp"; }; name = Release; @@ -673,13 +686,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -688,6 +709,7 @@ ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", @@ -705,6 +727,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_SWIFT3_OBJC_INFERENCE = Off; }; name = Debug; }; @@ -716,13 +739,21 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; 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_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -730,6 +761,7 @@ ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; @@ -739,6 +771,7 @@ IPHONEOS_DEPLOYMENT_TARGET = 8.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_SWIFT3_OBJC_INFERENCE = Off; VALIDATE_PRODUCT = YES; }; name = Release; @@ -752,6 +785,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; @@ -765,6 +799,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; @@ -781,6 +817,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpringApp.app/SpringApp"; }; name = Debug; @@ -793,6 +830,8 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "designcode.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 5.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SpringApp.app/SpringApp"; }; name = Release; diff --git a/SpringApp.xcodeproj/xcshareddata/xcschemes/Spring.xcscheme b/SpringApp.xcodeproj/xcshareddata/xcschemes/Spring.xcscheme index 8066cbf..ecfaae8 100644 --- a/SpringApp.xcodeproj/xcshareddata/xcschemes/Spring.xcscheme +++ b/SpringApp.xcodeproj/xcshareddata/xcschemes/Spring.xcscheme @@ -1,6 +1,6 @@ + shouldUseLaunchSchemeArgsEnv = "YES"> Bool { + func applicationDidFinishLaunching(_ application: UIApplication) { // Override point for customization after application launch. - return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/SpringApp/Base.lproj/LaunchScreen.xib b/SpringApp/Base.lproj/LaunchScreen.xib index 3ace0e1..a13447c 100644 --- a/SpringApp/Base.lproj/LaunchScreen.xib +++ b/SpringApp/Base.lproj/LaunchScreen.xib @@ -1,7 +1,9 @@ - + - + + + @@ -11,15 +13,13 @@ - - + - - + diff --git a/SpringApp/Base.lproj/Main.storyboard b/SpringApp/Base.lproj/Main.storyboard index f734ed9..6528bfc 100644 --- a/SpringApp/Base.lproj/Main.storyboard +++ b/SpringApp/Base.lproj/Main.storyboard @@ -1,8 +1,16 @@ - - + + - + + + + + + AvenirNext-DemiBold + AvenirNext-Regular + + @@ -13,15 +21,13 @@ - + - - - + @@ -35,32 +41,29 @@ - + @@ -130,67 +132,58 @@ - - - - + - - - + + - - - + + - - + - - + + - + @@ -210,7 +203,7 @@ - + @@ -256,40 +249,35 @@ - + - - - - + + - - + - + @@ -309,7 +297,7 @@ - + @@ -339,145 +327,130 @@ - + - - - - + + - - - + + - - - + + - - - + + - - - + + - - - + + - - + @@ -531,7 +504,7 @@ - + diff --git a/SpringApp/CodeViewController.swift b/SpringApp/CodeViewController.swift index 96e4895..9aa8327 100644 --- a/SpringApp/CodeViewController.swift +++ b/SpringApp/CodeViewController.swift @@ -20,7 +20,7 @@ class CodeViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - modalView.transform = CGAffineTransformMakeTranslation(-300, 0) + modalView.transform = CGAffineTransform(translationX: -300, y: 0) if data.animation != "" { codeText += "layer.animation = \"\(data.animation)\"\n" @@ -57,21 +57,23 @@ class CodeViewController: UIViewController { codeTextView.text = codeText } - @IBAction func closeButtonPressed(sender: AnyObject) { - UIApplication.sharedApplication().sendAction("maximizeView:", to: nil, from: self, forEvent: nil) + @IBAction func closeButtonPressed(_ sender: AnyObject) { + UIApplication.shared.sendAction(#selector(SpringViewController.maximizeView(_:)), to: nil, from: self, for: nil) modalView.animation = "slideRight" modalView.animateFrom = false - modalView.animateToNext({ - self.dismissViewControllerAnimated(false, completion: nil) + modalView.animateToNext(completion: { + self.dismiss(animated: false, completion: nil) }) } - override func viewDidAppear(animated: Bool) { + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) modalView.animate() - UIApplication.sharedApplication().sendAction("minimizeView:", to: nil, from: self, forEvent: nil) + UIApplication.shared.sendAction(#selector(SpringViewController.minimizeView(_:)), to: nil, from: self, for: nil) } } + + diff --git a/SpringApp/Images.xcassets/AppIcon.appiconset/Contents.json b/SpringApp/Images.xcassets/AppIcon.appiconset/Contents.json index 17d5afa..1acc2b0 100644 --- a/SpringApp/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/SpringApp/Images.xcassets/AppIcon.appiconset/Contents.json @@ -71,6 +71,12 @@ "idiom" : "ipad", "filename" : "appicon@152.png", "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "appicon@167.png", + "scale" : "2x" } ], "info" : { diff --git a/SpringApp/Images.xcassets/AppIcon.appiconset/appicon@167.png b/SpringApp/Images.xcassets/AppIcon.appiconset/appicon@167.png new file mode 100644 index 0000000..9ae2444 Binary files /dev/null and b/SpringApp/Images.xcassets/AppIcon.appiconset/appicon@167.png differ diff --git a/SpringApp/OptionsViewController.swift b/SpringApp/OptionsViewController.swift index 251a54a..be62011 100644 --- a/SpringApp/OptionsViewController.swift +++ b/SpringApp/OptionsViewController.swift @@ -10,13 +10,13 @@ import UIKit import Spring protocol OptionsViewControllerDelegate: class { - func dampingSliderChanged(sender: AnyObject) - func velocitySliderChanged(sender: AnyObject) - func scaleSliderChanged(sender: AnyObject) - func xSliderChanged(sender: AnyObject) - func ySliderChanged(sender: AnyObject) - func rotateSliderChanged(sender: AnyObject) - func resetButtonPressed(sender: AnyObject) + func dampingSliderChanged(_ sender: AnyObject) + func velocitySliderChanged(_ sender: AnyObject) + func scaleSliderChanged(_ sender: AnyObject) + func xSliderChanged(_ sender: AnyObject) + func ySliderChanged(_ sender: AnyObject) + func rotateSliderChanged(_ sender: AnyObject) + func resetButtonPressed(_ sender: AnyObject) } class OptionsViewController: UIViewController { @@ -50,7 +50,7 @@ class OptionsViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - modalView.transform = CGAffineTransformMakeTranslation(0, 300) + modalView.transform = CGAffineTransform(translationX: 0, y: 300) dampingSlider.setValue(Float(data.damping), animated: true) velocitySlider.setValue(Float(data.velocity), animated: true) @@ -67,64 +67,64 @@ class OptionsViewController: UIViewController { rotateLabel.text = getString("Rotate", value: data.rotate) } - @IBAction func dampingSliderChanged(sender: AnyObject) { - selectedDamping = sender.valueForKey("value") as! CGFloat + @IBAction func dampingSliderChanged(_ sender: AnyObject) { + selectedDamping = sender.value(forKey: "value") as! CGFloat delegate?.dampingSliderChanged(sender) dampingLabel.text = getString("Damping", value: selectedDamping) } - @IBAction func velocitySliderChanged(sender: AnyObject) { - selectedVelocity = sender.valueForKey("value") as! CGFloat + @IBAction func velocitySliderChanged(_ sender: AnyObject) { + selectedVelocity = sender.value(forKey: "value") as! CGFloat delegate?.velocitySliderChanged(sender) velocityLabel.text = getString("Velocity", value: selectedVelocity) } - @IBAction func scaleSliderChanged(sender: AnyObject) { - selectedScale = sender.valueForKey("value") as! CGFloat + @IBAction func scaleSliderChanged(_ sender: AnyObject) { + selectedScale = sender.value(forKey: "value") as! CGFloat delegate?.scaleSliderChanged(sender) scaleLabel.text = getString("Scale", value: selectedScale) } - @IBAction func xSliderChanged(sender: AnyObject) { - selectedX = sender.valueForKey("value") as! CGFloat + @IBAction func xSliderChanged(_ sender: AnyObject) { + selectedX = sender.value(forKey: "value") as! CGFloat delegate?.xSliderChanged(sender) xLabel.text = getString("X", value: selectedX) } - @IBAction func ySliderChanged(sender: AnyObject) { - selectedY = sender.valueForKey("value") as! CGFloat + @IBAction func ySliderChanged(_ sender: AnyObject) { + selectedY = sender.value(forKey: "value") as! CGFloat delegate?.ySliderChanged(sender) yLabel.text = getString("Y", value: selectedY) } - @IBAction func rotateSliderChanged(sender: AnyObject) { - selectedRotate = sender.valueForKey("value") as! CGFloat + @IBAction func rotateSliderChanged(_ sender: AnyObject) { + selectedRotate = sender.value(forKey: "value") as! CGFloat delegate?.rotateSliderChanged(sender) rotateLabel.text = getString("Rotate", value: selectedRotate) } - @IBAction func resetButtonPressed(sender: AnyObject) { + @IBAction func resetButtonPressed(_ sender: AnyObject) { delegate?.resetButtonPressed(sender) - dismissViewControllerAnimated(true, completion: nil) + dismiss(animated: true, completion: nil) - UIApplication.sharedApplication().sendAction("maximizeView:", to: nil, from: self, forEvent: nil) + UIApplication.shared.sendAction(#selector(SpringViewController.maximizeView(_:)), to: nil, from: self, for: nil) } - @IBAction func closeButtonPressed(sender: AnyObject) { - dismissViewControllerAnimated(true, completion: nil) + @IBAction func closeButtonPressed(_ sender: AnyObject) { + dismiss(animated: true, completion: nil) - UIApplication.sharedApplication().sendAction("maximizeView:", to: nil, from: self, forEvent: nil) + UIApplication.shared.sendAction(#selector(SpringViewController.maximizeView(_:)), to: nil, from: self, for: nil) } - override func viewDidAppear(animated: Bool) { + override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(true) - UIApplication.sharedApplication().sendAction("minimizeView:", to: nil, from: self, forEvent: nil) + UIApplication.shared.sendAction(#selector(SpringViewController.minimizeView(_:)), to: nil, from: self, for: nil) modalView.animate() } - func getString(name: String, value: CGFloat) -> String { + func getString(_ name: String, value: CGFloat) -> String { return String(format: "\(name): %.1f", Double(value)) } } diff --git a/SpringApp/SpringViewController.swift b/SpringApp/SpringViewController.swift index d621c14..6a4ea1b 100644 --- a/SpringApp/SpringViewController.swift +++ b/SpringApp/SpringViewController.swift @@ -34,49 +34,49 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView var selectedY: CGFloat = 0 var selectedRotate: CGFloat = 0 - @IBAction func forceSliderChanged(sender: AnyObject) { - selectedForce = sender.valueForKey("value") as! CGFloat + @IBAction func forceSliderChanged(_ sender: AnyObject) { + selectedForce = sender.value(forKey: "value") as! CGFloat animateView() forceLabel.text = String(format: "Force: %.1f", Double(selectedForce)) } - @IBAction func durationSliderChanged(sender: AnyObject) { - selectedDuration = sender.valueForKey("value") as! CGFloat + @IBAction func durationSliderChanged(_ sender: AnyObject) { + selectedDuration = sender.value(forKey: "value") as! CGFloat animateView() durationLabel.text = String(format: "Duration: %.1f", Double(selectedDuration)) } - @IBAction func delaySliderChanged(sender: AnyObject) { - selectedDelay = sender.valueForKey("value") as! CGFloat + @IBAction func delaySliderChanged(_ sender: AnyObject) { + selectedDelay = sender.value(forKey: "value") as! CGFloat animateView() delayLabel.text = String(format: "Delay: %.1f", Double(selectedDelay)) } - func dampingSliderChanged(sender: AnyObject) { - selectedDamping = sender.valueForKey("value") as! CGFloat + func dampingSliderChanged(_ sender: AnyObject) { + selectedDamping = sender.value(forKey: "value") as! CGFloat animateView() } - func velocitySliderChanged(sender: AnyObject) { - selectedVelocity = sender.valueForKey("value") as! CGFloat + func velocitySliderChanged(_ sender: AnyObject) { + selectedVelocity = sender.value(forKey: "value") as! CGFloat animateView() } - func scaleSliderChanged(sender: AnyObject) { - selectedScale = sender.valueForKey("value") as! CGFloat + func scaleSliderChanged(_ sender: AnyObject) { + selectedScale = sender.value(forKey: "value") as! CGFloat animateView() } - func xSliderChanged(sender: AnyObject) { - selectedX = sender.valueForKey("value") as! CGFloat + func xSliderChanged(_ sender: AnyObject) { + selectedX = sender.value(forKey: "value") as! CGFloat animateView() } - func ySliderChanged(sender: AnyObject) { - selectedY = sender.valueForKey("value") as! CGFloat + func ySliderChanged(_ sender: AnyObject) { + selectedY = sender.value(forKey: "value") as! CGFloat animateView() } - func rotateSliderChanged(sender: AnyObject) { - selectedRotate = sender.valueForKey("value") as! CGFloat + func rotateSliderChanged(_ sender: AnyObject) { + selectedRotate = sender.value(forKey: "value") as! CGFloat animateView() } @@ -102,18 +102,18 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView ballView.curve = animationCurves[selectedEasing].rawValue } - func minimizeView(sender: AnyObject) { - SpringAnimation.spring(0.7, animations: { - self.view.transform = CGAffineTransformMakeScale(0.935, 0.935) + @objc func minimizeView(_ sender: AnyObject) { + SpringAnimation.spring(duration: 0.7, animations: { + self.view.transform = CGAffineTransform(scaleX: 0.935, y: 0.935) }) - UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true) + UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.lightContent, animated: true) } - func maximizeView(sender: AnyObject) { - SpringAnimation.spring(0.7, animations: { - self.view.transform = CGAffineTransformMakeScale(1, 1) + @objc func maximizeView(_ sender: AnyObject) { + SpringAnimation.spring(duration: 0.7, animations: { + self.view.transform = CGAffineTransform(scaleX: 1, y: 1) }) - UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.Default, animated: true) + UIApplication.shared.setStatusBarStyle(UIStatusBarStyle.default, animated: true) } let animations: [Spring.AnimationPreset] = [ @@ -185,12 +185,12 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView animationPicker.showsSelectionIndicator = true } - @IBAction func ballButtonPressed(sender: AnyObject) { + @IBAction func ballButtonPressed(_ sender: AnyObject) { - UIView.animateWithDuration(0.1, animations: { + UIView.animate(withDuration: 0.1, animations: { self.ballView.backgroundColor = UIColor(hex: "69DBFF") }, completion: { finished in - UIView.animateWithDuration(0.5, animations: { + UIView.animate(withDuration: 0.5, animations: { self.ballView.backgroundColor = UIColor(hex: "#279CEB") }) }) @@ -209,14 +209,14 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView animation.toValue = cornerRadius animation.duration = 0.2 ballView.layer.cornerRadius = cornerRadius - ballView.layer.addAnimation(animation, forKey: "radius") + ballView.layer.add(animation, forKey: "radius") } - @IBAction func shapeButtonPressed(sender: AnyObject) { + @IBAction func shapeButtonPressed(_ sender: AnyObject) { changeBall() } - func resetButtonPressed(sender: AnyObject) { + func resetButtonPressed(_ sender: AnyObject) { selectedForce = 1 selectedDuration = 1 selectedDelay = 0 @@ -237,19 +237,19 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView delayLabel.text = String(format: "Delay: %.1f", Double(selectedDelay)) } - func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int { + func numberOfComponents(in pickerView: UIPickerView) -> Int { return 2 } - func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { + func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int { return component == 0 ? animations.count : animationCurves.count } - func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { + func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? { return component == 0 ? animations[row].rawValue : animationCurves[row].rawValue } - func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { + func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) { switch component { case 0: selectedRow = row @@ -260,15 +260,15 @@ class SpringViewController: UIViewController, UIPickerViewDelegate, UIPickerView } } - override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { - if let optionsViewController = segue.destinationViewController as? OptionsViewController { + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if let optionsViewController = segue.destination as? OptionsViewController { optionsViewController.delegate = self setOptions() optionsViewController.data = ballView } - else if let codeViewController = segue.destinationViewController as? CodeViewController { + else if let codeViewController = segue.destination as? CodeViewController { setOptions() codeViewController.data = ballView } } -} \ No newline at end of file +} diff --git a/SpringAppTests/SpringAppTests.swift b/SpringAppTests/SpringAppTests.swift index 2f0113b..ac2484b 100644 --- a/SpringAppTests/SpringAppTests.swift +++ b/SpringAppTests/SpringAppTests.swift @@ -28,7 +28,7 @@ class SpringAppTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } } diff --git a/SpringTests/SpringTests.swift b/SpringTests/SpringTests.swift index 105bf23..938737d 100644 --- a/SpringTests/SpringTests.swift +++ b/SpringTests/SpringTests.swift @@ -28,7 +28,7 @@ class SpringTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } }