I've seen this, but don't remember what Jedi technique exactly was used through interface builder to dismiss uikeboard when return key is pressed. Anyone knows how to do this?
Please do not post about using UITextFieldDelegate, I know that method, I'm only interested in forcing keyboard to be dismissed on return key being hit without any additional logic or protocol conformation.
Connect the IBAction with "Did End On Exit" event in your xib of your textfield
-(IBAction)textFieldDidEndOnExit:(UITextField *)sender
{
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first{
view.endEditing(true)
}
}
Related
I'm new to the iOS development and Swift and I have the following problem:
I would like to capture touch events from the screen. I have no problems with doing this on regular views. Unfortunately, I encountered issues with the UIScrollView component. When user is tapping on the screen, long pressing on the screen or moving finger horizontally, then I'm able to capture touches, but when user is moving finger vertically and activating vertical scrolling at the same time, then I'm not able to capture touches.
I found a few threads on StackOverflow regarding similar issue, but solutions provided there did not resolve my problem.
Structure of my views is as follows:
+- View (top-level view)
|
|
+--- UIScrollView
|
|
+-- other views inside...
Here is my code:
class MyViewController : UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
view.addGestureRecognizer(myRecognizer)
}
}
Gesture recognizer is added into the top-level view.
I also have basic custom implementation of the UIGestureRecognizer:
class MyRecognizer: UIGestureRecognizer {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesBegan(touches, with: event)
// handle events...
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesMoved(touches, with: event)
// handle events...
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
super.touchesEnded(touches, with: event)
// handle events...
}
}
What did I try to do to solve this issue?
setting parameter scrollView.canCancelContentTouches = false - didn't help
setting parameter scrollView.isScrollEnabled = false - I was able to capture all touch events, but scrollView stopped working - didn't help
adding gesture recognizer to the scrollView and removing it from the top-level view - didn't help
adding gesture recognizer both to the scrollView and the top-level view - didn't help
setting parameter scrollView.isUserInteractionEnabled = false - I was able to capture all touch events, but scrollView and all UI components stopped working - didn't help
reordering calls in MyRecognizer class: handling events first and then calling method from the upper class super.touches... - didn't help
Right now, I have no idea what else I can do to capture touch events inside the UIScrollView while user is scrolling the screen vertically.
Any suggestions or help are appreciated!
Regards,
Piotr
So UIScrollView has its own set of gestures that have cancelsTouchesInView set to true by default. Try setting this property to false for each gesture in the scrollview like so:
for gesture in scrollView.gestureRecognizers ?? [] {
gesture.cancelsTouchesInView = false
}
EDIT:
Solution to this problem is creating a separate custom UIScrollView and capture touches inside it. It is described in details in this thread: https://stackoverflow.com/a/70594220/10953499 (also linked in the comment).
I am trying to make my interface feel more responsive. A UIView changes color on user touch and I want it to do so already when the View is touched.
I could implement a UITapGestureRecognizer but a tap is not what I am looking for, since it requires the touch to end before being recognized.
I imagine this to be quite simple. Or am I wrong?
Do I create a custom UIGestureRecognizer class?
Have you tried touchedBegan?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if let touch = touches.first {
// ...
}
super.touchesBegan(touches, with: event)
}
I have a number of UIButton instances in a UIViewController and I want to perform a couple of actions when any of these buttons are pressed with pressure (all the way down), I don't know the exact term here (force touch maybe?).
So when UIButton is pressured, I want to give haptic feedback via vibration, change the button image source and do some other stuff. Then when the pressure is released I want to restore the button image source to the normal state and do some more stuff.
What is the easiest way to do this?
Should I make my own custom UIButton like below or are there methods that can be overridden for 3D touch "pressed" and "released".
This is my custom UIButton code so far. Should I determine, by trial and error, what the maximum force should be? Also how do I change the source of the image for each button in the easiest way possible?
import AudioToolbox
import UIKit
class customButton : UIButton {
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
print("% Touch pressure: \(touch.force/touch.maximumPossibleForce)");
if touch.force > valueThatIMustFindOut {
AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate))
// change image source
// call external function
}
}
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("Touches End")
// restore image source
// call external function
}
}
Please note that I am new to Swift so I would like to use the graphical interface in Xcode to create the user interface as much as possible. So I would like to avoid creating the UI from the code.
As for the force touch - you need to detect if it's available first:
func is3dTouchAvailable(traitCollection: UITraitCollection) -> Bool {
return traitCollection.forceTouchCapability == UIForceTouchCapability.available
}
if(is3dTouchAvailable(traitCollection: self.view!.traitCollection)) {
//...
}
and then in e.g. touchesMoved it will be available as touch.force and touch.maximumPossibleForce
func touchMoved(touch: UITouch, toPoint pos: CGPoint) {
let location = touch.location(in: self)
let node = self.atPoint(location)
//...
if is3dTouchEnabled {
bubble.setPressure(pressurePercent: touch.force / touch.maximumPossibleForce)
} else {
// ...
}
}
Here's the more detailed example with code samples:
http://www.mikitamanko.com/blog/2017/02/01/swift-how-to-use-3d-touch-introduction/
It's also a good practice to react on such "force touches" with haptic/taptic feedback, so user will experience the touch:
let generator = UIImpactFeedbackGenerator(style: .heavy)
generator.prepare()
generator.impactOccurred()
you might want to take a look at this post for details:
http://www.mikitamanko.com/blog/2017/01/29/haptic-feedback-with-uifeedbackgenerator/
How can I hide the keyboard At any touch on the screen, on a view that has a scroll View.
I added this code into viewDidLoad function:
self.NewAccountScrollView.keyboardDismissMode.UIScrollViewKeyboardDismissMode.OnDrag
And I added the UIScrollViewKeyboardDismissMode protocol!
I got errors?
What should I add more to make this works?
Is this the correct way to do that? or there are a better function to do the job?
try to add this, remove UIScrollViewKeyboardDismissMode
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
self.view.endEditing(true)
}
Add the tap gesture to NewAccountScrollView in ViewDidLoad Method.
let touch = UITapGestureRecognizer(target: self, action: "singleTapGestureCaptured:")
NewAccountScrollView.addGestureRecognizer(touch)
and hide keyboard after receiving tap.
func singleTapGestureCaptured(gesture: UITapGestureRecognizer){
self.view.endEditing(true)
}
My code inside a UIView Class that contains a UITextField named titleInput:
override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {
// Code to Dismiss the Keyboard when Pressed Outside Text Field
if !titleInput.pointInside(point, withEvent: event) {
endEditing(true)
}
// Return Original hitTest Result as Usual
return super.hitTest(point, withEvent: event)
}
I am experiencing a strange bug. When I first start the app, everything works as expected, touching outside the titleInput dismisses the keyboard. However, it brakes if I switch to a different app, and than come back to this app. After coming back to the app, clicking on the keyboard also dismisses the keyboard. Makes it difficult to type :)
Any idea why this is happening, and why it ONLY starts to happen after switching away from the app and then coming back to it? Also, is there a better way to do this same thing.
I would recommended doing it this way instead of what you are trying. This will just dismiss the keyboard when the enter/return key is pressed. I realize it is in Obj-C however the method calls are almost identical.
I usually do just this
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
view.endEditing(true)
super.touchesBegan(touches, withEvent: event)
}