如何根据input的文本增加文本字段的宽度?

我需要根据其内容增加文本字段的宽度。 当用户input文本时,文本字段大小应该自动增加。 我有一个closures(X)button旁边的文本字段。

我限制了文本字段和button,使文本字段居中在屏幕上,并且button与其相邻。 (文本字段应该是可编辑的,button应该是可点击的)

文本字段大小是这样的:

在这里输入图像说明

当我input文字时,尺寸应该会自动增加:

在这里输入图像说明

我怎样才能做到这一点?

我解决了我的问题:使用这个文本字段不在屏幕之外。

func getWidth(text: String) -> CGFloat { let txtField = UITextField(frame: .zero) txtField.text = text txtField.sizeToFit() return txtField.frame.size.width } func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool { let width = getWidth(textField.text!) if UIScreen.mainScreen().bounds.width - 55 > width { txtWidthOfName.constant = 0.0 if width > txtWidthOfName.constant { txtWidthOfName.constant = width } self.view.layoutIfNeeded() } return true } 

目标C版本

 -(CGFloat)getWidth:(NSString *)text{ UITextField * textField = [[UITextField alloc]initWithFrame:CGRectZero]; textField.text = text; [textField sizeToFit]; return textField.frame.size.width; } -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { if (self.textFieldName.isEditing == YES) { CGFloat width = [self getWidth:textField.text]; if ([UIScreen mainScreen].bounds.size.width - 60 > width) { self.txtWidthOfName.constant = 0.0; if (width > self.txtWidthOfName.constant) { self.txtWidthOfName.constant = width; } [self.view layoutIfNeeded]; } } return YES; } 

一个厚脸皮的解决方法,以获得一个特定的string的宽度将是

 func getWidth(text: String) -> CGFloat { let txtField = UITextField(frame: .zero) txtField.text = text txtField.sizeToFit() return txtField.frame.size.width } 

为了获得宽度,

 let width = getWidth(text: "Hello world") txtField.frame.size.width = width self.view.layoutIfNeeded() // if you use Auto layout 

如果你有一个约束txtField的宽度然后做

 yourTxtFieldWidthConstraint.constant = width self.view.layoutIfNeeded() // if you use Auto layout 

编辑我们正在创build一个基本上全零的框架的UITextField。 当你调用sizeToFit()的时候,它会设置UITextField的框架,使其显示它的所有内容,并且没有多余的空格。 我们只想要它的宽度,所以我返回了新创build的UITextField的宽度。 ARC会照顾我们从内存中删除它。

更新

 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { if textField.text != nil { let text = textField.text! as NSString let finalString = text.replacingCharacters(in: range, with: string) textField.frame.size.width = getWidth(text: finalString) } return true } 

你可以通过重写UITextField类来实现它,并返回intrinsicContentSize自定义值。 此外,您还需要订阅文本更改事件,并在文本更改animation时使内容内容大小无效

这里是Swift 3中的例子

 class Test: UITextField { override init(frame: CGRect) { super.init(frame: frame) setupTextChangeNotification() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) setupTextChangeNotification() } func setupTextChangeNotification() { NotificationCenter.default.addObserver( forName: Notification.Name.UITextFieldTextDidChange, object: self, queue: nil) { (notification) in UIView.animate(withDuration: 0.05, animations: { self.invalidateIntrinsicContentSize() }) } } deinit { NotificationCenter.default.removeObserver(self) } override var intrinsicContentSize: CGSize { if isEditing { if let text = text, !text.isEmpty { // Convert to NSString to use size(attributes:) let string = text as NSString // Calculate size for current text var size = string.size(attributes: typingAttributes) // Add margin to calculated size size.width += 10 return size } else { // You can return some custom size in case of empty string return super.intrinsicContentSize } } else { return super.intrinsicContentSize } } } 

实现UITextFieldDelegate以下方法。 使用由Matt提供的方法来获得所需的textField的宽度。 在自动布局中,确保您已经为textfield设置了中心和宽度约束。 在代码文件中为您的宽度约束创buildIBOutlet。 另外请确保你设置了你的textField的委托属性

 @IBOutlet weak var widthConstraint: NSLayoutConstraint! func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { let width = getWidth(text : textField.text) if width > widthConstraint.constant { widthConstraint.constant = width } self.layoutIfNeeded() return true } 

我认为这是一个更好的解决scheme,而不是有一个宽度约束,你必须修改:

在input时调整UITextField的大小(使用Autolayout)

 - (IBAction) textFieldDidChange: (UITextField*) textField { [UIView animateWithDuration:0.1 animations:^{ [textField invalidateIntrinsicContentSize]; }]; } 

如果需要,可以省略animation。

编辑 :这是一个示例项目: https : //github.com/TomSwift/growingTextField

答案都需要一堆代码,但你可以做所有的界面生成器; 没有需要的代码。

只要将textFieldembedded到UIStackView中,并将stackView限制为小于或等于其superview减去一些常数(如果你想要,也可以给它一个最小宽度)。 stackView会照顾到textField的固有尺寸,或者是stackView的最大宽度(这个尺寸越小越好),所以你可以自动input尺寸的大小来适应内容。

似乎很令人沮丧的是,没有直接的方式,像IB自己的UILabel有“Autoshrink”到“Minimum Font size”。 IB中的“调整为适合”文本字段也不好。

为什么苹果让我们编写所有这些样板代码,当文本字段需要Autoshrink时,如果不超过UILabel的话!