iOS : recognize touch on UI scrollView - ios

hi Im new to programming I was try to recognize the user touch on the screen and close all textfield but when I add a scrollview I won't be able to do that I read a lot in stack overflow like : tap recognizer but I could not do that anymore after adding the textfield I got confused
tell me how can I do it please?
thanks

for dismiss the keyboard is the subview of UIView, then use
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.view.endEditing(true)
}
for dismiss the keyboard is the subview of UIScrollview, then use in here scroll view observes the userInteraction so "By setting userInteractionEnabled to NO for your scroll view".
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.yourSCrollviewName.endEditing(true)
}
for resign the keyboard in various types, the some other type has already answered in SO
update
for hide the keyboard the create the TapGesture for your scrollview
self.ScrollView.isUserInteractionEnabled = true
// ScrollView.keyboardDismissMode = .onDrag
let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped))
tap.numberOfTapsRequired = 1
self.ScrollView.addGestureRecognizer(tap)
and call the action as
func doubleTapped() {
// do something cool here
self.ScrollView.endEditing(true)
}

You have to add tap gesture on ScrollView
Add below code in action of gesture:
self.yourSCrollviewName.endEditing(true)

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(keyBoardHideOnTap))
tapGesture.numberOfTapsRequired = 1
self.ScrollView.addGestureRecognizer(tapGesture)
func keyBoardHideOnTap() {
// do something cool here
self.ScrollView.endEditing(true)
}

Related

Why can't I interact with subviews?

I have a view controller where I can add several subviews with a LongPressGesture. For each subview I provide a TapGesture that should open a popover for this view (see picture below).
My problem is, that I can only open the popover for the last subview I added. So why can't I interact with the other subviews anymore?
This is my first App in Swift, so it would be nice if someone could help me.
Some code for you:
This is the LongPressGesture on the root view controller that creates a new subview.
#IBAction func onLongPress(_ gesture : UILongPressGestureRecognizer) {
let position: CGPoint = gesture.location(in: view)
if(gesture.state == .began) {
let subview = MySubview(position: position)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
subview.addGestureRecognizer(tapGesture)
view.addSubview(subview)
}
else if (gesture.state == .ended) {
let subview = self.view.subviews.last
self.openContextMenu(for: subview)
}
}
ViewController with subviews:-
When reacting to an event (long press in your case) only the first responder will handle the event. When adding subviews to a view, all the subviews are added one in front of another. So the last added subview will handle the event - if it is listening for the event. If you need a specific subview to handle the event, you can bring it to front as
parentView.bringSubviewToFront(view: subView)
Alternatively, you can also disable other subviews as
subView.isUserInteractionEnabled = false
Ok, I found a solution for my problem. The good thing is, that it only detects touches in the frames of the subviews.
In my root view controller I added:
var isPanGesture = false
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
isPanGesture = true
if let subview = touches.first!.view as? MySubview {
let position = touches.first!.location(in: self.view)
link.center = position
}
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
if let subview = touches.first!.view as? MySubview {
if(!isPanGesture) {
self.openContextMenu(for: subview)
}
isPanGesture = false
}
}

How to trigger an event when a user touches specific part of the screen - ios?

I have a custom pop up which I have made using a UIViewController (presentation: 'over current context') - please see below. What I would like to do is dismiss the UIViewController once the user touches the top - dark half- of the screen, which does not contain the menu options. What event can i trigger to get this to work?
You can add a tap gesture to the darkView and inside it do
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
mydarkView.addGestureRecognizer(tapGesture)
//
// 3. this method is called when a tap is recognized
#objc func handleTap(_ sender: UITapGestureRecognizer) {
self.dismiss(animated:true,completion:true)
}
OR use
override func touchesBegan(_ touches: Set<UITouch>,
with event: UIEvent?)

Tap gesture to NOT occur when touching a specific location - SpriteKit

