Make view draggable but not tappable












2















I have a label in my view controller that I set like this in viewDidLoad:



var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel()
view.add(label)
label.frame = CGRect(x: 0, y, 0, width: 20, height: 20)
label.text = "A"

let recognizer = UIPanGestureRecognizer(target: self, action: #selector(didDrag(_:))
label.addGestureRecognizer(recognizer)
label.isUserInteractionEnabled = true
}


I want the label to be draggable, so I implemented didDrag like this:



@objc func didDrag(_ gesture: UIPanGestureRecognizer) {
let center = label.center
let translation = gesture.translation(in: view)
label.center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}


It works perfectly and I can drag my label around.



However, if the label is over a button in my view and I try to tap the button, the button does not get the touch. I have tried:



label.isUserInteractionEnabled = false // then I can't also drag around
recognizer.cancelsTouchesInView = false // nothing changes
label.isMultipleTouchEnabled = false // nothing changes


Any idea how I can let single or double taps be passed/be ignored by the label's pan recognisers, but still be able to drag it?



I can delete this question if it's a duplicate, but I have not found any other that asks exactly the same.



Edit



Following Pass taps through a UIPanGestureRecognizer, the closest question I've found so far, I also tried:



recognizer.delaysTouchesBegan = true
recognizer.maximumNumberOfTouches = 1
recognizer.cancelsTouchesInView = true


But it, unfortunately, did not work.



Update
The view has all sorts of button and textfields, so comparing with each of them is not really possible, mostly because there are also stack views that contain buttons and sometimes they are there and somethings they are not.










share|improve this question

























  • cancelsTouchesInView = true is default behavior, try set it to false

    – inokey
    Nov 21 '18 at 15:32













  • Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

    – regina_fallangi
    Nov 21 '18 at 15:39
















2















I have a label in my view controller that I set like this in viewDidLoad:



var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel()
view.add(label)
label.frame = CGRect(x: 0, y, 0, width: 20, height: 20)
label.text = "A"

let recognizer = UIPanGestureRecognizer(target: self, action: #selector(didDrag(_:))
label.addGestureRecognizer(recognizer)
label.isUserInteractionEnabled = true
}


I want the label to be draggable, so I implemented didDrag like this:



@objc func didDrag(_ gesture: UIPanGestureRecognizer) {
let center = label.center
let translation = gesture.translation(in: view)
label.center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}


It works perfectly and I can drag my label around.



However, if the label is over a button in my view and I try to tap the button, the button does not get the touch. I have tried:



label.isUserInteractionEnabled = false // then I can't also drag around
recognizer.cancelsTouchesInView = false // nothing changes
label.isMultipleTouchEnabled = false // nothing changes


Any idea how I can let single or double taps be passed/be ignored by the label's pan recognisers, but still be able to drag it?



I can delete this question if it's a duplicate, but I have not found any other that asks exactly the same.



Edit



Following Pass taps through a UIPanGestureRecognizer, the closest question I've found so far, I also tried:



recognizer.delaysTouchesBegan = true
recognizer.maximumNumberOfTouches = 1
recognizer.cancelsTouchesInView = true


But it, unfortunately, did not work.



Update
The view has all sorts of button and textfields, so comparing with each of them is not really possible, mostly because there are also stack views that contain buttons and sometimes they are there and somethings they are not.










share|improve this question

























  • cancelsTouchesInView = true is default behavior, try set it to false

    – inokey
    Nov 21 '18 at 15:32













  • Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

    – regina_fallangi
    Nov 21 '18 at 15:39














2












2








2








I have a label in my view controller that I set like this in viewDidLoad:



var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel()
view.add(label)
label.frame = CGRect(x: 0, y, 0, width: 20, height: 20)
label.text = "A"

let recognizer = UIPanGestureRecognizer(target: self, action: #selector(didDrag(_:))
label.addGestureRecognizer(recognizer)
label.isUserInteractionEnabled = true
}


I want the label to be draggable, so I implemented didDrag like this:



@objc func didDrag(_ gesture: UIPanGestureRecognizer) {
let center = label.center
let translation = gesture.translation(in: view)
label.center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}


It works perfectly and I can drag my label around.



However, if the label is over a button in my view and I try to tap the button, the button does not get the touch. I have tried:



label.isUserInteractionEnabled = false // then I can't also drag around
recognizer.cancelsTouchesInView = false // nothing changes
label.isMultipleTouchEnabled = false // nothing changes


Any idea how I can let single or double taps be passed/be ignored by the label's pan recognisers, but still be able to drag it?



I can delete this question if it's a duplicate, but I have not found any other that asks exactly the same.



Edit



Following Pass taps through a UIPanGestureRecognizer, the closest question I've found so far, I also tried:



recognizer.delaysTouchesBegan = true
recognizer.maximumNumberOfTouches = 1
recognizer.cancelsTouchesInView = true


But it, unfortunately, did not work.



Update
The view has all sorts of button and textfields, so comparing with each of them is not really possible, mostly because there are also stack views that contain buttons and sometimes they are there and somethings they are not.










share|improve this question
















I have a label in my view controller that I set like this in viewDidLoad:



var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
label = UILabel()
view.add(label)
label.frame = CGRect(x: 0, y, 0, width: 20, height: 20)
label.text = "A"

let recognizer = UIPanGestureRecognizer(target: self, action: #selector(didDrag(_:))
label.addGestureRecognizer(recognizer)
label.isUserInteractionEnabled = true
}


I want the label to be draggable, so I implemented didDrag like this:



@objc func didDrag(_ gesture: UIPanGestureRecognizer) {
let center = label.center
let translation = gesture.translation(in: view)
label.center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
gesture.setTranslation(.zero, in: view)
}


