24

我在 UITextField 中有一个自定义字体,并且我注意到当它被访问时(当键盘出现时),文本会向下移动一个非常小的量 - 可能是一个像素或两个或三个像素。(当然,我无法测量它,但这足以让我注意到。)然后当键盘被关闭时,它又会再次向上移动。

我尝试在编辑时清除该字段(这隐藏了初始下移的问题),但它并没有解决问题。我还查看了 IB 中的各种属性,并尝试更改一些,但问题仍然存在。我在模拟器和我的 iPad2 上得到了相同的结果。

(该字段很清楚键盘,所以它不是整个视图移开 - 它只是该特定文本字段的内容。)

我确定这是导致问题的自定义字体——没有它就不会发生。

知道如何解决这个问题吗?我在想我可能需要以编程方式创建文本字段,而不是在 IB 中——我知道我可能应该在问这个问题之前尝试一下,但如果它不会,我不愿意去麻烦解决这个问题。

任何建议表示赞赏!

4

10 回答 10

16

我也有这个问题。

修复,子类UITextField化并实现以下方法以在不编辑和编辑时调整文本的位置。

- (CGRect)textRectForBounds:(CGRect)bounds {

    return CGRectInset( bounds , 8 , 8 );
}

- (CGRect)editingRectForBounds:(CGRect)bounds {

    return CGRectInset( bounds , 8 , 5 );
}
于 2012-04-10T10:41:58.370 回答
3

我的解决方案与 McDJ 的做法相同,但略有不同。子类 UITextField 并仅覆盖这些:

- (CGRect)placeholderRectForBounds:(CGRect)bounds {
  return CGRectOffset( [self editingRectForBounds:bounds], 0, 2 );
}

- (CGRect)editingRectForBounds:(CGRect)bounds {
  return CGRectOffset( [super editingRectForBounds:bounds], 0, -2 );
}

使用我使用的自定义字体,2 点是正确的垂直调整,有助于占位符、“静态”和“编辑”文本都保持在同一垂直线上。

于 2012-09-09T21:50:09.557 回答
2

不幸的是,没有一个答案对我有用。

@blackjacx 答案有效,但只是有时:(

我开始调试,这是我发现的:

1 -真正的问题似乎在于 UITextField 类型的私有子视图 UIFieldEditorContentView

UITextField 视图层次结构

下面你可以看到y它的子视图与它UITextField本身的不同:

Y 未设置为 0

意识到这一点后,我提出了以下解决方法:

override func layoutSubviews() {
    super.layoutSubviews()
    fixMisplacedEditorContentView()
}

func fixMisplacedEditorContentView() {
    if #available(iOS 10, *) {
        for view in subviews {
            if view.bounds.origin.y < 0 {
                view.bounds.origin = CGPoint(x: view.bounds.origin.x, y: 0)
            }
        }
    }
}

您将需要子类化UITextField和覆盖layoutSubviews以添加手动设置为0任何y设置为负值的子视图的功能。由于 iOS 9 不会出现此问题,因此我们在下面添加了一项检查以仅在 iOS 10 上执行解决方法。

您可以在下面看到结果:

好好工作

2 - 如果用户选择选择文本的子范围,则此解决方法不起作用(selectAll 工作正常)

由于文本的选择对于我的应用程序来说不是必须的,我宁愿禁用它。为此,您可以使用以下代码(Swift 3):

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    if #available(iOS 10, *) {
        if action == #selector(UIResponderStandardEditActions.select(_:)) {
            return false
        }
    }

    return super.canPerformAction(action, withSender: sender)
}
于 2017-04-13T19:29:52.183 回答
1

适用于所有字体大小,并且不会导致与clearButton.

子类化UITextField并覆盖它们,如下所示:

- (CGRect)placeholderRectForBounds:(CGRect)bounds
{
    return CGRectOffset( bounds, 0, 4 );
}

