Pavel Zorin
Pavel Zorin

Reputation: 11

Secondary click (TrackPad) and right click (mouse) don't work on Mac M1 (Designed for iPad)

In the application, we need an action (pop-up menu) to open when clicked:

We did as described in this post. The result is the following class:

class SecondaryActionInteraction: NSObject, UIInteraction {
    weak var target: AnyObject?
    var action: Selector
    
    private(set) weak var view: UIView?

    init(target: AnyObject, action: Selector) {
        self.target = target
        self.action = action
    }
    
    private lazy var oneTapGestureRecognizer = UITapGestureRecognizer(
        target: self,
        action: #selector(handlePrimaryClick)
    )

    private var gestureRecognizersList: [UIGestureRecognizer] {
        var recognizers: [UIGestureRecognizer] = [oneTapGestureRecognizer]
        if #available(iOS 13.4, *) {
            let twoTapGestureRecognizer: UITapGestureRecognizer = {
                let recognizer = UITapGestureRecognizer(
                    target: self,
                    action: #selector(handleSecondaryClick)
                )
                recognizer.allowedTouchTypes_ = [.indirectPointer]
                recognizer.buttonMaskRequired = .secondary
                return recognizer
            }()
            recognizers.append(twoTapGestureRecognizer)
        }
        return recognizers
    }

    func willMove(to newView: UIView?) {
        guard let oldView = self.view else {
            return;
        }

        for recognizer in gestureRecognizersList {
            oldView.removeGestureRecognizer(recognizer)
        }
    }

    func didMove(to newView: UIView?) {
        self.view = newView

        guard let newView = newView else {
            return
        }

        for recognizer in gestureRecognizersList {
            newView.addGestureRecognizer(recognizer)
        }
    }
    
    @objc private func handlePrimaryClick() {
        sendActions()
    }

    @objc private func handleSecondaryClick() {
        sendActions()
    }

    private func sendActions() {
        UIApplication.shared.sendAction(action, to: target, from: self, for: nil)
    }
}

extension UIGestureRecognizer {
    var allowedTouchTypes_: [UITouch.TouchType] {
        get {
            allowedTouchTypes.map { nsNumber -> UITouch.TouchType in
                UITouch.TouchType(rawValue: nsNumber.intValue)!
            }
        }
        set {
            allowedTouchTypes = newValue.map { type -> NSNumber in
                NSNumber(value: type.rawValue)
            }
        }
    }
}

Added to Info.plist

UIApplicationSupportsIndirectInputEvents = YES

Assigned this interaction to a view:

let tapActionInteraction = SecondaryActionInteraction(target: self, action: #selector(onTapAction))

view.addInteraction(tapActionInteraction)

As a result:

twoTapGestureRecognizer only worked when pressing Left Mouse Button + Control. But this is not what we expected.

Any ideas what we did wrong?

Upvotes: 1

Views: 65

Answers (0)

Related Questions