Reputation: 417
I know this is kind of obnoxious and technically not recommended, but I have a UITableViewCell inside a UITableView (of course) inside a ScrollView, inside another view.
Here's the hierarchy
View
=> ScrollView
=> TableView (also a scrollview)
=> Cell
=> TextField
Currently, I have a bit of code in the controller for the top view that scrolls the screen when a TextField is activated inside the ScrollView. That looks like this:
/// <summary>
/// Event fired when keyboard is popping up
/// Prevents keyboard from hiding selected text fields
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private void ShowCallback(object sender, UIKeyboardEventArgs args)
{
var currentStep = steps[currentIndex];
// Get the size of the keyboard
CGRect keyboardBounds = args.FrameEnd;
nfloat bottomGap = View.Frame.Bottom - currentView.Frame.Bottom;
// Create an inset and assign it to the tableview
UIEdgeInsets originalInsets = currentStep.ScrollView.ContentInset;
UIEdgeInsets contentInsets = new UIEdgeInsets(originalInsets.Top, 0.0f, keyboardBounds.Size.Height - bottomGap, 0.0f);
currentStep.ScrollView.DelaysContentTouches = false;
currentStep.ScrollView.ContentInset = contentInsets;
currentStep.ScrollView.ScrollIndicatorInsets = contentInsets;
UITextField tf = currentStep.GetActiveTextfield(currentView);
if (tf != null)
{
currentStep.ScrollView.ScrollRectToVisible(tf, true);
}
}
This works great for TextFields inside the ScrollView, but doesn't work for TextFields inside the TableView. "tf" is not null, so it's definitely getting the value, but the ScrollView doesn't budge and I'm still having the hidden textfield problem.
I've spent so much time fixing issues with the keyboard hiding my content. I wish there was a built-in, easy solution from Apple.
Upvotes: 0
Views: 503
Reputation: 417
Converting Rect of a Subview's Subview
Carter's answer got me started, but what I needed to do was get the coordinates of the TextField as it related to the top level ScrollView using ConvertRectFromView:
CGRect frame = currentStep.ScrollView.ConvertRectFromView(tf.Frame, tf.Superview);
currentStep.ScrollView.ScrollRectToVisible(frame, true);
This gave the me the position of the TextField inside the scrollview, instead of the coordinates inside the Cell. Scrolling works as expected after this addition.
Supporting Information
Apple documentation: https://developer.apple.com/reference/uikit/uiview/1622498-convertrect?language=objc
A link that helped me understand how to use the method: http://www.infragistics.com/community/blogs/torrey-betts/archive/2013/05/06/quick-tip-convert-coordinate-system-of-a-uiview.aspx
Objective C usage:
- (CGRect)convertRect:(CGRect)rect
fromView:(UIView *)view;
Upvotes: 0
Reputation: 3093
Built-in, easy solution from Apple :)
There's actually a function to scroll the cell you want to be visible! In Swift, it looks like:
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
So with this solution, just get the cell of the UITextField and ask your table view to scroll to that cell.
Alternative Answer
Problem
The UITextField's
frame is relative to its super view, the cell. In this case, the text field probably has a frame like CGRect(x:0, y:0, width: cell.frame.size.width, height:cell.frame.size.height)
, so when you call ScrollRectToVisible
, the scrollView
won't move.
Solution
To solve this, call ScrollRectToVisible
on the cell's frame instead, for example:
UITextField tf = currentStep.GetActiveTextfield(currentView);
UIView v = tf.superView;
if (v != null) {
currentStep.ScrollView.ScrollRectToVisible(v, true);
}
I'm not used to xamarin, so please correct any formatting or errors you see!
Upvotes: 1