UITextField 调整大小问题

Posted

技术标签:

【中文标题】UITextField 调整大小问题【英文标题】:UITextField resize issue 【发布时间】:2013-11-15 09:48:05 【问题描述】:

我发现 UITextField 存在问题。我创建了一个 uitexfield 的子类,它允许用户单击文本开始编辑,然后旋转和调整文本大小。

如果通过增大高度来调整文本字段的大小,即使文本字段的宽度没有增加,居中的文本也会向右移动。我对此进行了调查,发现 uitextfield 具有 UIFieldEditor 类型的内部视图,而 UIFieldEditor 又具有 _UIFieldEditorContentView 视图。 UIFieldEditor 似乎是 UIScrollView 的子类,并且此滚动视图的内容大小变得比 uitextview 的大小大得多。当 textview 增加它的高度时,scrollviews contentsize 宽度增加。我猜这可能是内部自动布局问题。

我在此处添加了一个演示项目来演示该问题。单击文本开始编辑,然后拖动调整大小图标,使高度增加,您将看到问题。

https://github.com/permagnus/UITextField-Resize-Issue-Demo

来自revealapp的截图:

滚动视图中底层视图的大小不正确:https://github.com/permagnus/UITextField-Resize-Issue-Demo/blob/master/Screenshots/screenshot-showing-incorrect-size.png

uitextfield的实际大小:https://github.com/permagnus/UITextField-Resize-Issue-Demo/blob/master/Screenshots/screenshot-showing-textfield-size.png

关于如何解决此问题的任何想法?

【问题讨论】:

【参考方案1】:

我找到了两种解决问题的方法:

问题在于底层滚动视图。一种方法是找到滚动视图并确定它的偏移量并补偿错误的偏移量:

- (CGRect)editingRectForBounds:(CGRect)bounds

    CGRect editRect = [super editingRectForBounds:bounds];

    UIScrollView *scrollView = [self findScrollViewFromView:self];

    if(scrollView)
    
        float diff = (self.bounds.size.width - scrollView.contentSize.width)/2;
        return CGRectInset(editRect, diff, 0);
    

    return editRect;


- (UIScrollView *)findScrollViewFromView:(UIView *)view

    if([view isKindOfClass:[UIScrollView class]])
    
        return (UIScrollView *) view;
    

    for(UIView *v in view.subviews)
    
        UIScrollView *scrollView = [self findScrollViewFromView:v];

        if(scrollView)
        
            return scrollView;
        
    

    return nil;

我还联系了 Apple 支持以了解他们的问题所在。他们确认这可能是一个错误,我已将其作为一个错误提交。他们的解决方案如下:

字段编辑器仅针对当前编辑会话激活,因此您可以 结束文本字段的编辑会话(通过调用 resignFirstResponder),然后再调整大小(在 touchesBegan 中...?)。在 你的情况,我想保持编辑会话可能不是 必要的。

如果你真的需要保持编辑会话,一个解决方案(丑陋)我 可以看到是重置文本并确保光标在 文档开头:

self.text = [self.text copy];
UITextPosition *beginningOfDocument = [self positionFromPosition:self.beginningOfDocument offset:0];
self.selectedTextRange = [self textRangeFromPosition:self.beginningOfDocument toPosition:beginningOfDocument];

这两种解决方案都是糟糕的 hack,不推荐使用,因此使用这些解决方案需要您自担风险 :)

【讨论】:

感谢您找到这些解决方法。使用苹果建议。在任何 becomeFirstResponder 之后调用类似这样的私有 func resetTextField(textField: UITextField) let text = textField.text textField.text = "" textField.text = text

以上是关于UITextField 调整大小问题的主要内容,如果未能解决你的问题,请参考以下文章

iPhone——获取 UITextField 调整后的字体大小

以编程方式调整 UITextField 的大小会自动恢复为旧大小

在 UITableViewCell 中自动调整 UITextField 的大小

触发 UITextField 时同步向上滑动 UIView 并调整 UITableView 的大小

在输入文本时保持居中的同时动态调整 UITextField 大小的正确方法是啥?

根据输入的文本调整 UITextField 的大小和位置