- (CGRect)editingRectForBounds:(CGRect)bounds
{
    return CGRectOffset( bounds, 0, 2);
}

- (CGRect)textRectForBounds:(CGRect)bounds
{
    return CGRectOffset( bounds , 0 , 4 );
}
于 2012-11-13T15:24:21.533 回答
1

出于一个奇怪的原因,我并没有真正理解我已经通过将 automaticAdjustsScrollViewInsets 设置为 NO(或在 Interface Builder 中等效)来解决这个问题。这与 iOS 8.1。

于 2016-02-24T17:13:40.003 回答
0

我在使用自定义字体时遇到了这个问题,并通过在键盘事件触发时将标签向另一个方向移动来解决它。我通过覆盖drawRect:方法移动了按钮中标签的中心

- (void)drawRect:(CGRect)rect
{
    self.titleLabel.center = CGPointMake(self.titleLabel.center.x, self.titleLabel.center.y+3);
}
于 2012-02-03T03:27:23.127 回答
0

这是标准 UITextField 中的预期行为。但是,您可以通过子类化 UITextField 并调整文本本身的边界来解决此问题。

斯威夫特 3

override func textRect(forBounds bounds: CGRect) -> CGRect {
    return(bounds.insetBy(dx: 0, dy: 0))
}

override func editingRect(forBounds bounds: CGRect) -> CGRect {
    return(bounds.insetBy(dx: 0, dy: -0.5))
}

override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
    return(bounds.insetBy(dx: 0, dy: 0))
}

这应该可以解决问题!

于 2016-10-27T11:18:15.910 回答
0

斯威夫特 3

不要忘记accessory viewsUITextField 的。如果您想要一个有效的实现,您需要考虑super*rect(forBounds: ...) 函数。并且还要确保只替换越野车的矩形iOS 10而不是 9 或 8!以下代码应该可以解决问题:

public class CustomTextField: UITextField {
    public override func textRect(forBounds bounds: CGRect) -> CGRect {
        let superValue = super.textRect(forBounds: bounds)

        if #available(iOS 10, *) {
            return superValue.insetBy(dx: 0, dy: 0)
        }
        return superValue
    }

    public override func editingRect(forBounds bounds: CGRect) -> CGRect {
        let superValue = super.editingRect(forBounds: bounds)

        if #available(iOS 10, *) {
            return superValue.insetBy(dx: 0, dy: -0.5)
        }
        return superValue
    }

    public override func placeholderRect(forBounds bounds: CGRect) -> CGRect {
        let superValue = super.placeholderRect(forBounds: bounds)

        if #available(iOS 10, *) {
            if isEditing {
                return superValue.insetBy(dx: 0, dy: 0.5)
            }
            return superValue.insetBy(dx: 0, dy: 0.0)
        }
        return superValue
    }
}

编辑

我从上面稍微编辑了我的代码到下面,它对我来说效果更好。我在 iPhone 6、6s、7、7s 以及 iOS 9.3 和 10.3 的“加号”设备上测试它。

public class CustomTextField: UITextField {

    public override func textRect(forBounds bounds: CGRect) -> CGRect {
        let superValue = super.textRect(forBounds: bounds)

        if #available(iOS 10, *) {
            return superValue.insetBy(dx: 0, dy: -0.3)
        }
        return superValue.insetBy(dx: 0, dy: -0.2)
    }

    public override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return self.textRect(forBounds: bounds)
    }
}

我认为这也取决于您使用的字体。我用UIFont.systemFont(ofSize: 17.0, weight: UIFontWeightLight)

于 2017-04-05T23:44:44.777 回答
0

将您的文本字段边框样式设置为除 IB 中的“无”之外的任何值,然后在您的 ViewController 的 viewDidLoad 集中:

yourTextField.borderStyle = .none

(基于Box Jeon的这个答案)

于 2017-02-02T22:25:36.140 回答
-1

您应该在 Text 属性之前设置 Font 属性。

于 2014-04-30T11:33:35.063 回答