Reputation: 955
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
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