Est-il possible pour un UIButton (ou tout autre contrôle d'ailleurs) de recevoir des événements tactiles lorsque le cadre de l'UIButton se trouve en dehors du cadre de son parent? Parce que lorsque j'essaye cela, mon UIButton ne semble pas pouvoir recevoir d'événements. Comment contourner ce problème?
92
Réponses:
Oui. Vous pouvez remplacer la
hitTest:withEvent:
méthode pour renvoyer une vue pour un ensemble de points plus grand que ce que contient cette vue. Consultez la référence de classe UIView .Edit: Exemple:
Edit 2: (Après clarification :) Afin de vous assurer que le bouton est traité comme étant dans les limites du parent, vous devez remplacer
pointInside:withEvent:
dans le parent pour inclure le cadre du bouton.Remarque le code juste là pour remplacer pointInside n'est pas tout à fait correct. Comme Summon l'explique ci-dessous, procédez comme suit:
Notez que vous le feriez très probablement avec
self.oversizeButton
un IBOutlet dans cette sous-classe UIView; alors vous pouvez simplement faire glisser le "bouton surdimensionné" en question, vers la vue spéciale en question. (Ou, si pour une raison quelconque vous faisiez beaucoup cela dans un projet, vous auriez une sous-classe UIButton spéciale, et vous pourriez regarder dans votre liste de sous-vues pour ces classes.) J'espère que cela vous aidera.la source
pointInside:withEvent:
pour inclure le cadre du bouton. Je vais ajouter un exemple de code à ma réponse ci-dessus.hitTest:withEvent:
et lapointInside:withEvent:
zone ne m'a pas appelé lorsque j'appuie sur un bouton qui se trouve en dehors des limites des parents. Qu'est-ce qui ne va pas?@jnic, je travaille sur iOS SDK 5.0 et pour que votre code fonctionne correctement, je devais faire ceci:
La vue conteneur dans mon cas est un UIButton et tous les éléments enfants sont également des UIButtons qui peuvent se déplacer en dehors des limites de l'UIButton parent.
Meilleur
la source
Dans la vue parent, vous pouvez remplacer la méthode de test de positionnement:
Dans ce cas, si le point se situe dans les limites de votre bouton, vous y transférez l'appel; sinon, revenez à l'implémentation d'origine.
la source
Dans mon cas, j'avais une
UICollectionViewCell
sous-classe qui contenait un fichierUIButton
. J'ai désactivéclipsToBounds
la cellule et le bouton était visible en dehors des limites de la cellule. Cependant, le bouton ne recevait pas d'événements tactiles. J'ai pu détecter les événements tactiles sur le bouton en utilisant la réponse de Jack: https://stackoverflow.com/a/30431157/3344977Voici une version Swift:
Swift 4:
la source
Pourquoi cela se produit-il?
En effet, lorsque votre sous-vue se trouve en dehors des limites de votre supervision, les événements tactiles qui se produisent réellement sur cette sous-vue ne seront pas livrés à cette sous-vue. Cependant, il FERA être livré à son superview.
Qu'as tu besoin de faire?
Lorsque votre superview reçoit l'événement tactile mentionné ci-dessus, vous devrez indiquer explicitement à UIKit que ma sous-vue doit être celle qui recevra cet événement tactile.
Et le code?
Dans votre supervision, implémentez
func hitTest(_ point: CGPoint, with event: UIEvent?)
Gotchya fascinant: vous devez aller à la "vue la plus haute trop petite"
Vous devez aller "vers le haut" jusqu'à la vue "la plus élevée" à laquelle la vue du problème se trouve à l'extérieur.
Exemple typique:
Supposons que vous ayez un écran S, avec une vue conteneur C.La vue du contrôleur de vue conteneur est V. (Rappelez-vous que V sera placé à l'intérieur de C et aura la même taille.) V a une sous-vue (peut-être un bouton) B.B est le problème vue qui est en fait en dehors de V.
Mais notez que B est également en dehors de C.
Dans cet exemple , vous devez appliquer la solution
override hitTest
en fait à C, et non à V . Si vous l'appliquez à V - cela ne fait rien.la source
Rapide:
Où targetView est la vue que vous souhaitez recevoir l'événement (qui peut être entièrement ou partiellement situé en dehors du cadre de sa vue parente).
la source
Pour moi (comme pour les autres), la réponse n'était pas de remplacer la
hitTest
méthode, mais plutôt lapointInside
méthode. Je devais le faire à seulement deux endroits.Le Superview C'est l'opinion que si elle avait été
clipsToBounds
mise à vrai, cela ferait disparaître tout ce problème. Alors, voici mon simpleUIView
dans Swift 3:La sous-vue Votre kilométrage peut varier, mais dans mon cas, j'ai également dû remplacer la
pointInside
méthode de la sous-vue qui avait décidé que le toucher était hors limites. Le mien est en Objective-C, donc:Cette réponse (et quelques autres sur la même question) peut vous aider à éclaircir votre compréhension.
la source
swift 4.1 mis à jour
Pour obtenir des événements tactiles dans le même UIView, il vous suffit d'ajouter la méthode de remplacement suivante, elle identifiera la vue spécifique tapée dans UIView qui est placée hors des limites
la source