Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions SimpleToast.podspec
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Pod::Spec.new do |s|
s.name = 'SimpleToast'
s.version = '0.1.1'
s.version = '0.2.0'
s.license = 'MIT'
s.summary = 'Simple toasts with Android-like API and keyboard aware positioning.'
s.homepage = 'https://github.com/lohmander/SimpleToast'
s.authors = { 'Hannes Lohmander' => 'hannes@lohmander.me' }
s.source = { :git => 'https://github.com/lohmander/SimpleToast.git', :tag => s.version }
s.source = { :git => 'https://github.com/lohmander/SimpleToast.git' }

s.ios.deployment_target = '8.0'

Expand Down
46 changes: 16 additions & 30 deletions Toast/Toast/Toast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ public class Toast {
public static let LENGTH_LONG: Double = 5

/// Shared toast appearance settings
public static let appearance = ToastAppearance()
let appearance: ToastAppearance!

/// Shared keyboard observer used to determine appropriate toast position
private static var keyboardObserver: KeyboardObserver?
static var keyboardObserver: KeyboardObserver?

var text: String!
var duration: Double!
var toast: ToastView!

public init(appearance: ToastAppearance) {
self.appearance = appearance
}

/**
Initializes keyboard observer used to figure out the appropriate
toast position
Expand All @@ -40,8 +44,8 @@ public class Toast {

:returns: Toast
*/
public class func makeText(text: String, duration: Double = Toast.LENGTH_LONG) -> Toast {
let toast = Toast()
public class func makeText(text: String, duration: Double = Toast.LENGTH_LONG, appearance: ToastAppearance = ToastAppearance()) -> Toast {
let toast = Toast(appearance: appearance)

toast.text = text
toast.duration = duration
Expand All @@ -55,33 +59,15 @@ public class Toast {
:returns: Void
*/
public func show() -> Void {
let keyWindow = UIApplication.sharedApplication().keyWindow

if let windowView = keyWindow?.subviews.first as? UIView {
toast = ToastView()
toast.textLabel?.text = self.text

let margin = Toast.appearance.margin
let views = ["toast": toast]
let yMargin: CGFloat

if let kO = Toast.keyboardObserver {
yMargin = margin + kO.offset
} else {
yMargin = margin
}
let nc = UIApplication.sharedApplication().keyWindow!.rootViewController as! UINavigationController
let vc = nc.viewControllers.last

if let windowView = vc?.view {
toast = ToastView(text: self.text, parent: windowView, appearance: appearance)

windowView.addSubview(toast)

let verticalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("V:[toast]-\(yMargin)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
let horizontalConstraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|-(>=\(margin))-[toast]-(>=\(margin))-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
let centerContraint = NSLayoutConstraint(item: toast, attribute: .CenterX, relatedBy: .Equal, toItem: windowView, attribute: .CenterX, multiplier: 1, constant: 0)

windowView.addConstraints(verticalConstraints)
windowView.addConstraints(horizontalConstraints)
windowView.addConstraint(centerContraint)

UIView.animateWithDuration(Toast.appearance.animationDuration, animations: { () -> Void in
UIView.animateWithDuration(appearance.animationDuration, animations: { () -> Void in
self.toast.alpha = 1
})

Expand All @@ -95,7 +81,7 @@ public class Toast {
:returns: Void
*/
public func hide() -> Void {
UIView.animateWithDuration(Toast.appearance.animationDuration, animations: { () -> Void in
UIView.animateWithDuration(appearance.animationDuration, animations: { () -> Void in
self.toast.alpha = 0
}) { (_) -> Void in
self.remove()
Expand Down Expand Up @@ -126,4 +112,4 @@ public class Toast {
public func remove() -> Void {
self.toast.removeFromSuperview()
}
}
}
16 changes: 9 additions & 7 deletions Toast/Toast/ToastAppearance.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,26 @@
import Foundation

public class ToastAppearance {
/// Whether or not the toast background should have a blurred background
public var blur: Bool = true

/// Blur style if blur is set to true
public var blurStyle: UIBlurEffectStyle = .Dark
public init() {

}

/// Toast background corner radius
public var cornerRadius: CGFloat = 4

/// Margin between the toast and the surrounding view
public var margin: CGFloat = 16

/// Padding between the text label and the toast background
public var padding: CGFloat = 10

/// The label text color
public var backgroundColor: UIColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.7)

/// The label text color
public var textColor: UIColor = UIColor.whiteColor()

/// The duration of the fade in animation
public var animationDuration: NSTimeInterval = 0.5

/// A font to use
public var font: UIFont? = nil
}
104 changes: 58 additions & 46 deletions Toast/Toast/ToastView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,74 +8,86 @@

import Foundation

extension UILabel{

func requiredHeight() -> CGFloat{

let label:UILabel = UILabel(frame: CGRectMake(0, 0, self.frame.width, CGFloat.max))
label.numberOfLines = 0
label.lineBreakMode = NSLineBreakMode.ByWordWrapping
label.font = self.font
label.text = self.text

label.sizeToFit()

return label.frame.height
}
}

class ToastView: UIView {
var blurEffectView: UIVisualEffectView?
var textLabel: UILabel?

private var constraintsSet: Bool = false

private var ko = KeyboardObserver()

required init() {
super.init(frame: CGRectZero)
setup()
}

required override init(frame: CGRect) {
super.init(frame: frame)
setup()
}

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
super.init(coder: aDecoder)!
}

private func setup() {
self.setTranslatesAutoresizingMaskIntoConstraints(false)
self.alpha = 0
init(text: String, parent: UIView, appearance: ToastAppearance) {
super.init(frame: CGRectZero)
setup(text, parent: parent, appearance: appearance)
}

private func setup(text: String, parent: UIView, appearance: ToastAppearance) {

if Toast.appearance.blur {
let blurEffect = UIBlurEffect(style: Toast.appearance.blurStyle)
blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView?.setTranslatesAutoresizingMaskIntoConstraints(false)
blurEffectView?.layer.cornerRadius = 5
blurEffectView?.clipsToBounds = true

self.addSubview(blurEffectView!)
}
self.alpha = 0
self.backgroundColor = appearance.backgroundColor
self.layer.cornerRadius = appearance.cornerRadius

textLabel = UILabel()
textLabel?.textColor = Toast.appearance.textColor
textLabel?.textColor = appearance.textColor
textLabel?.numberOfLines = 0
textLabel?.setTranslatesAutoresizingMaskIntoConstraints(false)
textLabel?.textAlignment = NSTextAlignment.Center
textLabel?.font = appearance.font

self.addSubview(textLabel!)
}

override func updateConstraints() {
if !constraintsSet {
let padding = Toast.appearance.padding

var views: [String: AnyObject] = ["label": textLabel!]

let horizontalMargin = NSLayoutConstraint.constraintsWithVisualFormat("H:|-\(padding)-[label]-\(padding)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
let verticalMargin = NSLayoutConstraint.constraintsWithVisualFormat("V:|-\(padding)-[label]-\(padding)-|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)

self.addConstraints(horizontalMargin)
self.addConstraints(verticalMargin)

if blurEffectView != nil {
views["blur"] = blurEffectView!

let blurWidthConstraint = NSLayoutConstraint.constraintsWithVisualFormat("H:|[blur]|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)
let blurHeightContraint = NSLayoutConstraint.constraintsWithVisualFormat("V:|[blur]|", options: NSLayoutFormatOptions(0), metrics: nil, views: views)

self.addConstraints(blurWidthConstraint)
self.addConstraints(blurHeightContraint)
}

constraintsSet = true

frame = CGRectMake(10, parent.frame.size.height, parent.frame.size.width - 20, 100)

textLabel?.frame = CGRectMake(0 + appearance.padding,
0 + appearance.padding,
frame.size.width - appearance.padding * 2,
1000)
textLabel?.text = text
let size = textLabel?.sizeThatFits(CGSizeMake(frame.size.width - appearance.padding * 2, 1000))
textLabel!.frame = CGRectMake( textLabel!.frame.origin.x,
textLabel!.frame.origin.y,
textLabel!.frame.size.width,
size!.height
)

let yMargin: CGFloat

if let kO = Toast.keyboardObserver {
yMargin = kO.offset
} else {
yMargin = 0
}

super.updateConstraints()
frame = CGRectMake(frame.origin.x,
frame.origin.y - textLabel!.frame.size.height - appearance.padding * 2 - 10 - yMargin,
frame.size.width,
textLabel!.frame.size.height + appearance.padding * 2)
}
}

}