Skip to content

Instantly share code, notes, and snippets.

@damodarnamala
Created January 20, 2022 13:54
Show Gist options
  • Select an option

  • Save damodarnamala/3bbbadd788cf11deaf9ada4b033a328e to your computer and use it in GitHub Desktop.

Select an option

Save damodarnamala/3bbbadd788cf11deaf9ada4b033a328e to your computer and use it in GitHub Desktop.
Shadow Toast View Bottom
struct ContentView: View {
var body: some View {
ZStack {
Color.banescoBackground.ignoresSafeArea()
VStack {
Spacer()
Text("this is a convenient way to create this view controller without a imageURL this is a convenient way to create this view controller without a imageURL thing went worg.!")
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
UIViewController.showToast("this is a convenient way to create this view controller without a imageURL this is a convenient way to create this view controller without a imageURL thing went worg.!!")
}
}
}
}
extension Color {
static let banescoBackground = Color("banescoBackground")
static let banescoGreen = Color("banescoGreen")
}
extension UIColor {
static let banescoGreen = #colorLiteral(red: 0, green: 0.4745098039, blue: 0.3215686275, alpha: 1)
}
class ToastViewController: UIView {
// this is a convenient way to create this view controller without a imageURL
convenience init() {
self.init(message: "")
}
init(message: String) {
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
let label = PaddingLabel()
addSubview(label)
label.translatesAutoresizingMaskIntoConstraints = false
label.text = message
label.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
label.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
label.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
label.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
label.textAlignment = .center
label.numberOfLines = 0
label.textColor = UIColor.banescoGreen
self.backgroundColor = UIColor.white.withAlphaComponent(0.96)
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.removeFromSuperview()
}
}
override func layoutSubviews() {
shadows()
self.zoomInOutAminate()
}
func shadows() {
self.layer.cornerRadius = 8
self.layer.shadowOpacity = 0.2
self.layer.shadowRadius = 8
self.layer.shadowOffset = CGSize.zero
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowPath = UIBezierPath(roundedRect: self.bounds, cornerRadius: self.layer.cornerRadius).cgPath
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
}
extension UIViewController {
static func showToast(_ message: String) {
let controller = ToastViewController(message: message)
guard let keyWindow = UIApplication.shared.connectedScenes
.filter({$0.activationState == .foregroundActive})
.map({$0 as? UIWindowScene})
.compactMap({$0})
.first?.windows
.filter({$0.isKeyWindow}).first else {return}
keyWindow.addSubview(controller)
controller.leadingAnchor.constraint(equalTo: keyWindow.leadingAnchor, constant: 16).isActive = true
controller.trailingAnchor.constraint(equalTo: keyWindow.trailingAnchor, constant: -16).isActive = true
controller.safeBottomAnchor.constraint(greaterThanOrEqualTo: keyWindow.safeBottomAnchor).isActive = true
controller.heightAnchor.constraint(greaterThanOrEqualToConstant: 34).isActive = true
controller.centerXAnchor.constraint(equalTo: keyWindow.centerXAnchor).isActive = true
}
}
extension UIView {
var safeTopAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return safeAreaLayoutGuide.topAnchor
}
return topAnchor
}
var safeLeftAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return safeAreaLayoutGuide.leftAnchor
}
return leftAnchor
}
var safeRightAnchor: NSLayoutXAxisAnchor {
if #available(iOS 11.0, *){
return safeAreaLayoutGuide.rightAnchor
}
return rightAnchor
}
var safeBottomAnchor: NSLayoutYAxisAnchor {
if #available(iOS 11.0, *) {
return safeAreaLayoutGuide.bottomAnchor
}
return bottomAnchor
}
}
class PaddingLabel: UILabel {
var topInset: CGFloat = 16
var bottomInset: CGFloat = 16
var leftInset: CGFloat = 16
var rightInset: CGFloat = 16
override func drawText(in rect: CGRect) {
let insets = UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
super.drawText(in: rect.inset(by: insets))
}
override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
return CGSize(width: size.width + leftInset + rightInset,
height: size.height + topInset + bottomInset)
}
override var bounds: CGRect {
didSet {
// ensures this works within stack views if multi-line
preferredMaxLayoutWidth = bounds.width - (leftInset + rightInset)
}
}
}
extension UIView {
func zoomInOutAminate() {
UIView.animate(withDuration: 0.5, delay: 0.0, options: .curveEaseOut, animations: {
self.transform = CGAffineTransform.identity.scaledBy(x: 0.85, y: 0.85) // Scale your image
}) { (finished) in
UIView.animate(withDuration: 1, animations: { [weak self] in
self?.transform = CGAffineTransform.identity // undo in 1 seconds
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment