简体   繁体   English

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

[英]How to increase width of textfield according to typed text?

I need to increase a text field's width according to its content. 我需要根据文本字段的内容增加文本字段的宽度。 When the user inputs text, then the textfield size should increase automatically. 当用户输入文本时,文本字段大小应自动增加。 I have one close (X) button next to this text field. 我在这个文本字段旁边有一个关闭(X)按钮。

I have constrained the text field and button so that the text field is centered on screen, and the button is adjacent to it. 我已经约束了文本字段和按钮,以便文本字段在屏幕上居中,并且按钮与它相邻。 (Text field should be editable, button should be clickable) (文本字段应该是可编辑的,按钮应该是可点击的)

Text field size is this: 文本字段大小是这样的:

在此输入图像描述

When I enter text in it, the size should automatically increase: 当我在其中输入文本时,大小应自动增加:

在此输入图像描述

How can I achieve this? 我怎样才能做到这一点?

I solve my problem : use this for textfield not go outside of screen. 我解决了我的问题:用于文本字段而不是屏幕之外。

 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
}

Objective C Version 目标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;
}

You can achieve it with overriding UITextField class and return custom value in intrinsicContentSize . 您可以通过重写UITextField类来实现它,并在intrinsicContentSize返回自定义值。 Also you need to subscribe to text change event and invalidate intrinsic content size on text change animated 此外,您还需要订阅文本更改事件,并在文本更改动画时使内在内容大小无效

Here is example in Swift 3 这是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
        }
    }
}

A cheeky workaround to get width for a particular string would be 获得特定字符串宽度的厚颜无耻的解决方法是

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

And to get the width, 并获得宽度,

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

If you have a constraint linked to txtField's width then do 如果你有一个与txtField的宽度相关联的约束,那么就做

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

Edit We are creating a UITextField with a frame of basically all zeros. 编辑我们正在创建一个UITextField,其框架基本上都是零。 When you call sizeToFit(), it will set the frame of UITextField in a way that it will show all of its content with literally no extra spaces around it. 当你调用sizeToFit()时,它将以一种方式设置UITextField的框架,它将显示其所有内容,并且周围没有额外的空格。 We only wanted its width, so I returned the width of the newly created UITextField. 我们只想要它的宽度,所以我返回了新创建的UITextField的宽度。 ARC will take care of removing it from memory for us. ARC将负责将它从内存中删除。

Update 更新

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
    }

Implement following method of UITextFieldDelegate . 实现UITextFieldDelegate以下方法。 Use approach provided by Matt to get required width of textField. 使用Matt提供的方法获得textField所需的宽度。 In auto layout make sure you have centre and width constraints set for textfield. 在自动布局中,请确保为文本字段设置了中心和宽度约束。 Create IBOutlet for your width constraint in code file. 在代码文件中为宽度约束创建IBOutlet。 Also make sure you set delegate property of your textField 还要确保设置textField的delegate属性

@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
}

The answers all require a bunch of code, but you can do everything interface builder; 答案都需要一堆代码,但你可以做一切界面构建器; no code needed. 无需代码。

Just embed the textField in a UIStackView and constrain the stackView to be less than or equal to its superview minus some constant (if you want you can also give it a minimum width). 只需将textField嵌入到UIStackView中,并将stackView约束为小于或等于其superview减去某个常量(如果你想要,你也可以给它一个最小宽度)。 The stackView will take care of always making the textField its intrinsic size, or the maxwidth of the stackView (which ever is smaller), so as you type the size changes automatically to fit the content. stackView将始终使textField成为其固有大小,或者stackView的最大宽度(通常更小),因此当您键入大小更改以适应内容时。

I think this is a better solution than having a width constraint that you have to modify: 我认为这是一个比你必须修改的宽度约束更好的解决方案:

Resize a UITextField while typing (by using Autolayout) 键入时调整UITextField的大小(使用Autolayout)

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

You can omit the animation if desired.. 如果需要,您可以省略动画..

EDIT : Here's an example project: https://github.com/TomSwift/growingTextField 编辑 :这是一个示例项目: https//github.com/TomSwift/growingTextField

We can easily make it by setting UITextField constraints like this: 我们可以通过设置UITextField约束来轻松实现:

在此输入图像描述

//Tested on Xcode 9.1, Swift 4 //在Xcode 9.1,Swift 4上测试

Output: 输出:

在此输入图像描述

Seems so frustrating that there is no direct way like there is "Autoshrink" to "Minimum Font size" for UILabel in IB itself. 似乎令人沮丧的是,没有直接的方式,就像在IB本身的UILabel中“自动收缩”到“最小字体大小”一样。 The "Adjust to Fit" in IB for a textfield is no good too. 对于文本字段,IB中的“调整到适合”也不是很好。

Why does Apple make us write all this boilerplate code, when a text field needs Autoshrink as much if not more than the UILabel! 为什么Apple让我们编写所有这些样板代码,当文本字段需要自动收缩时,如果不超过UILabel!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何根据标题标签文本的变化增加/减少 UIButton 宽度? - How to Increase/decrease UIButton width according to title lable text changes? 如何根据UITableView中的文本增加UILabel的高度? - How to increase UILabel hight according to text in UITableView? 如何根据文本使UICollectioncell宽度动态 - How to make UICollectioncell width dynamic according to text 编辑时如何根据TextField内容更改标签文本 - How to change label text according to TextField content while edited 根据文本字段中的键入文本显示消息 - Show message depending on typed text in textfield 如何在Swift 3的静态表格视图中根据文本增加textview的大小 - how to increase the textview size according to text in static table view in swift 3 如何根据文本长度增加UITextview高度,如whatsapp - How to increase UITextview height according to text length like whatsapp 如何根据标题文本增加UIButton的高度? - How to increase UIButton height according to its title text? 如何调整 TextField() 文本的大小以适应 Expanded() 小部件的最大宽度 - How to resize TextField() text to fit the max width of an Expanded() widget 使用`textField:shouldChangeCharactersInRange:`,如何获取包含当前输入字符的文本? - Using `textField:shouldChangeCharactersInRange:`, how do I get the text including the current typed character?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM