How to hide keyboard without animation in swift 2? - swift

I have a segmented control that switches between 3 views, one of which is a chat. I have an #IBAction set up to that segmented control for when the index (tab selected) changes. Since I want the keyboard to go down, the first thing I do is call my dismissKeyboard function:
func dismissKeyboard() {
view.endEditing(true)
}
The problem is this method has a sliding down animation, I would want it to just disappear. Looking for a Swift 2 solution

You can do
UIView.performWithoutAnimation {
self.view.endEditing(true)
}

Looks like it's not possible in Swift 2 or 3 to dismiss a keyboard without the slide down animation.
resignFirstResponder doesn't take any arguments.

Related

UIGesture Recognizer for Scrolling?

I was wondering if there is a UIGesture Recognizer for scrolling, like on a tableView?
So, like the second a user starts scrolling on the tableView, the UIGesture Recognizer is triggered? I tried UISwipeGestureRecognizer but that did not do that trick.
I essentially just want to detect when a user starts scrolling on a tableView, and then update a value based on this. Is there anything designed for this purpose in xCode?
plz help I have spent 3 days on this one thing :)
thank you so much
you can use scrollview delegate method for that purpose
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if scrollView == tblview{
//Do your code here
}
}

How can I invalidate flow layout with animation like in ios?

I'm making an app in Xcode for Mojave OSX.
I want to make a resize of a collectionview and items position of that.
Currently I call to invalidateLayout() method, but it recalculate and set sizes and positions without animations.
In the GIF you could see what is the current behavior, I need that the last item go to second row, in an animated way.
For this i try to override this methods of NSCollectionViewFlowLayout
open override func prepare(forAnimatedBoundsChange oldBounds: NSRect){
}
open override func finalizeAnimatedBoundsChange() {
}
But these never get called, and I don't know what code I need to animate this transition.
(Moved from question to an answer.)
You could override the viewDidLayout of your viewController (or assign an observer to the frame view) and execute this:
collectionView.animator().performBatchUpdates(nil)
This reloads your collectionviewLayout with an animation.

How do I dismiss the keyboard in a custom keyboard?

I would like to assign a key/button on my custom keyboard to dismiss/hide the keyboard. I can't seem to get any code to work.
I have tried:
self.view.resignFirstRespoder()
view.endEditing(true)
But nothing along these lines seems to work.
Could someone please point me in the right direction?
Call the dismissKeyboard() function.
Because a custom keyboard does not have access to the current text
input object, you cannot send it a resignFirstResponder() message (as
you would to dismiss the system keyboard when you are developing an
app with text entry). To dismiss the custom keyboard, call
dismissKeyboard() instead.
Apple reference.

'resignFirstResponder()' returns true and the text field loses focus but the keyboard does not dismiss

