1.7 C
New York
Saturday, January 11, 2025

ios – UISwipeGestureRecognizer Not Triggering Constantly on a Customized UIView with Blur Impact


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.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles