You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

401 lines
10 KiB

//
// UIViewExtension.swift
// GMERemittance
//
// Created by Fm-user on 12/23/17.
// Copyright © 2017 Gobal Money Express Co. Ltd. All rights reserved.
//
import Foundation
import UIKit
import VisualEffectView
extension UIView {
func rounded() {
self.layer.cornerRadius = self.frame.height / 2
}
func addBlur() {
let visualEffectView = VisualEffectView(frame: self.frame)
visualEffectView.colorTint = .clear
visualEffectView.colorTintAlpha = 0.2
visualEffectView.blurRadius = 3
visualEffectView.scale = 1
visualEffectView.isUserInteractionEnabled = false
self.addSubview(visualEffectView)
}
}
extension UIView {
func fadeIn(
duration: TimeInterval = 1.0,
delay: TimeInterval = 0.0,
completion: @escaping ((Bool) -> Void) = {(finished: Bool) -> Void in}) {
UIView.animate(
withDuration: duration,
delay: delay,
options: UIView.AnimationOptions.curveEaseIn,
animations: {
self.alpha = 1.0
},
completion: completion
)
}
func fadeOut(
duration: TimeInterval = 1.0,
delay: TimeInterval = 3.0,
completion: @escaping (Bool) -> Void = {(finished: Bool) -> Void in}
) {
UIView.animate(
withDuration: duration,
delay: delay,
options: UIView.AnimationOptions.curveEaseIn,
animations: {
self.alpha = 0.0
},
completion: completion
)
}
}
// MARK: - Animator
extension UIView {
func bottomToOrigin(duration: Double = 0.3, completion: (() -> Void)? = nil) {
let transform = CGAffineTransform(translationX: 0, y: self.bounds.height * 2)
self.transform = transform
// let velocity = self.bounds.height * CGFloat(duration)
UIView.animate(
withDuration:duration,
delay: duration,
usingSpringWithDamping: 0.85,
initialSpringVelocity: 2,
animations: {
let transform = CGAffineTransform(translationX: 0, y: 0)
self.transform = transform
},
completion: { _ in
completion?()
}
)
}
func originToBottom(duration: Double = 0.1, completion: @escaping () -> Void ) {
let transform = CGAffineTransform(translationX: 0, y: 0)
self.transform = transform
let animator = UIViewPropertyAnimator(
duration: duration,
curve: .linear) {
let transform = CGAffineTransform(translationX: 0, y: self.bounds.height * 2)
self.transform = transform
}
animator.addCompletion { _ in
completion()
}
animator.startAnimation()
}
func popUpBouncy(duration: Double = 0.1) {
alpha = 0.0
let transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
self.transform = transform
UIView.animate(
withDuration:duration,
delay: duration,
usingSpringWithDamping: 0.2,
initialSpringVelocity: 10,
animations: {
self.alpha = 1.0
let transform = CGAffineTransform(scaleX: 1, y: 1)
self.transform = transform
}
)
}
func animateHidden(isHidden: Bool, duration: Double = 0.5, completion: (() -> Void)? = nil) {
if self.isHidden {
self.isHidden = isHidden
UIView.animate(
withDuration: duration,
animations: {
self.alpha = isHidden ? 0 : 1
},
completion: { _ in
completion?()
}
)
} else {
UIView.animate(
withDuration: duration,
animations: {
self.alpha = isHidden ? 0 : 1
},
completion: { _ in
self.isHidden = isHidden
completion?()
}
)
}
// UIView.animate(withDuration: duration) {
// self.alpha = isHidden ? 0 : 1
// }
}
func travelSubView(block: (_ view: UIView, _ stop: inout Bool) -> Void) {
var stop = false
block(self, &stop)
if !stop {
self.subviews.forEach { $0.travelSubView(block: block) }
}
}
func rotate(duration: Double = 0.1, angle: CGFloat = .pi) {
let animator = UIViewPropertyAnimator(
duration: duration,
curve: .easeInOut
) {
self.transform = CGAffineTransform(rotationAngle: .pi)
}
animator.startAnimation()
}
}
// MARK: - FOR Badge
extension UIView {
/*
* Assign badge with only text.
*/
/// - parameter text: The badge value, use nil to remove exsiting badge.
@objc public func badge(text badgeText: String?) {
badge(text: badgeText, appearance: BadgeAppearance())
}
/// - parameter text: The badge value, use nil to remove exsiting badge.
/// - parameter appearance: The appearance of the badge.
public func badge(text badgeText: String?, appearance: BadgeAppearance) {
badge(text: badgeText, badgeEdgeInsets: nil, appearance: appearance)
}
/*
* Assign badge with text and edge insets.
*/
@available(*, deprecated, message: "Use badge(text: String?, appearance:BadgeAppearance)")
/// badge
///
/// - Parameters:
/// - badgeText: badge's Text
/// - badgeEdgeInsets: badge's Inset
@objc public func badge(text badgeText: String?, badgeEdgeInsets: UIEdgeInsets) {
badge(text: badgeText, badgeEdgeInsets: badgeEdgeInsets, appearance: BadgeAppearance())
}
/*
* Assign badge with text,insets, and appearance.
*/
public func badge (
text badgeText:String?,
badgeEdgeInsets: UIEdgeInsets?,
appearance: BadgeAppearance
) {
//Create badge label
var badgeLabel: BadgeLabel!
var doesBadgeExist = false
//Find badge in subviews if exists
for view in subviews {
if view.tag == 1, let label = view as? BadgeLabel {
badgeLabel = label
}
}
//If assigned text is nil (request to remove badge) and badge label is not nil:
if badgeText == nil && badgeLabel != nil {
if appearance.animate {
UIView.animate(
withDuration: appearance.duration,
animations: {
badgeLabel.alpha = 0.0
badgeLabel.transform = CGAffineTransform(scaleX: 0.1, y: 0.1)
},
completion: { _ in
badgeLabel.removeFromSuperview()
}
)
} else {
badgeLabel.removeFromSuperview()
}
return
} else if badgeText == nil && badgeLabel == nil {
return
}
//Badge label is nil (There was no previous badge)
if (badgeLabel == nil) {
//init badge label variable
badgeLabel = BadgeLabel()
//assign tag to badge label
badgeLabel.tag = 1
} else {
doesBadgeExist = true
}
let oldWidth: CGFloat? = doesBadgeExist ? badgeLabel.frame.width : nil
//Set the text on the badge label
badgeLabel.text = badgeText
//Set font size
badgeLabel.font = UIFont.systemFont(ofSize: appearance.textSize)
badgeLabel.sizeToFit()
//set the allignment
badgeLabel.textAlignment = appearance.textAlignment
//set background color
badgeLabel.layer.backgroundColor = appearance.backgroundColor.cgColor
//set text color
badgeLabel.textColor = appearance.textColor
//get current badge size
let badgeSize = badgeLabel.frame.size
//calculate width and height with minimum height and width of 20
let height = max(18, Double(badgeSize.height) + 5.0)
let width = max(height, Double(badgeSize.width) + 10.0)
badgeLabel.frame.size = CGSize(width: width, height: height)
//add to subview
if doesBadgeExist {
//remove view to delete constraints
badgeLabel.removeFromSuperview()
}
addSubview(badgeLabel)
//The distance from the center of the view (vertically)
let centerY =
appearance.distanceFromCenterY == 0 ? -(bounds.size.height / 2) : appearance.distanceFromCenterY
//The distance from the center of the view (horizontally)
let centerX =
appearance.distanceFromCenterX == 0 ? (bounds.size.width / 2) : appearance.distanceFromCenterX
//disable auto resizing mask
badgeLabel.translatesAutoresizingMaskIntoConstraints = false
//add height constraint
addConstraint(
NSLayoutConstraint(
item: badgeLabel!,
attribute: .height,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1.0,
constant: CGFloat(height)
)
)
//add width constraint
addConstraint(
NSLayoutConstraint(
item: badgeLabel!,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1.0,
constant: CGFloat(width)
)
)
//add vertical constraint
addConstraint(
NSLayoutConstraint(
item: badgeLabel!,
attribute: .centerX,
relatedBy: .equal,
toItem: self,
attribute: .centerX,
multiplier: 1.0,
constant: centerX
)
)
//add horizontal constraint
addConstraint(
NSLayoutConstraint(
item: badgeLabel!,
attribute: .centerY,
relatedBy: .equal,
toItem: self,
attribute: .centerY,
multiplier: 1.0,
constant: centerY
)
)
badgeLabel.layer.borderColor = appearance.borderColor.cgColor
badgeLabel.layer.borderWidth = appearance.borderWidth
//corner radius
badgeLabel.layer.cornerRadius = badgeLabel.frame.size.height / 2
//setup shadow
if appearance.allowShadow {
badgeLabel.layer.shadowOffset = CGSize(width: 1, height: 1)
badgeLabel.layer.shadowRadius = 1
badgeLabel.layer.shadowOpacity = 0.5
badgeLabel.layer.shadowColor = UIColor.black.cgColor
}
//badge does not exist, meaning we are adding a new one
if !doesBadgeExist {
//should it animate?
if appearance.animate {
badgeLabel.transform = CGAffineTransform(scaleX: 0, y: 0)
UIView.animate(
withDuration: appearance.duration,
delay: 0,
usingSpringWithDamping: 0.5,
initialSpringVelocity: 0.5,
options: [],
animations: {
badgeLabel.transform = .identity
},
completion: nil
)
}
} else {
if appearance.animate, let oldWidth = oldWidth {
let currentWidth = badgeLabel.frame.width
badgeLabel.frame.size.width = oldWidth
UIView.animate(withDuration: appearance.duration) {
badgeLabel.frame.size.width = currentWidth
}
}
}
}
}