iOS: show segue prevents UITableViewController to auto scroll when UITextField gets focus - ios

I have a UITableViewController that is presented via a show (push) segue. Its rows have UITextFields. On the iPhone, when a textfield get focus, the keyboard hides the textfield if said textfield is towards the bottom of the screen.
This only happens on the iPhone, with any segue except "present modally" or "present as popover" ones. For these latter segues, the table scrolls up the textfield so that it's not covered by the keyboard - the standard behavior for UITableViewController.
On the iPad it works as expected (auto-scrolling the table), regardless of the segue type. Any idea why?
I've created a new project just to test this, it works as expected. In the initial project where it doesn't work, the UITableViewController is a secondary controller of a SplitViewController.
I've tested with or without auto-layout, same results.
iOS8
Thanks
The first screenshot shows the table with no textfield having focus
The second one was taken after the last textfield got focus. It is covered by the keyboard.
PS: I've tried the same with just a UITableViewController, not a subclass of UITableViewController as initially. I know in subclasses there is a problem if for example you override viewWillAppear but do not call super. This is not the case.
Relevant Apple documentation excerpt:
Note: A table view controller supports inline editing of table view rows; if, for example, rows have embedded text fields in editing mode, it scrolls the row being edited above the virtual keyboard that is displayed. It also supports the NSFetchedResultsController class for managing the results returned from a Core Data fetch request.
The UITableViewController class implements the foregoing behavior by overriding loadView, viewWillAppear:, and other methods inherited from UIViewController. In your subclass of UITableViewController, you may also override these methods to acquire specialized behavior. If you do override these methods, be sure to invoke the superclass implementation of the method, usually as the first method call, to get the default behavior.
https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TableView_iPhone/TableViewAndDataModel/TableViewAndDataModel.html#//apple_ref/doc/uid/TP40007451-CH5-SW7

I have checked the behaviour and faced this kind of issue in iPhone 6.
In viewDidLoad method -
self.tableView.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];

I wish I could tell you why the code below works, but I can't; I am aware that makes this a bad answer. With that said, it does work consistently across my application.
Add a simple completion block to your view controller dismissal. In my code, that means the viewWillAppear is called twice, once before dismissal and once after (as I said, I don't know why this works but it does for me).
dismissViewControllerAnimated(true) { self.viewWillAppear(true) }

Related

How to change UITabbarController's More ViewControllers UITableViewCells images?

More viewcontroller images are showing up in default blue background instead on original images. I want to change them to original images and also want to increase UITableViewCell's height.
I have tried implementing tableview delegate methods on UITabbarController, but nothing working out.
Even moreNavigationController is also not changing.
1) Where do i have to write these custom methods viewDidLoad or viewWillAppear. Also shouldSelectViewController is not getting called. First time when i select a tabbar item it is being called and when i select the more item it is not getting called.
2) Where should i implement UITableView delegate methods.
My screen -
required screen -
A solution using swift is helpful. Thanks in advance.
I got the requirement working. The step wise procedure I followed is
Take a ViewController which extends UITabbarController.
Take an array with five elements exactly.(If more than five then default More functionality gets enabled).
First four tabs as required and fifth should be 'More' tab. With required tab images.
For 'More' tab create a View Controller which extends UITableView delegates and datasources. And implement respective methods of delegate and datasources.
Take an array of the Cells you want to display and display them.
Link this 'More' View Controller to the 'More' tab.
Change the images in tableview in cellForRowAtIndexPath method.
Run the application and check by selecting 'More' tab. This time it should show the changed UI.
When each cell should show different View Controllers on selecting the cells, then segue to different view controllers using the segues from ViewController (Not segue from the tablecell). Define a unique segue id for each segue and show the viewcontrollers based on switch or ifelse conditions in shouldSelectViewController using performSegueWithIdentifier.
Thanks #KKRocks for the valuable links.
There's some content to be unpacked here. I am not entirely certain I fully understand the question but I'll go ahead and reply partially as best I can.
ViewDidLoad and ViewWillAppear
You add code in viewDidLoad for initialization. This method will run when your view is originally loaded and unless you're instantiating the controller every time it will only run once ( in this case you dont because you're using the prebuilt tabbar system which takes care of that for you)
So I would add the styling code in viewDidLoad()
When a viewController is to be displayed, viewWillAppear() will be called. This will happen every time so if you need to perform repetitive tasks like network calls, restyling based on some other data, refreshing your tables, you should do it here.
Table methods
For doing whatever you need to do with a table you will most likely need both UITableViewDelegate and UITableViewDataSource to your view controller. Look up any UITableView tutorial online they're many very comprehensive and will explain how to add all the table methods you need in your viewController.