It works perfectly and I can drag my label around.



However, if the label is over a button in my view and I try to tap the button, the button does not get the touch. I have tried:



label.isUserInteractionEnabled = false // then I can't also drag around
recognizer.cancelsTouchesInView = false // nothing changes
label.isMultipleTouchEnabled = false // nothing changes


Any idea how I can let single or double taps be passed/be ignored by the label's pan recognisers, but still be able to drag it?



I can delete this question if it's a duplicate, but I have not found any other that asks exactly the same.



Edit



Following Pass taps through a UIPanGestureRecognizer, the closest question I've found so far, I also tried:



recognizer.delaysTouchesBegan = true
recognizer.maximumNumberOfTouches = 1
recognizer.cancelsTouchesInView = true


But it, unfortunately, did not work.



Update
The view has all sorts of button and textfields, so comparing with each of them is not really possible, mostly because there are also stack views that contain buttons and sometimes they are there and somethings they are not.







ios swift uipangesturerecognizer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 '18 at 10:36







regina_fallangi

















asked Nov 21 '18 at 15:19









regina_fallangiregina_fallangi

851723




851723













  • cancelsTouchesInView = true is default behavior, try set it to false

    – inokey
    Nov 21 '18 at 15:32













  • Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

    – regina_fallangi
    Nov 21 '18 at 15:39



















  • cancelsTouchesInView = true is default behavior, try set it to false

    – inokey
    Nov 21 '18 at 15:32













  • Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

    – regina_fallangi
    Nov 21 '18 at 15:39

















cancelsTouchesInView = true is default behavior, try set it to false

– inokey
Nov 21 '18 at 15:32







cancelsTouchesInView = true is default behavior, try set it to false

– inokey
Nov 21 '18 at 15:32















Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

– regina_fallangi
Nov 21 '18 at 15:39





Just tried recognizer.cancelsTouchesInView = false. Still nothing changes. Thanks, though.

– regina_fallangi
Nov 21 '18 at 15:39












1 Answer
1






active

oldest

votes


















0














After thinking I came up with the solution that might work. The idea is playing around with touch events. Every view has a set of methods like touchesBegan(), touchesMoved() etc. Now what you can do is when touchesBegan is invoked you can check the location of the touch that is happening and if this location contained in the frame of the button, call the function manually.



Here's the pseudocode so you get the concept. Not tested but from my experience something like that should work



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touches.forEach { touch in
let touchLocation = touch.location(in: myButton) // that may need to be self instead of myButton
if myButton.frame.contains($0.location) {
//invoke button method here
}
}
}





share|improve this answer
























  • I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

    – regina_fallangi
    Nov 21 '18 at 18:03











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415202%2fmake-view-draggable-but-not-tappable%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














After thinking I came up with the solution that might work. The idea is playing around with touch events. Every view has a set of methods like touchesBegan(), touchesMoved() etc. Now what you can do is when touchesBegan is invoked you can check the location of the touch that is happening and if this location contained in the frame of the button, call the function manually.



Here's the pseudocode so you get the concept. Not tested but from my experience something like that should work



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touches.forEach { touch in
let touchLocation = touch.location(in: myButton) // that may need to be self instead of myButton
if myButton.frame.contains($0.location) {
//invoke button method here
}
}
}





share|improve this answer
























  • I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

    – regina_fallangi
    Nov 21 '18 at 18:03
















0














After thinking I came up with the solution that might work. The idea is playing around with touch events. Every view has a set of methods like touchesBegan(), touchesMoved() etc. Now what you can do is when touchesBegan is invoked you can check the location of the touch that is happening and if this location contained in the frame of the button, call the function manually.



Here's the pseudocode so you get the concept. Not tested but from my experience something like that should work



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touches.forEach { touch in
let touchLocation = touch.location(in: myButton) // that may need to be self instead of myButton
if myButton.frame.contains($0.location) {
//invoke button method here
}
}
}





share|improve this answer
























  • I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

    – regina_fallangi
    Nov 21 '18 at 18:03














0












0








0







After thinking I came up with the solution that might work. The idea is playing around with touch events. Every view has a set of methods like touchesBegan(), touchesMoved() etc. Now what you can do is when touchesBegan is invoked you can check the location of the touch that is happening and if this location contained in the frame of the button, call the function manually.



Here's the pseudocode so you get the concept. Not tested but from my experience something like that should work



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touches.forEach { touch in
let touchLocation = touch.location(in: myButton) // that may need to be self instead of myButton
if myButton.frame.contains($0.location) {
//invoke button method here
}
}
}





share|improve this answer













After thinking I came up with the solution that might work. The idea is playing around with touch events. Every view has a set of methods like touchesBegan(), touchesMoved() etc. Now what you can do is when touchesBegan is invoked you can check the location of the touch that is happening and if this location contained in the frame of the button, call the function manually.



Here's the pseudocode so you get the concept. Not tested but from my experience something like that should work



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
touches.forEach { touch in
let touchLocation = touch.location(in: myButton) // that may need to be self instead of myButton
if myButton.frame.contains($0.location) {
//invoke button method here
}
}
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 '18 at 17:57









inokeyinokey

1,100818




1,100818













  • I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

    – regina_fallangi
    Nov 21 '18 at 18:03



















  • I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

    – regina_fallangi
    Nov 21 '18 at 18:03

















I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

– regina_fallangi
Nov 21 '18 at 18:03





I have a lot of different buttons and textfields. I would have to compare with each subview, and each subview of every subview.

– regina_fallangi
Nov 21 '18 at 18:03




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53415202%2fmake-view-draggable-but-not-tappable%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

ts Property 'filter' does not exist on type '{}'

Notepad++ export/extract a list of installed plugins