2

I saw a cool feature on YouTube for playing instream ads directly in the system pip
I wanted to repeat their functionality. I was able to add a regular UILabel, but I had problems with the UIButton. The event of clicking on the "Skip" button is not processed
Please tell me how to add the button correctly and handle the event of clicking on it

The YouTube feature is shown in the screenshot

private lazy var button: UIButton = {
    let button = UIButton()
    button.setTitle("Skip", for: .normal)
    button.backgroundColor = .gray
    button.tintColor = .white
    button.translatesAutoresizingMaskIntoConstraints = false
    button.isUserInteractionEnabled = true
    button.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
    return button
}()

@objc
private func handleTap() {
    print("TEST")
}
func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
    if let window = UIApplication.shared.windows.first {
        window.addSubview(button)
        window.bringSubviewToFront(button)
        NSLayoutConstraint.activate([
            button.trailingAnchor.constraint(equalTo: window.trailingAnchor, constant: -16),
            button.bottomAnchor.constraint(equalTo: window.bottomAnchor, constant: -16),
        ])
    }
}
New contributor
Герман Кунин is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
2
  • If you add a working piece of code that roughly shows what you already implemented it is much easier to tell what went wrong compared to only having your words and nothing else :) Commented Nov 26 at 9:05
  • 1
    I agree, I added the main pieces of code. I repeat, the button is displayed, but the handleTap method is not triggered Thank you :) Commented Nov 26 at 9:10

1 Answer 1

0

Use a tap gesture recognizer on the window itself and handle the hit testing manually:

private lazy var button: UIButton = {
    let button = UIButton()
    button.setTitle("Skip", for: .normal)
    button.backgroundColor = .gray
    button.tintColor = .white
    button.translatesAutoresizingMaskIntoConstraints = false
    button.isUserInteractionEnabled = true
    return button
}()

private lazy var tapGesture: UITapGestureRecognizer = {
    let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
    return gesture
}()

@objc private func handleTap(_ gesture: UITapGestureRecognizer) {
    let location = gesture.location(in: button)
    if button.bounds.contains(location) {
        print("TEST - Button tapped!")
        // Handle skip action here
    }
}

func pictureInPictureControllerWillStartPictureInPicture(_ pictureInPictureController: AVPictureInPictureController) {
    if let window = UIApplication.shared.windows.first {
        window.addSubview(button)
        window.addGestureRecognizer(tapGesture)
        window.bringSubviewToFront(button)
        
        NSLayoutConstraint.activate([
            button.trailingAnchor.constraint(equalTo: window.trailingAnchor, constant: -20),
            button.bottomAnchor.constraint(equalTo: window.bottomAnchor, constant: -100)
        ])
    }
}

This works because the tap gesture is on the window, which is always in the responder chain, and we manually check if the tap was on the button's bounds.

Sign up to request clarification or add additional context in comments.

1 Comment

It looked good, but in fact the handleTap method was never called. I copied your code completely. I also made DebugButton class for debugging. The point(inside: with:) method was never called too class DebugButton: UIButton { override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { print("TEST - point inside method") return super.point(inside: point, with: event) } } Of course, I replaced the initialization of the button from UIButton to DebugButton. Sorry, I'm new to this forum. I don't know how to insert the code in the comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.