Skip to content

Commit

Permalink
Merge pull request #13 from dkcas11/dev/spring-cleaning-and-protocols
Browse files Browse the repository at this point in the history
Spring cleaning and protocols
  • Loading branch information
dkcas11 authored May 25, 2018
2 parents cf1c03e + a57be2d commit eb9572e
Show file tree
Hide file tree
Showing 17 changed files with 427 additions and 302 deletions.
133 changes: 76 additions & 57 deletions CRNotifications/Classes/CRNotification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,37 @@

import UIKit

class CRNotification: UIView {
internal class CRNotification: UIView {

public fileprivate(set) lazy var imageView: UIImageView = {
private lazy var imageView: UIImageView = {
let view = UIImageView()
view.tintColor = .white
return view
}()
public fileprivate(set) lazy var titleLabel: UILabel = {

private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 15, weight: UIFont.Weight.bold)
label.textColor = .white
return label
}()
public fileprivate(set) lazy var messageView: UITextView = {
let view = UITextView()
view.font = UIFont.systemFont(ofSize: 14, weight: UIFont.Weight.semibold)
view.backgroundColor = .clear
view.textColor = .white
view.isUserInteractionEnabled = false
view.textContainerInset = UIEdgeInsets(top: 0, left: -5, bottom: 0, right: 0)
view.textContainer.lineBreakMode = .byWordWrapping
return view

private lazy var messageLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 13, weight: UIFont.Weight.semibold)
label.textColor = .white
label.numberOfLines = 2
return label
}()
public var completion: () -> () = {}

init() {
private var completion: () -> () = {}


// MARK: - Init

required internal init?(coder aDecoder:NSCoder) { fatalError("Not implemented.") }

internal init() {
let deviceWidth = min(UIScreen.main.bounds.width, UIScreen.main.bounds.height)
let widthFactor: CGFloat = DeviceManager.value(iPhone35: 0.9, iPhone40: 0.9, iPhone47: 0.9, iPhone55: 0.85, iPhone58: 0.9, iPadSmall: 0.5, iPadMedium: 0.45, iPadBig: 0.4)
let heightFactor: CGFloat = DeviceManager.value(iPhone35: 0.2, iPhone40: 0.2, iPhone47: 0.2, iPhone55: 0.2, iPhone58: 0.2, iPadSmall: 0.18, iPadMedium: 0.17, iPadBig: 0.17)
Expand All @@ -49,103 +54,117 @@ class CRNotification: UIView {
setupTargets()
}

func setupLayer() {

// MARK: - Setup

private func setupLayer() {
layer.cornerRadius = 5
layer.shadowRadius = 5
layer.shadowOpacity = 0.25
layer.shadowColor = UIColor.lightGray.cgColor
}

func setupSubviews() {
private func setupSubviews() {
addSubview(imageView)
addSubview(titleLabel)
addSubview(messageView)
addSubview(messageLabel)
}

func setupConstraints() {
private func setupConstraints() {
imageView.translatesAutoresizingMaskIntoConstraints = false
messageView.translatesAutoresizingMaskIntoConstraints = false
messageLabel.translatesAutoresizingMaskIntoConstraints = false
titleLabel.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
imageView.topAnchor.constraint(equalTo: imageView.superview!.topAnchor, constant: 12),
imageView.leadingAnchor.constraint(equalTo: imageView.superview!.leadingAnchor, constant: 12),
imageView.bottomAnchor.constraint(equalTo: imageView.superview!.bottomAnchor, constant: -12),
imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor)
])
])

NSLayoutConstraint.activate([
titleLabel.topAnchor.constraint(equalTo: titleLabel.superview!.topAnchor, constant: -2),
titleLabel.topAnchor.constraint(greaterThanOrEqualTo: titleLabel.superview!.topAnchor, constant: 6),
titleLabel.topAnchor.constraint(lessThanOrEqualTo: titleLabel.superview!.topAnchor, constant: 2),
titleLabel.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: 8),
titleLabel.trailingAnchor.constraint(equalTo: titleLabel.superview!.trailingAnchor, constant: -8),
titleLabel.bottomAnchor.constraint(equalTo: titleLabel.superview!.centerYAnchor, constant: -2)
])
titleLabel.trailingAnchor.constraint(equalTo: titleLabel.superview!.trailingAnchor, constant: -8)
])

NSLayoutConstraint.activate([
messageView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor, constant: -6),
messageView.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
messageView.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
messageView.bottomAnchor.constraint(equalTo: messageView.superview!.bottomAnchor, constant: -4)
])
messageLabel.topAnchor.constraint(lessThanOrEqualTo: titleLabel.bottomAnchor, constant: 3),
messageLabel.leadingAnchor.constraint(equalTo: titleLabel.leadingAnchor),
messageLabel.trailingAnchor.constraint(equalTo: titleLabel.trailingAnchor),
messageLabel.bottomAnchor.constraint(lessThanOrEqualTo: messageLabel.superview!.bottomAnchor, constant: -4)
])
}

