ios - UIScrollView 与 UITextField/UIPickerView 的奇怪行为

标签 ios swift uiscrollview uitextfield uipickerview

所以我现在很困惑,因为我的 UIScrollView 表现得很奇怪。

基本上,我有一个 UIScrollView,大约是 iPhone 6 高度的两倍,我用它来显示一些使用 iOS 图表的图表,所以我将它设置为能够垂直滚动和弹跳,但既不滚动也不滚动水平弹跳。所有图表以及一些额外的 UITextFields 和 UILabels 都嵌入在一个单独的“主体 View ”上,该 View 与 UIScrollView 的框架对齐,这似乎是常见的做法。因此,我的 View 的层次结构如下所示:

hierarchy

这种方法工作得很好,直到今天我注意到当我在这个 UIScrollView 上按下特定的 UITextField 时,它会触发 UIPickerView,突然间我的 ScrollView 开始允许水平弹跳。当点击正文 View 上的另外两个 UITextField 时,不会发生此行为。

我已经检查了通过点击受影响的文本字段触发的所有代码,没有任何代码直接编辑任何 UI 对象的框架或边界。事实上,点击文本字段时调用的唯一函数是 textFieldDidBeginEditing。我在下面附上了该函数的代码,但我相当确定这不是问题。

我的下一个怀疑是弹出的 UIPickerView 扰乱了我的 ScrollView 和/或其嵌入 View 的尺寸。我不太确定这是否可能/可能,但这整件事让我很困惑。

这是我的代码:

func textFieldDidBeginEditing(_ textField: UITextField) {
    
    if textField == overallTimeframeTextField {
        ...
        // Not the problematic text field
    } else if textField == subjectTimeframeTextField {
        ...
        // Also not the problematic text field
    } else { // Affected text field
        
        // Set the text of the text field
        if textField.text == "" {
            // This is executed in this scenario
            textField.text = subjectPickerData[0]
        } else {
            ...
        }
    }
}

这是一个简短的 GIF,概述了我的问题。您可以看到我向下滚动页面,但无法水平弹跳,然后一旦我在文本字段上标记, ScrollView 突然允许弹跳。

GIF

我对这个问题很困惑,因此我们将不胜感激。

编辑

为了澄清,我明确声明我的 ScrollView 的内容大小等于用户所在屏幕的所需高度和宽度。然后我将 bodyView 的宽度设置为相同的值。这是在 viewDidAppear 中使用以下代码完成的:

// Fit the content to the screen
scrollView.contentSize = CGSize(width: UIScreen.main.bounds.width, height: 1200)
bodyView.frame.size.width = UIScreen.main.bounds.width

我还有一些约束,强制 ScrollView 和主体 View 都具有与 UIViewController 的默认 subview (层次结构中 ScrollView 的父 View )相同的宽度。

我注意到的一件有趣的事情是,当我在 View 加载时打印 ScrollView 和正文 View 的宽度时,我会收到以下 iPhone 6 的输出:

385.0

385.0

这是正确的,因为这是 iPhone 6 的宽度。但是,当我点击文本字段,然后打印相同的值时,我得到以下输出:

385.0

384.0

因此,由于某种原因,我的 body View 比我的 ScrollView 小一个点。当我点击文本字段时,我尝试将正文 View 的宽度设置为等于 ScrollView ,就像我在 viewDidAppear 函数中所做的那样,但这没有效果。

就 UIPickerView 而言,我使用类实例变量初始化一个 pickerview,如下所示:

var subjectPickerView = UIPickerView()

然后,我将此选取器 View 指定为 viewDidLoad 中文本字段的输入 View :

textField.inputView = subjectPickerView

所以我不确定这是否会使选择器 View 成为 ScrollView 的 subview ,但在这种情况下它只是替换键盘。

最佳答案

感谢 @AchmadJP 的评论,我尝试在 ScrollView 和主体 View 之间显式创建相等的宽度约束。这似乎已经解决了问题。

我之前没有这样做的原因是主体 View 的前导空间、尾部空间、顶部空间和底部空间被限制为与 ScrollView 的相同。从理论上讲,这应该意味着宽度始终相等,但显然情况并非如此。

关于ios - UIScrollView 与 UITextField/UIPickerView 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46096014/

相关文章:

swift - 不能从其他类调用函数

ios - UITableVIewCell 中的 UIScrollView 不会滚动

ios - swift 为 collectionView 正确关闭键盘

ios - 如何获取leftBarButtonItem的宽度?

ios - 如何从另一个单例类更新 UISlider?

ios - 无法初始化参数

ios - ios中如何根据字段大小滚动 ScrollView

ios - 无法在 swift ios 或 mac os 中获取公共(public) IP

ios - 这个弹出窗口类的名称是什么?

ios - EDT 无法与 NSDateFormatter 一起使用