Created
January 20, 2022 13:54
-
-
Save damodarnamala/3bbbadd788cf11deaf9ada4b033a328e to your computer and use it in GitHub Desktop.
Shadow Toast View Bottom
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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