I am constructing a customized notification system for my iOS app the place non permanent notification views are displayed on high of the display screen. These views have a layered construction with a UIVisualEffectView for a blur impact and a content material view containing icons and textual content.
I need customers to dismiss the notification by swiping down. I’ve efficiently discovered that the swipe gestures are being added to the views, however by some means, the swipes should not being detected, not even faucets or pan gestures.
The swipe gesture typically fails to set off constantly. Under is the related code:
class NotificationViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
tremendous.viewDidLoad()
view.backgroundColor = .white
// Present a notification after 1 second
DispatchQueue.fundamental.asyncAfter(deadline: .now() + 1.0) {
self.showNotification(message: "Swipe all the way down to dismiss!")
}
}
func showNotification(message: String) {
let notificationView = createNotificationView(message: message)
view.addSubview(notificationView)
positionNotification(notificationView, above: nil)
// Mechanically dismiss after 3 seconds
DispatchQueue.fundamental.asyncAfter(deadline: .now() + 3.0) {
self.dismissNotification(notificationView)
}
}
non-public func createNotificationView(message: String) -> UIView {
// Create the notification view
let notificationView = UIView()
notificationView.backgroundColor = .clear
notificationView.layer.cornerRadius = 12
notificationView.layer.borderWidth = 1
notificationView.layer.borderColor = UIColor.darkGray.cgColor
notificationView.translatesAutoresizingMaskIntoConstraints = false
notificationView.isUserInteractionEnabled = true
// Add blur impact
let blurEffect = UIBlurEffect(fashion: .systemChromeMaterial)
let blurEffectView = UIVisualEffectView(impact: blurEffect)
blurEffectView.body = notificationView.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurEffectView.isUserInteractionEnabled = false
notificationView.addSubview(blurEffectView)
// Add content material to the blur impact view
let label = UILabel()
label.textual content = message
label.textColor = .label
label.textAlignment = .heart
label.translatesAutoresizingMaskIntoConstraints = false
blurEffectView.contentView.addSubview(label)
NSLayoutConstraint.activate([
label.centerXAnchor.constraint(equalTo: blurEffectView.contentView.centerXAnchor),
label.centerYAnchor.constraint(equalTo: blurEffectView.contentView.centerYAnchor)
])
// Add swipe gesture recognizer
let swipeGesture = UISwipeGestureRecognizer(goal: self, motion: #selector(handleSwipe(_:)))
swipeGesture.route = .down
swipeGesture.delegate = self
notificationView.addGestureRecognizer(swipeGesture)
return notificationView
}
non-public func positionNotification(_ notificationView: UIView, above previousNotificationView: UIView?) {
notificationView.translatesAutoresizingMaskIntoConstraints = false
if let previousView = previousNotificationView {
NSLayoutConstraint.activate([
notificationView.bottomAnchor.constraint(equalTo: previousView.topAnchor, constant: -10),
notificationView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
notificationView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
notificationView.heightAnchor.constraint(equalToConstant: 60)
])
} else {
NSLayoutConstraint.activate([
notificationView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 60),
notificationView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
notificationView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.9),
notificationView.heightAnchor.constraint(equalToConstant: 60)
])
}
}
@objc non-public func handleSwipe(_ gesture: UISwipeGestureRecognizer) {
guard let notificationView = gesture.view else { return }
print("Swipe detected on notification!")
dismissNotification(notificationView)
}
non-public func dismissNotification(_ notificationView: UIView) {
UIView.animate(withDuration: 0.3, animations: {
notificationView.alpha = 0
}) { _ in
notificationView.removeFromSuperview()
}
}
}
Identical strategy has been working for different views, however they have been declared on the father or mother class degree, whereas this “notification view” is one thing that’s initialized inside a operate, however the values and every thing else works properly. This could have labored, so I’m not certain what I’m lacking.
Would love some recommendation.