UITableViewController auto-scrolling stops taking into account keyboard when shown from a UISplitViewController

When you subclass UITableViewController, you normally get certain behaviors "for free". For example, when a text field in your table view becomes first responder, the view controller automatically scrolls itself to ensure the field is fully visible.
However, when the table view controller is the detail view controller of a UISplitViewController, this auto-scrolling no longer takes into account the presence of the keyboard. The table view controller will still auto-scroll to keep the text field within the bounds of the screen, but it no longer scrolls to keep the field from being covered by the keyboard.
You can test this yourself by creating a new project using Xcode's "Master-Detail Application" template, and replacing the detail view controller with a table view controller that displays cells with text fields in them.
I would like to understand why the auto-scrolling stops accounting for the keyboard in this case, and if possible how to rectify that without having to duplicate the auto-scrolling functionality myself. BTW, this has nothing to do with overriding viewWillAppear (as in some other questions here about table view controller auto-scrolling).
I know its late but this might help others who are having this issue. This happens to me as well when I added textfield in UITableViewCell. What I did was to remove
superViewWilAppear:animated
line in viewWillAppear method.So the method looks like this
-(void)viewWillAppear:(BOOL)animated{
//[superViewWilAppear:animated];
Your rest of code
}
But what this does is it removes the auto scrolling all together and you have to manage the scrolling of UITableView when textField starts editing. Don't know if this solved your problem but it will save you the trouble of considering keyboard height for different devices and its better to manage on your own. Also I am not sure if this is the right way to do it but it worked for me.

My view automatically goes up when keyboard come in ios

In my storyboard I have two navigation controllers, say A and B. I bring NavB as a modal controller when a button is clicked on NavA. I have a textfield in my NavB. I have connected this textfield to the controller from storyboard and also have set the textfield delegate. When I click on this textfield, my view automatically animates up. I did some research and found that this happens when I set the delegate for textfield. This dont happen when I push my controller.
I have no clue how to fix it.
Please help!
I believe your viewController is UITableViewContoller, no?
The autoscroll-behavior is located in the UITableViewController functionality. To disable the automatic scrolling there are two ways:
use instead of the UITableViewController simply a UIViewController - set the datasource and delegate on your own.
Override the viewWillAppear-Routine - and DON´T call [super viewWillAppear: animated].
Hope this fixes your issue, cheers :)
I would like to just make sure that your view is not a class of TPKeyboardAvoiding. Since its description says that:
A drop-in universal solution for moving text fields out of the way
of the keyboard in iOS
I have used in the login/sign controllers and observed that when a UITextField goes in edit mode, the TextField goes out of the way and view scrolls accordingly.
I fixed the issue. I had unticked 'Under top bars' in the storyboard and thats why i was getting this behaviour.

How to make a callback from a UITableViewController to another UIViewController

I followed this discussion: UITableView issue when using separate delegate/dataSource, and even though I found it super informative and useful, I have a follow up question:
So I've got a similar setup where I have a UITableView within the UIView. The UIView is controlled by it's own UIViewController (let's call it MyUIViewController) and also I moved the delegate and datasource for the UITableView into a separate subclass of UITableViewController (say, MyUITableViewController).
Everything works fine with the tableView.
The question is, how do I make a callback from MyUITableViewController to the MyUIViewController? For example, if the user selects a cell under the tableView which triggers didSelectRowAtIndexPath, I need to update something on the UIView which is actually a parent of this UITableView. So I basically need to send a message to MyUITableViewController. How would I do that?
You can use a delegate pattern in this case. I have a similar answer with sample code in this SO . In your case, the parent view controller is MyUIViewController. And the child view controller is MyUITableViewController.

UITextField focus before navigation view push?

I have a UITextField set up in a UITableViewCell, for a control mimicking that in Apple's own Contacts app, when you go to edit a field. This is all mostly working fine, except for a little UI bug.
The UITableView is part of a UIViewController created and loaded from a XIB, but the text field is being created programmatically (and becoming first responder) in tableView:cellForRowAtIndexPath:, so that it can be added to the cell.
This results in a slight keyboard lag, where the view controller is pushed onto the stack, with the keyboard coming soon after.
The Contacts app, however, pushes it all as one.
How can I correct this lag? I've tried moving the text field creation and first responder-ing to viewDidLoad, and this didn't help. I even tried creating a layoutSubviews and calling it from outside the view controller, before it was pushed to the stack.
Unfortunately, it doesn't seem as though the text field actually becomes the first responder until it is part of the cell—well after the view has been pushed.
You have to let the UITextField become the first responder in viewWillAppear.
I have created an example project here:
https://github.com/lukaswuerzburger/pushed-keyboard

Resources