diff --git a/Demo/WhisperDemo/WhisperDemo.xcworkspace/xcuserdata/RamonGilabert.xcuserdatad/UserInterfaceState.xcuserstate b/Demo/WhisperDemo/WhisperDemo.xcworkspace/xcuserdata/RamonGilabert.xcuserdatad/UserInterfaceState.xcuserstate index 706039e..89e2f78 100644 Binary files a/Demo/WhisperDemo/WhisperDemo.xcworkspace/xcuserdata/RamonGilabert.xcuserdatad/UserInterfaceState.xcuserstate and b/Demo/WhisperDemo/WhisperDemo.xcworkspace/xcuserdata/RamonGilabert.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/Demo/WhisperDemo/WhisperDemo/AppDelegate.swift b/Demo/WhisperDemo/WhisperDemo/AppDelegate.swift index b582389..2d9627b 100644 --- a/Demo/WhisperDemo/WhisperDemo/AppDelegate.swift +++ b/Demo/WhisperDemo/WhisperDemo/AppDelegate.swift @@ -16,6 +16,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate { window?.rootViewController = navigationController window?.makeKeyAndVisible() + UIApplication.sharedApplication().statusBarHidden = true + UIApplication.sharedApplication().statusBarHidden = false + return true } } diff --git a/Demo/WhisperDemo/WhisperDemo/Info.plist b/Demo/WhisperDemo/WhisperDemo/Info.plist index d338c77..303058c 100644 --- a/Demo/WhisperDemo/WhisperDemo/Info.plist +++ b/Demo/WhisperDemo/WhisperDemo/Info.plist @@ -2,6 +2,8 @@ + UIViewControllerBasedStatusBarAppearance + CFBundleDevelopmentRegion en CFBundleExecutable @@ -31,6 +33,8 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight UISupportedInterfaceOrientations~ipad diff --git a/Demo/WhisperDemo/WhisperDemo/ViewController.swift b/Demo/WhisperDemo/WhisperDemo/ViewController.swift index c2880ef..fb1b99f 100644 --- a/Demo/WhisperDemo/WhisperDemo/ViewController.swift +++ b/Demo/WhisperDemo/WhisperDemo/ViewController.swift @@ -55,6 +55,14 @@ class ViewController: UIViewController { return button }() + lazy var statusBarButton: UIButton = { [unowned self] in + let button = UIButton() + button.addTarget(self, action: "statusBarButtonDidPress:", forControlEvents: .TouchUpInside) + button.setTitle("Status bar", forState: .Normal) + + return button + }() + lazy var containerView: UIView = { let view = UIView() view.backgroundColor = UIColor.grayColor() @@ -68,13 +76,14 @@ class ViewController: UIViewController { view.backgroundColor = UIColor.whiteColor() view.addSubview(scrollView) - for subview in [icon, titleLabel, presentButton, showButton, presentPermanentButton, notificationButton] { scrollView.addSubview(subview) } - - for button in [presentButton, showButton, presentPermanentButton, notificationButton] { - button.setTitleColor(UIColor.grayColor(), forState: .Normal) - button.layer.borderColor = UIColor.grayColor().CGColor - button.layer.borderWidth = 1.5 - button.layer.cornerRadius = 7.5 + [icon, titleLabel, presentButton, showButton, + presentPermanentButton, notificationButton, statusBarButton].forEach { scrollView.addSubview($0) } + + [presentButton, showButton, presentPermanentButton, notificationButton, statusBarButton].forEach { + $0.setTitleColor(UIColor.grayColor(), forState: .Normal) + $0.layer.borderColor = UIColor.grayColor().CGColor + $0.layer.borderWidth = 1.5 + $0.layer.cornerRadius = 7.5 } guard let navigationController = navigationController else { return } @@ -95,10 +104,16 @@ class ViewController: UIViewController { setupFrames() } + // MARK: - Orientation changes + + override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) { + setupFrames() + } + // MARK: Action methods func presentButtonDidPress(button: UIButton) { - guard let navigationController = self.navigationController else { return } + guard let navigationController = navigationController else { return } let message = Message(title: "This message will silent in 3 seconds.", color: UIColor(red:0.89, green:0.09, blue:0.44, alpha:1)) Whisper(message, to: navigationController, action: .Present) @@ -106,14 +121,14 @@ class ViewController: UIViewController { } func showButtonDidPress(button: UIButton) { - guard let navigationController = self.navigationController else { return } + guard let navigationController = navigationController else { return } let message = Message(title: "Showing all the things.", color: UIColor.blackColor()) Whisper(message, to: navigationController) } func presentPermanentButtonDidPress(button: UIButton) { - guard let navigationController = self.navigationController else { return } + guard let navigationController = navigationController else { return } let message = Message(title: "This is a permanent Whisper.", color: UIColor(red:0.87, green:0.34, blue:0.05, alpha:1)) Whisper(message, to: navigationController, action: .Present) @@ -125,17 +140,30 @@ class ViewController: UIViewController { Shout(announcement, to: self) } + func statusBarButtonDidPress(button: UIButton) { + let murmur = Murmur(title: "This is a small whistle", + backgroundColor: UIColor(red: 0.975, green: 0.975, blue: 0.975, alpha: 1)) + + Whistle(murmur) + } + // MARK - Configuration func setupFrames() { let totalSize = UIScreen.mainScreen().bounds - scrollView.frame = CGRect(x: 0, y: 0, width: totalSize.width, height: totalSize.height) - titleLabel.frame.origin = CGPoint(x: (totalSize.width - titleLabel.frame.width) / 2, y: totalSize.height / 2 - 250) - presentButton.frame = CGRect(x: 50, y: titleLabel.frame.maxY + 75, width: totalSize.width - 100, height: 50) - showButton.frame = CGRect(x: 50, y: presentButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) - presentPermanentButton.frame = CGRect(x: 50, y: showButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) - notificationButton.frame = CGRect(x: 50, y: presentPermanentButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) + UIView.animateWithDuration(0.3, animations: { + self.scrollView.frame = CGRect(x: 0, y: 0, width: totalSize.width, height: totalSize.height) + self.titleLabel.frame.origin = CGPoint(x: (totalSize.width - self.titleLabel.frame.width) / 2, y: 60) + self.presentButton.frame = CGRect(x: 50, y: self.titleLabel.frame.maxY + 75, width: totalSize.width - 100, height: 50) + self.showButton.frame = CGRect(x: 50, y: self.presentButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) + self.presentPermanentButton.frame = CGRect(x: 50, y: self.showButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) + self.notificationButton.frame = CGRect(x: 50, y: self.presentPermanentButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) + self.statusBarButton.frame = CGRect(x: 50, y: self.notificationButton.frame.maxY + 15, width: totalSize.width - 100, height: 50) + + let height = self.statusBarButton.frame.maxY >= totalSize.height ? self.statusBarButton.frame.maxY + 35 : totalSize.height + self.scrollView.contentSize = CGSize(width: totalSize.width, height: height) + }) } } diff --git a/Source/Configuration/ColorList.swift b/Source/Configuration/ColorList.swift index 87f52bf..85d3876 100644 --- a/Source/Configuration/ColorList.swift +++ b/Source/Configuration/ColorList.swift @@ -9,4 +9,9 @@ public struct ColorList { public static var title = UIColor.blackColor() public static var subtitle = UIColor.blackColor() } + + public struct Whistle { + public static var background = UIColor.whiteColor() + public static var title = UIColor.blackColor() + } } diff --git a/Source/Configuration/FontList.swift b/Source/Configuration/FontList.swift index ba943d8..15ea943 100644 --- a/Source/Configuration/FontList.swift +++ b/Source/Configuration/FontList.swift @@ -7,4 +7,9 @@ public struct FontList { public static let title = UIFont.boldSystemFontOfSize(15) public static let subtitle = UIFont.systemFontOfSize(13) } + + public struct Whistle { + + public static let title = UIFont.systemFontOfSize(12) + } } diff --git a/Source/Message.swift b/Source/Message.swift index a6cbd36..f281fea 100644 --- a/Source/Message.swift +++ b/Source/Message.swift @@ -29,3 +29,20 @@ public struct Announcement { self.action = action } } + +public struct Murmur { + + public var title: String + public var duration: NSTimeInterval + public var backgroundColor: UIColor + public var titleColor: UIColor + public var font: UIFont + + public init(title: String, duration: NSTimeInterval = 1.5, backgroundColor: UIColor = ColorList.Whistle.background, titleColor: UIColor = ColorList.Whistle.title, font: UIFont = FontList.Whistle.title) { + self.title = title + self.duration = duration + self.backgroundColor = backgroundColor + self.titleColor = titleColor + self.font = font + } +} diff --git a/Source/WhistleFactory.swift b/Source/WhistleFactory.swift new file mode 100644 index 0000000..9d00f1b --- /dev/null +++ b/Source/WhistleFactory.swift @@ -0,0 +1,111 @@ +import UIKit + +let whistleFactory = WhistleFactory() + +public func Whistle(murmur: Murmur) { + whistleFactory.whistler(murmur) +} + +public class WhistleFactory: UIViewController { + + public struct Dimensions { + public static let height: CGFloat = 20 + } + + public lazy var whistleWindow: UIWindow = UIWindow() + + public lazy var titleLabel: UILabel = { + let label = UILabel() + label.textAlignment = .Center + + return label + }() + + public var duration: NSTimeInterval = 2 + public var viewController: UIViewController? + public var hideTimer = NSTimer() + + // MARK: - Initializers + + override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) { + super.init(nibName: nil, bundle: nil) + + setupWindow() + view.clipsToBounds = true + view.addSubview(titleLabel) + } + + public required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Configuration + + public func whistler(murmur: Murmur) { + titleLabel.text = murmur.title + titleLabel.font = murmur.font + titleLabel.textColor = murmur.titleColor + view.backgroundColor = murmur.backgroundColor + whistleWindow.backgroundColor = murmur.backgroundColor + + setupFrames() + present() + } + + // MARK: - Setup + + public func setupWindow() { + whistleWindow.addSubview(self.view) + whistleWindow.windowLevel = UIWindowLevelStatusBar + whistleWindow.clipsToBounds = true + } + + public func setupFrames() { + titleLabel.sizeToFit() + + whistleWindow.rootViewController = self + whistleWindow.frame = CGRect(x: 0, y: 0, width: UIScreen.mainScreen().bounds.width, + height: Dimensions.height) + view.frame = whistleWindow.bounds + titleLabel.frame = view.bounds + } + + // MARK: - Movement methods + + public func present() { + hideTimer.invalidate() + + let initialOrigin = whistleWindow.frame.origin.y + whistleWindow.frame.origin.y = initialOrigin - Dimensions.height + whistleWindow.makeKeyAndVisible() + UIView.animateWithDuration(0.2, animations: { + self.whistleWindow.frame.origin.y = initialOrigin + }) + + hideTimer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: "timerDidFire", userInfo: nil, repeats: false) + } + + public func hide() { + let finalOrigin = view.frame.origin.y - Dimensions.height + UIView.animateWithDuration(0.2, animations: { + self.whistleWindow.frame.origin.y = finalOrigin + }, completion: { _ in + if let window = UIApplication.sharedApplication().windows.filter({ $0 != self.whistleWindow }).first { + window.makeKeyAndVisible() + } + }) + } + + // MARK: - Timer methods + + public func timerDidFire() { + hide() + } + + public override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) { + if whistleWindow.keyWindow { + setupFrames() + hide() + } + } +}