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
23 changes: 11 additions & 12 deletions Example/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ extension ViewController {
if section == 0 {
return 2
} else {
return 11
return 12
}
}

Expand Down Expand Up @@ -146,9 +146,10 @@ extension ViewController {
case 5: cell.textLabel?.text = "Make toast with a custom style"
case 6: cell.textLabel?.text = "Show a custom view as toast"
case 7: cell.textLabel?.text = "Show an image as toast at point\n(110, 110)"
case 8: cell.textLabel?.text = showingActivity ? "Hide toast activity" : "Show toast activity"
case 9: cell.textLabel?.text = "Hide toast"
case 10: cell.textLabel?.text = "Hide all toasts"
case 8: cell.textLabel?.text = showingActivity ? "Hide toast activity" : "Show toast activity (no message)"
case 9: cell.textLabel?.text = showingActivity ? "Hide toast activity" : "Show toast activity (with message)"
case 10: cell.textLabel?.text = "Hide toast"
case 11: cell.textLabel?.text = "Hide all toasts"
default: cell.textLabel?.text = nil
}

Expand Down Expand Up @@ -202,21 +203,19 @@ extension ViewController {
// Show an image view as toast, on center at point (110,110)
let toastView = UIImageView(image: UIImage(named: "toast.png"))
self.navigationController?.view.showToast(toastView, duration: 2.0, point: CGPoint(x: 110.0, y: 110.0))
case 8:
// Make toast activity
case 8, 9:
let message = (indexPath.row == 9) ? "This is a toast activity with a custom message" : nil
if !showingActivity {
self.navigationController?.view.makeToastActivity(.center)
navigationController?.view.makeToastActivity(.center, message)
} else {
self.navigationController?.view.hideToastActivity()
navigationController?.view.hideToastActivity()
}

showingActivity.toggle()

tableView.reloadData()
case 9:
case 10:
// Hide toast
self.navigationController?.view.hideToast()
case 10:
case 11:
// Hide all toasts
self.navigationController?.view.hideAllToasts()
default:
Expand Down
107 changes: 79 additions & 28 deletions Toast/Toast.swift
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ public extension UIView {

@param position The toast's position
*/
func makeToastActivity(_ position: ToastPosition) {
func makeToastActivity(_ position: ToastPosition, _ message: String? = nil) {
// sanity
guard objc_getAssociatedObject(self, &ToastKeys.activityView) as? UIView == nil else { return }

let toast = createToastActivityView()
let toast = createToastActivityView(message: message)
let point = position.centerPoint(forToast: toast, inSuperview: self)
makeToastActivity(toast, point: point)
}
Expand All @@ -271,11 +271,11 @@ public extension UIView {

@param point The toast's center point
*/
func makeToastActivity(_ point: CGPoint) {
func makeToastActivity(_ point: CGPoint, _ message: String? = nil) {
// sanity
guard objc_getAssociatedObject(self, &ToastKeys.activityView) as? UIView == nil else { return }

let toast = createToastActivityView()
let toast = createToastActivityView(message: message)
makeToastActivity(toast, point: point)
}

Expand Down Expand Up @@ -317,28 +317,64 @@ public extension UIView {
})
}

private func createToastActivityView() -> UIView {
private func createToastActivityView(message: String?) -> UIView {
let style = ToastManager.shared.style

let activityView = UIView(frame: CGRect(x: 0.0, y: 0.0, width: style.activitySize.width, height: style.activitySize.height))
activityView.backgroundColor = style.activityBackgroundColor
activityView.autoresizingMask = [.flexibleLeftMargin, .flexibleRightMargin, .flexibleTopMargin, .flexibleBottomMargin]
activityView.layer.cornerRadius = style.cornerRadius


let containerView = UIView()
containerView.backgroundColor = style.activityBackgroundColor
containerView.layer.cornerRadius = style.cornerRadius

if style.displayShadow {
activityView.layer.shadowColor = style.shadowColor.cgColor
activityView.layer.shadowOpacity = style.shadowOpacity
activityView.layer.shadowRadius = style.shadowRadius
activityView.layer.shadowOffset = style.shadowOffset
containerView.layer.shadowColor = style.shadowColor.cgColor
containerView.layer.shadowOpacity = style.shadowOpacity
containerView.layer.shadowRadius = style.shadowRadius
containerView.layer.shadowOffset = style.shadowOffset
}

let activityIndicatorView = UIActivityIndicatorView(style: .whiteLarge)
activityIndicatorView.center = CGPoint(x: activityView.bounds.size.width / 2.0, y: activityView.bounds.size.height / 2.0)
activityView.addSubview(activityIndicatorView)
activityIndicatorView.color = style.activityIndicatorColor
activityIndicatorView.startAnimating()

return activityView

let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = style.activityViewSpacing
stackView.translatesAutoresizingMaskIntoConstraints = false

let activityIndicator = UIActivityIndicatorView(style: .whiteLarge)
activityIndicator.color = style.activityIndicatorColor
activityIndicator.startAnimating()
stackView.addArrangedSubview(activityIndicator)

// Optional message label
let padding: CGFloat
if let message = message, !message.isEmpty {
let label = UILabel()
label.font = style.messageFont
label.textColor = style.messageColor
label.textAlignment = .center
label.numberOfLines = 0
label.text = message
stackView.addArrangedSubview(label)
padding = style.activityViewPaddingWithMessage
} else {
padding = style.activityViewPaddingNoMessage
}

containerView.addSubview(stackView)

NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: padding),
stackView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -padding),
stackView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: padding),
stackView.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -padding),
stackView.widthAnchor.constraint(lessThanOrEqualToConstant: style.activityViewMaxWidth)
])

// We need to set a frame to calculate a center point while the view is off-screen
let containerViewSize = containerView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize)
containerView.frame = CGRect(
origin: .zero,
size: containerViewSize
)

return containerView
}

// MARK: - Private Show/Hide Methods
Expand Down Expand Up @@ -681,13 +717,28 @@ public struct ToastStyle {
The image size. The default is 80 x 80.
*/
public var imageSize = CGSize(width: 80.0, height: 80.0)

/**
The size of the toast activity view when `makeToastActivity(position:)` is called.
Default is 100 x 100.
The maximum width of the toast when `makeToastActivity(position:message:)` is called with a message.
The view can further grow vertically vertically to fit the message.
*/
public var activitySize = CGSize(width: 100.0, height: 100.0)

public var activityViewMaxWidth: CGFloat = 200.0

/**
The spacing between the spinner and the label when`makeToastActivity(position:message:)` is called with a message.
*/
public var activityViewSpacing: CGFloat = 10.0

/**
The padding in the toast when `makeToastActivity(position:message:)` is called without a message.
*/
public var activityViewPaddingNoMessage: CGFloat = 32.0

/**
The padding in the toast when `makeToastActivity(position:message:)` is called with a message.
*/
public var activityViewPaddingWithMessage: CGFloat = 16.0

/**
The fade in/out animation duration. Default is 0.2.
*/
Expand Down