Daltron / NotificationBanner

The easiest way to display highly customizable in app notification banners in iOS
MIT License
4.78k stars 662 forks source link

Receiving tap events from leftView and/or rightView #298

Closed skhillon closed 4 years ago

skhillon commented 4 years ago

Problem

I'm using the notification banner to show text directions, and I've added arrows to the leftView and rightView, respectively:

IMG_351EFBAC5316-1

I want to perform an action when one of the subviews is tapped, but those actions are not being fired. I've tried adding a UITapGestureRecognizer to each subview, but it seems that the banner is swallowing all touch events. How can I detect whether the left or the right arrow was tapped and perform an action?

Code

Creating the tappable UIImageView

extension UIImageView {
  static func makeTappableImageView(icon: UIImage, action: Selector) -> UIImageView {
    let imageView = UIImageView(image: icon)
    let tapGesture = UITapGestureRecognizer(target: imageView, action: action)
    imageView.addGestureRecognizer(tapGesture)
    return imageView
  }
}

Creating the FloatingNotificationBanner

extension FloatingNotificationBanner {
  static func makeDirectionsBanner(
    subtitle: String?,
    onLeftArrowTapped: Selector? = nil,
    onRightArrowTapped: Selector? = nil
  ) -> FloatingNotificationBanner {
    guard let subtitle = subtitle else { return FloatingNotificationBanner() }

    var leftView: UIView?
    if let leftArrowAction = onLeftArrowTapped {
      leftView = UIImageView.makeTappableImageView(icon: Constants.Icons.leftArrow, action: leftArrowAction)
    }

    var rightView: UIView?
    if let rightArrowAction = onRightArrowTapped {
      rightView = UIImageView.makeTappableImageView(icon: Constants.Icons.rightArrow, action: rightArrowAction)
    }

    let banner = FloatingNotificationBanner(
      subtitle: subtitle,
      subtitleFont: UIFont.systemFont(ofSize: UIFont.systemFontSize),
      subtitleColor: .white,
      subtitleTextAlign: .left,
      leftView: leftView,
      rightView: rightView
    )
    banner.backgroundColor = .green
    banner.autoDismiss = false
    return banner
  }
}

Call Site

      let directionsBanner = FloatingNotificationBanner.makeDirectionsBanner(
        subtitle: directions,
        onLeftArrowTapped: #selector(self.leftArrowAction),
        onRightArrowTapped: #selector(self.rightArrowAction)
      )
skhillon commented 4 years ago

I realized that a UIButton already does what I'm trying to do, so I switched out the imageViews with buttons and now they correctly receive touch events.