为什么 ScrollToRect 不适用于 ScrollView 内的 Tableview 内的 TextField?

Why is ScrollToRect not working for a TextField inside a Tableview, inside a ScrollView?

我知道这有点令人讨厌,技术上不推荐,但我在 UITableView 中有一个 UITableViewCell(当然)在 ScrollView 中,在另一个视图中。

这是层次结构

View
=> ScrollView
    => TableView (also a scrollview)
        => Cell
            => TextField

目前,当在 ScrollView 中激活 TextField 时,我在顶部视图的控制器中有一些代码可以滚动屏幕。看起来像这样:

/// <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);
    }


}

这对 ScrollView 中的 TextFields 非常有效,但对 TableView 中的 TextFields 无效。 "tf" 不为空,所以它肯定得到了值,但 ScrollView 没有移动,我仍然有隐藏的文本字段问题。

我花了很多时间来解决键盘隐藏我的内容的问题。我希望 Apple 有一个内置的简单解决方案。

来自 Apple 的内置简单解决方案:)

实际上有一个功能可以滚动您想要显示的单元格!在 Swift 中,它看起来像:

self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)

因此,使用此解决方案,只需获取 UITextField 的单元格并让您的 table 视图滚动到该单元格。


替代答案

问题

UITextField's 框架是相对于它的超视图,cell。在这种情况下,文本字段可能有一个框架,如 CGRect(x:0, y:0, width: cell.frame.size.width, height:cell.frame.size.height),因此当您调用 ScrollRectToVisible 时,scrollView 不会移动。

解决方案

要解决此问题,请改为在 单元格的 框架上调用 ScrollRectToVisible,例如:

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!

转换子视图的子视图的矩形

Carter 的回答让我开始了,但我需要做的是使用 ConvertRectFromView 获取与顶级 ScrollView 相关的 TextField 的坐标:

CGRect frame = currentStep.ScrollView.ConvertRectFromView(tf.Frame, tf.Superview);

currentStep.ScrollView.ScrollRectToVisible(frame, true);

这为我提供了 TextField 在滚动视图中的位置,而不是 Cell 中的坐标。添加后滚动按预期工作。

支持信息

Apple 文档:https://developer.apple.com/reference/uikit/uiview/1622498-convertrect?language=objc

帮助我理解如何使用该方法的 link:http://www.infragistics.com/community/blogs/torrey-betts/archive/2013/05/06/quick-tip-convert-coordinate-system-of-a-uiview.aspx

Objective C 用法:

- (CGRect)convertRect:(CGRect)rect 
         fromView:(UIView *)view;