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

Posted

技术标签:

【中文标题】在输入文本时保持居中的同时动态调整 UITextField 大小的正确方法是啥?【英文标题】:What's the proper way to dynamically resize a UITextField while keeping it centered as text is entered?在输入文本时保持居中的同时动态调整 UITextField 大小的正确方法是什么? 【发布时间】:2014-04-13 11:41:28 【问题描述】:

给定一个文本字段,我希望它在用户输入文本时水平动态调整大小。我还希望它保持在其超级视图的中心。我偶然发现了一种方法来做到这一点,但它似乎是做作的,不太可能是正确的方法。我觉得我在这里遗漏了一些简单的东西,例如文本字段或控件的属性或我不熟悉的某些协议。

在 Interface Builder 中,我有一个带有文本“__”的 UITextField。它有两个约束,距顶部 100 像素,垂直居中。 ViewController 是文本字段的委托,并且 Editing Changed 事件被发送到 textFieldAction:

- (IBAction)textFieldAction:(UITextField *)sender 
    NSString *s = sender.text;
    CGSize newSize = [sender sizeThatFits:CGSizeMake(MAXFLOAT, MAXFLOAT)];
    CGRect newFrame = sender.frame;
    newFrame.size = newSize;
    sender.frame = newFrame;
    sender.text = s;


- (BOOL)textFieldShouldReturn:(UITextField *)textField 
    [textField resignFirstResponder];
    return YES;


- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField 
    textField.text = @"";
    return YES;

奇怪的是

如果我没有在 textFieldShouldBeginEditing 中将文本设置为 @"": 文本字段不会动态调整大小

如果我不重新分配 textFieldAction: 中的文本,则文本字段会动态调整大小但不会动态保持居中。

在这两种情况下,最终都会在文本字段退出第一响应者时调整布局。

这是获得动态调整大小和居中文本字段的正确方法,还是 hack?

【问题讨论】:

你能设置一些断点或日志并确定这些方法被调用的顺序吗?最具体地说,是 textViewAction: 在您点击文本字段时调用一次还是两次?如果两次,谁是发件人? textFieldAction: 每次按键调用一次。发件人是文本字段。 textFieldShouldBeginEditing:在我点击 textField 时调用,textFieldAction:每次点击时调用一次,textFieldShouldReturn:在我点击“return”时调用。 经过更多实验,似乎 textFieldShouldBeginEditing: 只需要一行:sender.text = sender.text; 重新分配字符串是必要的,但也足够了。 hack 看起来很有吸引力。 【参考方案1】:

这对我来说似乎是一个 hack,但我现在无法测试我自己的建议。 如果我试图在用户输入期间保持文本字段居中,我会使用

-(BOOL)textField:(UITextField)shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

在 UITextFieldDelegate 协议中并在那里进行计算。 在此过程中,您还可以尝试[textfield sizeToFit] 以完全摆脱计算。

您也可以摆脱约束,只需设置textfield.center.x = [[UIScreen mainScreen] screensize].width / 2textfield.center.x = textfield.superview.center.x 以使其水平居中。或者你坚持使用自动布局,我只是不太喜欢。

来自 textField:shouldChangeCharactersInRange:replacementString: 的文档:

Return Value:  
YES if the specified text range should be replaced; otherwise, NO to keep the old text.

Discussion:  
The text field calls this method whenever the user types a new character in the text field or deletes an existing character.`

所以请务必返回“是”,如果您尝试,请告诉我结果如何。

【讨论】:

谢谢,刚刚试了一下你的建议,但是使用textField:shouldChangeCharactersInRange:replacementString:的效果和使用action差不多。如果文本字符串未在 textFieldShouldBeginEditing 中设置为 @"" 并在 textField:shouldChangeCharactersInRange:replacementString: 中重新分配,则文本字段不会动态调整大小。 顺便说一句,我确实尝试了您的建议,用 sizeToFit 替换框架调整大小计算,这是一个改进。谢谢。

以上是关于在输入文本时保持居中的同时动态调整 UITextField 大小的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用视口动态调整 3x3 方格的大小

CSS:居中对齐文本,同时将容器的其他元素保持在左侧[重复]

元素不会保持居中,尤其是在调整屏幕大小时

调整浏览器大小时,如何使部分中的对象保持居中?

切换uitextf时停止键盘关闭

调整大小后如何保持表单居中在屏幕中间