I have a storyboard scene that only has two UITextField.The first one is left untouched, fresh out of the object library. The second one has its delegate outlet connected to the ViewController's code.
App's interface
The second text field's connection in IB
(Sorry I have to post images this way, because StackOverflow won't let me.)
The code is really simple. This is all of it.
class ViewController: UIViewController, UITextFieldDelegate {
func textFieldDidBeginEditing(textField: UITextField) {
textField.resignFirstResponder()
}
}
The only thing it does is dismiss the keyboard when it's about to come up.
The first one shows the keyboard normally. The second one doesn't show keyboard because it's immediately dismissed.
It all works perfectly on their own, until I click the first text field to bring up the keyboard, then with the keyboard on screen, I click the second text field.
What happens next, is that the second text field loses its focus, but the keyboard remains on screen.
Using print(:), I've verified that, when I call resignFirstResponder on the second text field, it is the first responder, and the return value of that call is true, and after the call it is no longer the first responder.
But the keyboard is still there...
I tried adding print(:) in the delegate's textFieldShouldReturn(:) method, and clicking the return key after the text field resigned. There was nothing printed in the debug console.
I tried disablesAutomaticKeyboardDismissal(), returning neither false nor true produces any difference.
Edit
What I want is simple:
I want the first text field to do whatever it's default to do, and the second one to dismiss its keyboard as soon as it's tapped (from the user's perspective, basically meaning not showing it).
I know textFieldShouldBeginEditing(:), but I can't use it for various reasons, I just have to dismiss the keyboard after it's been activated.
Edit Again
I tried view.endEditing(true) as well. In fact, I tried .endEditing(true) on every view in the scene. Doesn't work.
Try smth like that:
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
view.endEditing(true)
return true
}
func textFieldDidBeginEditing(textField: UITextField) {
textField.resignFirstResponder()
//make here whatever you like
}

How to Fix Disappearing Views When the Keyboard Appears in Xcode 6?

I've included a link to a video that shows what problem I'm having:
https://dl.dropboxusercontent.com/u/39330138/Bug_Demo1.mov
There are two View Controllers, the first is non blurred and less important. When the plus button is clicked, the app segues to a new controller (without animating) and in prepareForSegue() I use UIGraphicsBeginImageContext and UIGraphicsGetImageFromCurrentImageContext to capture a UIImage from the current view and pass it on to the next one.
When the new view appears I use UIVisualEffectView to create a blur view and add it as a subview to the Image View that is the 'background'. Then, its opacity is animated at the same time the 2 views and 2 buttons are animated on screen with UIView animation and springWithDamping, giving the illusion of the view blurring over and items animating over the top.
The top view has a UITextField embedded in it which, when tapped calls becomeFirstResponder() and makes all overlaid (New Session, Tag & Button) views including the Visual Effect View imbedded in the background Image View disappear.
The reason I go into so much detail is because I'm not sure what exactly the problem is. However, I have a suspicion that it is to do with the AutoLayout/Size Classes in Xcode 6.
Does anyone know why this might be happening and how to fix it?
If you need additional information, just let me know.
Thanks!
EDIT:
When I log the views after I click on the TextField, all the frames seem the same.
EDIT 2:
Here's a link to a demo project will all the functionality from the video:
https://dl.dropboxusercontent.com/u/39330138/DEMO%20APP.zip
There are a couple of things happening here, but the main culprit is your use of viewDidLayoutSubviews(). This is called any time the system has to reevaluate the layout. I see you're setting your UIVisualEffectView's alpha to 0 in that method:
if !returningFromTagView {
blurView.alpha = 0
}
I think you're intending this to be called just once before the view appears because I see you animate the alpha to 1 in viewDidAppear(animated: Bool). However, any time the system reevaluates layout for any reason, viewDidLayoutSubviews() is called and the alpha on blurView is going back to 0 if returningFromTagView is false. That's why when you summon the keyboard (triggering a layout reevaluation), this view disappears. Xcode also warns you about making the alpha 0 in the console (it breaks the visual effect until the opacity returns to 1). Put the code above in the viewDidLoad() method instead, and you'll see blurView come back. The alpha only needs to be set to 0 once when the view loads.
The issue with the other views is a bit tougher to see, but the culprit again is your use of viewDidLayoutSubviews(). I imagine that you're puzzled why the views don't appear even after you've been very thorough in your keyboardNotfication() method to set the frames, bring the views to the front, make sure they aren't hidden, and then log this all. But after the keyboardNotification() method finishes, the layout system once again is triggered, and I see that you're nudging the views' frames here and there:
if returningFromTagView {
setX(-titleView.frame.size.width, v: titleView)
setX(-tagView.frame.size.width, v: tagView)
setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton)
setX(-nextButton.frame.size.width, v: nextButton)
} else {
setX(-titleView.frame.size.width, v: titleView)
setX(view.frame.size.width, v: tagView)
setX(-cancelButton.frame.size.width, v: cancelButton)
setX(view.frame.size.width, v: nextButton)
}
You're moving the views offscreen every time a layout change is made! Pause the program after you summon the keyboard and look at your view hierarchy using Xcode 6's great new Capture View Hierarchy ability. It's in Debug > View Debugging > Capture View Hierarchy. Those views are just hiding off to the side.
I image you're trying to do this just once when the view appears in order to support your transition animations, but it gets called whether the view is just appearing or if a small change like the keyboard is appearing. I suggest that you implement these animations another way, like using the views' transforms or using autolayout constraints (though you have a lot of missing constraints in the storyboard) to do your animation. viewDidLayoutSubviews() is really a place to fudge things here and there in your layout after the layout system has done its work. You should have a good reason for using it. It has the nice feature of overriding your autolayout constraints and letting you animate those views without toying with the constraints (because the method happens after the updateConstraints() and layoutSubviews() methods), and that's why we can't put the above code in a method like viewWillAppear(animated: Bool) instead (because autolayout constraints would counter the animation during layout later), but viewDidLayoutSubviews() just is not a method that's meant to support basic animations.
In spite of that, here's something simple to get your app going again and for you to see what's going on:
Make a property var comingFromSessionView: Bool property for your NewSessionVC view controller. In the prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) of SessionVC, add nextVC.comingFromSessionView = true
Then change the code block from viewDidLayoutSubviews() above to this:
if returningFromTagView {
setX(-titleView.frame.size.width, v: titleView)
setX(-tagView.frame.size.width, v: tagView)
setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton)
setX(-nextButton.frame.size.width, v: nextButton)
} else if comingFromSessionView {
setX(-titleView.frame.size.width, v: titleView)
setX(view.frame.size.width, v: tagView)
setX(-cancelButton.frame.size.width, v: cancelButton)
setX(view.frame.size.width, v: nextButton)
}
We'll switch these Bools to false during viewDidAppear after it's done with them:
override func viewDidAppear(animated: Bool) {
...
if returningFromTagView {
...
returningFromTagView = false
} else if comingFromSessionView {
...
comingFromSessionView = false
}
}
Now when the keyboard is summoned, your views are right where you left them!
The code above isn't great. I'd rather stay away from viewDidLayoutSubviews() for doing these animations. But hopefully you can see what's going on now. Your viewsDidLayoutSubviews() has been whisking away your views.