I have a UIViewController that contains UITextField. I set the inputAccessory of the textfield to a UIToolbar that I create.
My ViewController's view is inside a UIScrollView (To handle the events of keyboard popping up)
Before:
Now, when the keyboard pops up, suddenly my ScrollView is setting it's contentOffset.y to 64 with animation, so part of my view is pushed above the top of the screen:
After:
This is done by the framework because I'm using a toolbar for inputAccessoryView.
If i'm dropping the toolbar there is no animation and no content offset.
Is anyone knows how can I disable this automatic animation and scrolling?
Thank you!
You can use a combination of boolean flags and your UIScrollViewDelegate to prevent the scrolling from taking place. Scroll view delegates can be used to detect when scrolling is taking place, modify the type of scrolling, and also simply prevent it from happening, so your best approach is probably to look into detecting when the keyboard goes up (via a notification or text field delegate, whichever is more appropriate) and using that in combination with your scroll view delegate.
Related
I have an UITableView with a single cell that contains an UITextView. When calling -becomeFirstResponder on the UITextView my UITableView gets messed up by the automatic animation. This only occurs when the UITextView has to scroll down for the end of the text.
I already tried disabling scrolling on the UITableView.
Depending on the needs of your interface, you could probably do what you're asking by making the parent view controller an instance of UIViewController instead of UITableViewController (which is what provides that "slide to get out of the way of the keyboard" behavior).
Indeed, if your UI consists solely of a text view, you probably don't need a table view at all.
I made UIPicker and with background on it:
(left is normal size of Picker, on the right is mine)
The problem is: when the user clicks on TextField - the picker reacts and scrolls down. Is it possible to prevent clicking, and make it to react only on swipe?
Add an another UIView above all view then add your UITextField on this UIView.
This will prevent the user interaction conflict.
I think you should move your UITextField farther away from the UIPickerView. Maybe a few notches up as the users touch would cover both the views.
The "too long; didn't read" version: Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?
I have a scroll view with paging enabled and several views as subviews, each subview being controlled by its own view controller. Each subview has a UITextField.
The requirement is that when a page is scrolled into view, it's text field should become first responder.
This is fine when using finger swipes to scroll -- I use the scroll view delegate method scrollViewDidEndDecelerating: to know when scrolling stops and a page is in view, I can tell the text field to become first responder.
However, when the scroll view is "autoscrolled", as in when telling the scrollview to scrollRectToVisible:animated:, the scroll view delegate method for deceleration isn't called. I use this method when scrolling newly created pages into view without the user's interation, or when the user taps the UIPageControl.
My solution was to simply set the first responder status of the text field before telling it to scroll into view - but it seems that telling a text field that is in a scroll view to become first responder causes the scroll view to automatically scroll it into view.
I assume this is behaviour used when putting text fields in table view cells (since table views are scroll view subclasses). If you set up a small test app, with a table view, and a text field within a table cell, if the keyboard would obscure the table view cell when it becomes first responder, the table view will automatically scroll it to be visible.
I don't understand, though, why this behaviour occurs in my example, where I'm not using a table view - just a plain scroll view.
I should also mention that my scroll view has vertical scrolling disabled and only scrolls horizontally.
I have tested in another test app that puts text fields as direct subviews of a scrollview (no view controllers or container views) and the same happens. If you tell a text field that is offscreen to become first responder, the scroll view with automatically scroll it for you.
This wouldn't normally be a problem, but it seems to screw up the paging of the scroll view. When I scroll with my finger, each view bounces and is centred properly. But when I scroll a rect to be visible with animation and tell a text field to become first responder, scroll view seems to become conflicted with itself and the view is only scrolled part of the way into view, and isn't centred.
Then, if I touch a view using my finger (not swipe, or even move), the scroll view jumps back to the first page.
My current work around for all this silly auto scrolling behaviour is to use an NSTimer to determine when to update the first responder.
I do the manual scrolling in code using scrollRectToVisible:animated and then after 0.3 seconds, call my method to update the text field to be first responder. (0.3 seconds was trial and error, trying to see which seemed to be the smallest amount of time to allow for the animation but still be long enough not to cause the conflict with the scrollview.
As you can see, this isn't elegant, and is likely to break.
Is there any way to disable the automatic scrolling behaviour of UIScrollView when telling a UITextField to becomeFirstResponder?
Call becomeFirstResponder, then right away, set the contentOffset of the scrollview to its current position..
[textField becomeFirstResponder];
[scrollview setContentOffset:scrollview.contentOffset animated:NO];
Not an answer to your question, but it should fix the problem:
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// Make the text field first responder...
}
I am trying to animate table rows in a UITableView in an iPhone project as I swipe across the screen to reload the data.
When I disable animations and only call reloadData, table continues responding to swipe gestures.
When I add animations with the reloadSections:WithRowAnimation: method, table stops responding to swipes, and only the navigation bar at the top responds to swipes.
Another change is that, table starts responding to selection and I have to manually disable it again. I suspect these two issues might be related.
I am using the swipe detection code over here btw: 1
My code for managing the gesture was in a UIView which contained another UIView which in turn contains the UITableView. It turns out that the user interaction of the UIView which is the superview of the UITableView was Enabled. Setting it to disabled caused the gesture to move up in the responder chain, and solve the problem.
I'm using a UISwitch-Component at the bottom of a view that sits within a UIScrollView.
Now the problem that appeared, is that the switch is nearly impossible to swipe because the UIScrollView seems to dominate the userinput.
Switching works very well by tapping the switch, but from my point of view, most users "switch" the UISwitch instead of tapping.
Did anyone of you face the same / or similar problems and managed to come up with a solution?
thx in advance
sam
You have a design decision to make: if your content is meant to scroll horizontally, then a user swipe over a switch is ambiguous -- does it mean they want to scroll, or toggle the switch?
The easiest solution is to modify your UI so that this ambiguity disappears. For example, if the scroll's contentSize is not wider than the bounds of the scroll view, then it can't scroll horizontally, and a horizontal swipe will always activate the switch.
If you do want to allow horizontal scrolling, then it makes sense to replace the UISwitch with a UIButton that toggles on touch, similar to a play/pause button.
On the other hand, if you don't want to modify your UI, you could always just do:
myScrollView.delaysContentTouches = NO;
This will cause your switch to "get" the touches immediately, rather than have them go to the UIScrollView first. More info here. (You can also set this boolean in Interface Builder, as pointed out by Squeegy.)