I have used touchesBegan to provide functionality for my UIButtons and have used a tapped gesture to provide functionality for my main player SKSpriteNode making it jump when triggered.
//Code regarding the UIButton touch
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//touches began is only used for GUI buttons -> not to affect player
for touch: AnyObject in touches {
//We get location of the touch
let locationOfTouch = touch.location(in: self)
if muteButton.contains(locationOfTouch) { //mute the game
timer.invalidate()
audioPlayer.volume = 0
}
//Code regarding the tap
let tap = UITapGestureRecognizer(target: self, action: #selector(GameScene.tapped(gesture:)))
tap.cancelsTouchesInView = false
self.view!.addGestureRecognizer(tap)
......
func tapped(gesture: UIGestureRecognizer) { //used to make the player jump
player.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 60))
player.physicsBody!.affectedByGravity = true */
}
My problem is that when I press on the restartButton the tap gesture is also activated later when the touch ends. Is there anything I can do?
The main issue is that the two separate systems for detecting touches (using gesture recognizers and using the touchesBegan/Moved/Ended methods) are in conflict.
One solution is to enable and disable the gesture recognizer if the touch is inside one of the buttons.
In the touchesBegan method, if the touch is inside a button, disable the tap gesture recognizer:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let locationOfTouch = touch.location(in: self)
if muteButton.contains(locationOfTouch) {
// mute action
tap.isEnabled = false
}
}
}
Then in touchesEnded and touchesCancelled, re-enable the gesture recognizer:
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
tap.isEnabled = true
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
tap.isEnabled = true
}
This way, if the touch is inside a button, the tap gesture recognizer will not fire. Whenever any touch is complete, we always re-enable the gesture recognizer in case the next touch is meant to make the player jump.
I have tested this out in an empty project, and it works.
Hopefully that helps! Good luck with your game.

Capture tap when dismissing keyboard

I cannot seem to figure out how to capture the tap that a user does when they tap outside of a keyboard. The main issue is I have a send button that is not part of the keyboard and I want if they tap it, while the keyboard is open for the send to occur. Currently the user taps the send button which dismisses the keyboard then if they tap the send button again it will send the text.
Just add a tapGesture to your view:
let tap = UITapGestureRecognizer(target: self, action: #selector(viewTapped(_:)))
self.view.addGestureRecognizer(tap)
Which will call self.view.endEditing(true) and dismiss the keyboard.
func viewTapped(_ gesture: UITapGestureRecognizer){
self.view.endEditing(true)
}
This does not require any gesture recognizer, and will capture any contact with the screen, dismissing the keyboard.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
view.endEditing(true)
}

touchesbegan for dismissing keyboard textview under scrollview not working

I have a text field under a view which is under a scroll view inside a view controller which is one of the view controllers of a navigation controller. I want to dismiss the keyboard when the user touches outside the textfield. I tried using touchesBegan:, but it is not firing when it's under the scrollview. I also tried disabling user interaction in the scroll view, but nothing worked. Could anyone help me out?
func dismissKeyboard(txtField:UITextField)
{
txtField.resignFirstResponder()
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
dismissKeyboard(firstNameTxt)
}
Changed the below way for it to work
extension AddEditHireViewController {
func hideKeyboard()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: "dismissKeyboardNew")
self.formView.addGestureRecognizer(tap)
}
func dismissKeyboardNew()
{
self.formView.endEditing(true)
// self.dismissKeyboard(self.firstNameTxt)
} }
Whilst the solution given by Matthew Bradshaw works too, it will not dismiss the keyboard if the user scrolls. If you want it to do that, another solution would be to subclass UIScrollView. You could then override the touchesBegan method in this subclass, and then end editing accordingly.
class DismissableScrollView: UIScrollView {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
endEditing(false)
}
}
Once you have done this, simply change your existing UIScrollView's class to DismissableScrollView, or if you are already subclassing UIScrollView, you could add this to that subclass.
You could try to create an extension of the view controller. This has worked much smoother for me and with less hassle than trying to use .resignFirstResponder()
extension UIViewController
{
func hideKeyboard()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(
target: self,
action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}
func dismissKeyboard()
{
view.endEditing(true)
}
}
Call self.hideKeyboard() in the viewDidLoad

Resources