我需要根据文本字段的内容增加文本字段的宽度。当用户输入文本时,文本字段大小应自动增加。我在这个文本字段旁边有一个关闭(X)按钮。
我已经约束了文本字段和按钮,以便文本字段在屏幕上居中,并且按钮与它相邻。 (文本字段应该是可编辑的,按钮应该是可点击的)
文本字段大小为:
当我在其中输入文字时,尺寸应自动增加:
我怎样才能做到这一点?
答案 0 :(得分:11)
我解决了我的问题:将此文本字段用于不在屏幕之外。
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;
}
答案 1 :(得分:11)
您可以通过覆盖UITextField
类来实现它,并在intrinsicContentSize
中返回自定义值。此外,您还需要订阅文本更改事件,并在文本更改动画
以下是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
}
}
}
答案 2 :(得分:7)
获取特定字符串宽度的厚颜无耻的解决方法是
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
修改强> 我们正在创建一个UITextField,其框架基本上都是零。当你调用sizeToFit()时,它将以一种方式设置UITextField的框架,它将显示其所有内容,并且周围没有额外的空格。我们只想要它的宽度,所以我返回了新创建的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
}
答案 3 :(得分:3)
实施UITextFieldDelegate
的以下方法。使用Matt提供的方法获得textField所需的宽度。在自动布局中,请确保为文本字段设置了中心和宽度约束。在代码文件中为宽度约束创建IBOutlet。还要确保设置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
}
答案 4 :(得分:3)
答案都需要一堆代码,但你可以做一切界面构建器;无需代码。
只需将textField嵌入到UIStackView中,并将stackView限制为小于或等于其superview减去某个常量(如果你想要,你也可以给它一个最小宽度)。 stackView将始终使textField成为其固有大小,或者stackView的最大宽度(通常更小),因此当您自动键入大小更改以适应内容时。
答案 5 :(得分:3)
我认为这是一个比你必须修改的宽度约束更好的解决方案:
Resize a UITextField while typing (by using Autolayout)
- (IBAction) textFieldDidChange: (UITextField*) textField
{
[UIView animateWithDuration:0.1 animations:^{
[textField invalidateIntrinsicContentSize];
}];
}
如果需要,您可以省略动画..
编辑:这是一个示例项目:https://github.com/TomSwift/growingTextField
答案 6 :(得分:2)
答案 7 :(得分:0)
似乎非常令人沮丧,因为没有像#34; Autoshrink&#34;到&#34;最小字体大小&#34;对于IB本身的UILabel
。
&#34;调整适合&#34;在IB中,文本字段也不好。
为什么Apple让我们编写所有这些样板代码,当文本字段需要自动收缩时,如果不超过UILabel那么多!