func setupTargets() {
private func setupTargets() {
NotificationCenter.default.addObserver(self, selector: #selector(didRotate), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
let dismissRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissNotification))
addGestureRecognizer(dismissRecognizer)

let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.dismissNotification))
let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(self.dismissNotification))
swipeRecognizer.direction = .up

addGestureRecognizer(tapRecognizer)
addGestureRecognizer(swipeRecognizer)
}


// MARK: - Helpers

@objc func didRotate() {
@objc internal func didRotate() {
UIView.animate(withDuration: 0.2) {
self.center.x = UIScreen.main.bounds.width/2
self.center.y = UIApplication.shared.statusBarFrame.height + 10 + self.frame.height/2
}
}

/** Sets the background color of the notification **/
internal func setBackgroundColor(color: UIColor) {
backgroundColor = color
}

/** Sets the background color of the notification **/
internal func setTextColor(color: UIColor) {
titleLabel.textColor = color
messageLabel.textColor = color
}

/// Required init for nib loading (nib loading is not supported)
required public init?(coder aDecoder:NSCoder) { fatalError("Not implemented.") }

/// Sets the background color of the notification
func setBackgroundColor(color: UIColor) {
backgroundColor = color
}

/// Sets the title of the notification
func setTitle(title: String) {
/** Sets the title of the notification **/
internal func setTitle(title: String) {
titleLabel.text = title
}

/// Sets the message of the notification
func setMessage(message: String) {
messageView.text = message
/** Sets the message of the notification **/
internal func setMessage(message: String) {
messageLabel.text = message
}

/// Sets the image of the notification
func setImage(image: UIImage) {
/** Sets the image of the notification **/
internal func setImage(image: UIImage?) {
imageView.image = image
}

/// Sets the completion block of the notification for when it is dismissed
func setCompletionBlock(_ completion: @escaping () -> ()) {
/** Sets the completion block of the notification for when it is dismissed **/
internal func setCompletionBlock(_ completion: @escaping () -> ()) {
self.completion = completion
}

/// Dismisses the notification with a delay > 0
func setDismisTimer(delay: TimeInterval) {
/** Dismisses the notification with a delay > 0 **/
internal func setDismisTimer(delay: TimeInterval) {
if delay > 0 {
Timer.scheduledTimer(timeInterval: Double(delay), target: self, selector: #selector(dismissNotification), userInfo: nil, repeats: false)
}
}

/// Animates in the notification
func showNotification() {
/** Animates in the notification **/
internal func showNotification() {
UIView.animate(withDuration: 0.3, delay: 0.0, usingSpringWithDamping: 0.68, initialSpringVelocity: 0.1, options: UIViewAnimationOptions(), animations: {
self.frame.origin.y = UIApplication.shared.statusBarFrame.height + 10
})
}

/// Animates out the notification
@objc func dismissNotification() {
/** Animates out the notification **/
@objc internal func dismissNotification() {
UIView.animate(withDuration: 0.1, delay: 0.0, options: UIViewAnimationOptions(), animations: {
self.frame.origin.y = self.frame.origin.y + 5
}, completion: {
Expand Down
28 changes: 5 additions & 23 deletions CRNotifications/Classes/CRNotificationType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,9 @@

import Foundation

/// Enum for types of notifications
public enum CRNotificationType {
case success
case error
case info

var color: UIColor {
switch self {
case .success: return UIColor.flatGreen
case .error: return UIColor.flatRed
case .info: return UIColor.flatGray
}
}

var image: UIImage {
let bundle = Bundle(for: CRNotifications.self)

switch self {
case .success: return UIImage(named: "success", in: bundle, compatibleWith: nil)!
case .error: return UIImage(named: "error", in: bundle, compatibleWith: nil)!
case .info: return UIImage(named: "info", in: bundle, compatibleWith: nil)!
}
}
/** Protocol for defining a CRNotification style **/
public protocol CRNotificationType {
var textColor: UIColor { get }
var backgroundColor: UIColor { get }
var image: UIImage? { get }
}
32 changes: 29 additions & 3 deletions CRNotifications/Classes/CRNotifications.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,32 @@ import UIKit

public class CRNotifications {

// MARK: - Static notification types

public static let success: CRNotificationType = CRNotificationTypeDefinition(textColor: UIColor.white, backgroundColor: UIColor.flatGreen, image: UIImage(named: "success", in: Bundle(for: CRNotifications.self), compatibleWith: nil))
public static let error: CRNotificationType = CRNotificationTypeDefinition(textColor: UIColor.white, backgroundColor: UIColor.flatRed, image: UIImage(named: "error", in: Bundle(for: CRNotifications.self), compatibleWith: nil))
public static let info: CRNotificationType = CRNotificationTypeDefinition(textColor: UIColor.white, backgroundColor: UIColor.flatGray, image: UIImage(named: "info", in: Bundle(for: CRNotifications.self), compatibleWith: nil))


// MARK: - Init

public init(){}

/// Shows a CRNotification
public static func showNotification(type: CRNotificationType, title: String, message: String, dismissDelay: TimeInterval, completion: @escaping () -> () = {}) {

// MARK: - Helpers

/** Shows a CRNotification **/
public static func showNotification(textColor: UIColor, backgroundColor: UIColor, image: UIImage?, title: String, message: String, dismissDelay: TimeInterval, completion: @escaping () -> () = {}) {
let notificationDefinition = CRNotificationTypeDefinition(textColor: textColor, backgroundColor: backgroundColor, image: image)
showNotification(type: notificationDefinition, title: title, message: message, dismissDelay: dismissDelay, completion: completion)
}

/** Shows a CRNotification from a CRNotificationType **/
public static func showNotification(type: CRNotificationType, title: String, message: String, dismissDelay: TimeInterval, completion: @escaping () -> () = {}) {
let view = CRNotification()

view.setBackgroundColor(color: type.color)
view.setBackgroundColor(color: type.backgroundColor)
view.setTextColor(color: type.textColor)
view.setImage(image: type.image)
view.setTitle(title: title)
view.setMessage(message: message)
Expand All @@ -27,7 +46,14 @@ public class CRNotifications {
print("Failed to show CRNotification. No keywindow available.")
return
}

window.addSubview(view)
view.showNotification()
}
}

fileprivate struct CRNotificationTypeDefinition: CRNotificationType {
var textColor: UIColor
var backgroundColor: UIColor
var image: UIImage?
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
20 changes: 16 additions & 4 deletions CRNotificationsExample/Base.lproj/Main.storyboard
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13196" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="cgU-iY-bff">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="cgU-iY-bff">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13173"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand Down Expand Up @@ -52,23 +52,35 @@
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="81M-2e-SRi">
<rect key="frame" x="119" y="434.5" width="137" height="30"/>
<rect key="frame" x="119" y="493.5" width="137" height="30"/>
<state key="normal" title="Next ViewController"/>
<connections>
<action selector="nextViewControllerButton:" destination="BYZ-38-t0r" eventType="touchUpInside" id="cmw-Tl-541"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ehu-8b-b9O">
<rect key="frame" x="153.5" y="384.5" width="68" height="34"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<state key="normal" title="Custom">
<color key="titleColor" red="0.66799789669999998" green="0.47512125970000002" blue="0.25860109930000003" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<connections>
<action selector="showCustom:" destination="BYZ-38-t0r" eventType="touchUpInside" id="AY0-hV-s5c"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<constraints>
<constraint firstItem="i48-R5-0AR" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" constant="-50" id="5go-4j-WZe"/>
<constraint firstItem="d4B-VL-ogg" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="96u-dy-my2"/>
<constraint firstItem="81M-2e-SRi" firstAttribute="top" secondItem="ehu-8b-b9O" secondAttribute="bottom" constant="75" id="BTd-Gy-ZOQ"/>
<constraint firstItem="ehu-8b-b9O" firstAttribute="top" secondItem="d4B-VL-ogg" secondAttribute="bottom" constant="25" id="Dra-t6-fOc"/>
<constraint firstItem="VH0-uo-A2x" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="R76-q6-Zkw"/>
<constraint firstItem="i48-R5-0AR" firstAttribute="top" secondItem="VH0-uo-A2x" secondAttribute="bottom" constant="25" id="VhZ-Dk-Z1I"/>
<constraint firstItem="81M-2e-SRi" firstAttribute="top" secondItem="d4B-VL-ogg" secondAttribute="bottom" constant="75" id="gbN-tg-XRd"/>
<constraint firstItem="i48-R5-0AR" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="h90-dx-Fsh"/>
<constraint firstItem="d4B-VL-ogg" firstAttribute="top" secondItem="i48-R5-0AR" secondAttribute="bottom" constant="25" id="rB0-1T-9GM"/>
<constraint firstItem="81M-2e-SRi" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="wM7-Sy-LIk"/>
<constraint firstItem="ehu-8b-b9O" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="zgC-Go-mdQ"/>
</constraints>
</view>
<navigationItem key="navigationItem" id="IPT-cX-ycH"/>
Expand Down
2 changes: 1 addition & 1 deletion CRNotificationsExample/PushViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ class PushViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)

CRNotifications.showNotification(type: .success, title: "Pushed through!", message: "I'm right here.", dismissDelay: 3)
CRNotifications.showNotification(type: CRNotifications.success, title: "Pushed through!", message: "I'm right here.", dismissDelay: 3)
}
}
Loading

0 comments on commit eb9572e

Please sign in to comment.