user3745635
user3745635

Reputation: 955

Trying to replicate iOS style notification inside the application, but animation is not working

I am working on an application which highly depends on notifications like chat applications but it's not actually a chat application.

What I am trying to do is whenever a user receives a push notification on the device while he/she is using the application a notification inside the application is created. This is a very common feature in chat applications.

Where I had reached -

I am able to create a box on top of the application with the details which I want to show the information send via push notification and designed the way I wanted to design it.

The problem I am facing -

I want it to work in a way like it appears with an animation from the top and then it collapses after 2 seconds with an animation but none of the animations is working and I can't proceed with it.

Code flow-

UIViewController+Extensions

func showInlineNotification(header: String, message: String) {

    let window = UIApplication.shared.keyWindow
    let notificationView = UIView(frame: CGRect.zero)
    notificationView.backgroundColor = .lightGray
    let heading = UILabel(frame: .zero)
    let messageLabel = UILabel(frame: .zero)
    heading.textColor = UIColor.black
    messageLabel.textColor = UIColor.black
    heading.text = header
    messageLabel.text = message
    notificationView.addSubview(heading)
    notificationView.addSubview(messageLabel)
    heading.translatesAutoresizingMaskIntoConstraints = false
    messageLabel.translatesAutoresizingMaskIntoConstraints = false
    messageLabel.numberOfLines = 0

    notificationView.layer.cornerRadius = 20
    notificationView.clipsToBounds = true
    window?.addSubview(notificationView)
    notificationView.translatesAutoresizingMaskIntoConstraints = false


    self.view.bringSubview(toFront: notificationView)


    self.view.topAnchor.constraint(equalTo: notificationView.topAnchor, constant: -20).isActive = true
    self.view.leftAnchor.constraint(equalTo: notificationView.leftAnchor, constant: 0).isActive = true
    self.view.rightAnchor.constraint(equalTo: notificationView.rightAnchor, constant: 0).isActive = true
    let heightConstraint = NSLayoutConstraint(item: self.view, attribute: .height, relatedBy: .equal, toItem: notificationView, attribute: .height, multiplier: 2, constant: 0)
    heightConstraint.isActive = true


        notificationView.topAnchor.constraint(equalTo: heading.topAnchor, constant: -20).isActive = true
        notificationView.leftAnchor.constraint(equalTo: heading.leftAnchor, constant: -8).isActive = true
        notificationView.rightAnchor.constraint(equalTo: heading.rightAnchor, constant: -8).isActive = true

        heading.leftAnchor.constraint(equalTo: messageLabel.leftAnchor, constant: 0).isActive = true
        heading.rightAnchor.constraint(equalTo: messageLabel.rightAnchor, constant: 0).isActive = true

        NSLayoutConstraint(item: heading, attribute: .bottom, relatedBy: .equal, toItem: messageLabel, attribute: .top, multiplier: 1, constant: 4).isActive = true



        UIView.animate(withDuration: 4.0, delay: 2, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.2, options: [.curveLinear], animations: {
                heightConstraint.constant = 200

            self.view.layoutIfNeeded()
        }, completion: { (completed) in
            print("animation completed")

        })




}

The function is called on a view controller whenever a push notification is received and that functionality is achieved via Notifications.

Upvotes: 1

Views: 402

Answers (1)

Shehata Gamal
Shehata Gamal

Reputation: 100503

Here you give the notificationView 1/2 height of self.view

let heightConstraint = NSLayoutConstraint(item: self.view, attribute: .height, relatedBy: .equal, toItem: notificationView, attribute: .height, multiplier: 2, constant: 0)
heightConstraint.isActive = true

despite it's height should be content-dependent , so you need to remove that constraint and hook the bottom of the messagelb to notificationView's bottom constraint like this

messageLabel.bottomAnchor.constraint(equalTo: notificationView.bottomAnchor, constant: 0).isActive = true

//

plus you need first to set bottom of notificationView to top of self.view ( To make it slide from top to bottom ) by

1-

notificationView.bottomAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true

2- then remove it and add this

notificationView.topAnchor.constraint(equalTo: view.topAnchor, constant: 0).isActive = true

//

inside animation block only should be

self.view.layoutIfNeeded()

//

You may do something like this

func showInlineNotification(header: String, message: String) {

        let window = UIApplication.shared.keyWindow
        let notificationView = UIView(frame: CGRect.zero)
        notificationView.backgroundColor = .lightGray
        let heading = UILabel(frame: .zero)
        let messageLabel = UILabel(frame: .zero)
        heading.textColor = UIColor.black
        messageLabel.textColor = UIColor.black
        heading.text = header
        messageLabel.text = message
        notificationView.addSubview(heading)
        notificationView.addSubview(messageLabel)
        heading.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.translatesAutoresizingMaskIntoConstraints = false
        messageLabel.numberOfLines = 0

        notificationView.layer.cornerRadius = 20
        notificationView.clipsToBounds = true
        window?.addSubview(notificationView)
        notificationView.translatesAutoresizingMaskIntoConstraints = false


        self.view.bringSubview(toFront: notificationView)


        let botCon = self.view.topAnchor.constraint(equalTo: notificationView.bottomAnchor, constant: 0)
        botCon.isActive = true
        self.view.leftAnchor.constraint(equalTo: notificationView.leftAnchor, constant: 0).isActive = true
        self.view.rightAnchor.constraint(equalTo: notificationView.rightAnchor, constant: 0).isActive = true


        notificationView.topAnchor.constraint(equalTo: heading.topAnchor, constant: -20).isActive = true
        notificationView.leftAnchor.constraint(equalTo: heading.leftAnchor, constant: -8).isActive = true
        notificationView.rightAnchor.constraint(equalTo: heading.rightAnchor, constant: -8).isActive = true

        heading.leftAnchor.constraint(equalTo: messageLabel.leftAnchor, constant: 0).isActive = true
        heading.rightAnchor.constraint(equalTo: messageLabel.rightAnchor, constant: 0).isActive = true
        messageLabel.topAnchor.constraint(equalTo: messageLabel.headingAnchor, constant: 4).isActive = true
        messageLabel.bottomAnchor.constraint(equalTo: messageLabel.bottomAnchor, constant: 0).isActive = true

        self.view.layoutIfNeeded()

        botCon.constant = -1 * notificationView.bounds.height

        UIView.animate(withDuration: 4.0, delay: 2, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.2, options: [.curveLinear], animations: {

            self.view.layoutIfNeeded()

        }, completion: { (completed) in
            print("animation completed")

        })


}

Upvotes: 1

Related Questions