[英]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
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.