【问题标题】:Auto-Stretching UITextField on typing键入时自动拉伸 UITextField
【发布时间】:2016-05-09 11:04:15
【问题描述】:

我有一个UITextField,是我以编程方式创建的。我想在开头和结尾有不可编辑的前缀字符,例如

"Hello [TextField] world". 

首先,我尝试手动添加字符并使用shouldChangeCharactersInRange make 但这种方法不起作用,因为如果用户长按 TextField 并开始,他可以编辑第一个字符(所以可以弄乱前缀人物)。这个选项似乎不太方便。


另一个选项可能是创建一个空的UITextField 和 2 个静态的UILabels(用于“Hello”和“world”)。这里,又出现了一个问题。由于我的UITextField 的文本居中对齐(并且在视图中垂直居中),因此我给它一个视图的宽度和 x 轴的 0(因此 textField 会同时触及视图的左右边缘)。相反,如果我在创建时尝试为 TextField 提供固定宽度,则宽度不会在用户输入时扩展/拉伸。

我想要实现的是从 0 开始 TextField 的宽度,并且在每一侧都有静态的 UILabels,如 "hello "[textField]" world";当用户输入时,向左和向右增加/拉伸 textField 的宽度(因为它是 textaligned center)。随着 textField 的宽度延伸,将UILabel 推向边缘。所以:

|          ["Hello "][textField][" world"]         |

|    ["Hello "][MyTextFieldTextIsNice][" world"]   |

不使用 Storyboard 并以编程方式实例化 UITextFieldUILabels 的正确方法是什么?如何在用户键入时创建自动调整大小的文本字段,将 UILabel 推到两侧?

【问题讨论】:

    标签: ios swift autolayout uitextfield uilabel


    【解决方案1】:

    我用这种情况,用StoryboardUITextField两边用UILabel居中对齐。

    下面是storyboard的截图。

    然后我正在做UITextField 的委托并使用以下代码。

    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
    {
    
        NSString *strForWholeString = [NSString stringWithFormat:@"%@%@",textField.text,string];
    
        CGSize fontSize = [strForWholeString sizeWithAttributes:
                           @{NSFontAttributeName:
                                 [UIFont fontWithName:@"Helvetica" size:14]}];
    
    
    
        if (self.textfieldLayoutWidthConstraint.constant >= 40) {
            self.textfieldLayoutWidthConstraint.constant = fontSize.width + 40 ;
            [self.view layoutIfNeeded];
            [self.view setNeedsUpdateConstraints];
        }
    
        return YES;
    }
    

    Swift 代码

    func textField(textField: UITextField!, shouldChangeCharactersInRange range: NSRange, replacementString string: String!) -> Bool {
    
            let strForWholeString = NSString(format:"%@%@", textField.text!,string) as String
    
            let fontSize: CGSize = strForWholeString.sizeWithAttributes([NSFontAttributeName: UIFont.systemFontOfSize(14.0)])
    
            if self.textfieldLayoutWidthConstraint?.constant >= 40 {
                self.textfieldLayoutWidthConstraint!.constant = fontSize.width + 40 ;
                self.view.layoutIfNeeded();
                self.view.setNeedsUpdateConstraints();
            }
            return true
        }
    

    希望这对您有很大帮助。

    You can download the sample code from here - Objective c

    You can download the sample code from here - Swift

    输出

    【讨论】:

    • 有没有办法在不限制宽度的情况下做到这一点?
    • @Irfan 你需要像明智的Jonas 回答一样检查字符。
    【解决方案2】:

    我不相信您可以将文本添加到不可编辑的文本字段中,但您可以做的是自动检查输入的文本并在前面加上“Hello”并附加“world”。

    您首先必须检查输入的文本。你可以这样做:

    var charArray: [Character] = []
    
    for character in textField.characters {
    charArray.append(character) }
    

    这会给你一个字符数组。然后您可以检查第一个字符是否仍然是“Hello”,最后一个字符是否仍然是“world”:

    func checkInputStartsHello() -> Bool {
    
    guard charArray[0] == "H" else { return false }
    guard charArray[1] == "e" else { return false }
    guard charArray[2] == "l" else { return false }
    guard charArray[3] == "l" else { return false }
    guard charArray[4] == "o" else { return false }
    guard charArray[5] == " " else { return false }
    
    return true
    }
    
    func checkInputEndsWorld() -> Bool {
    
    guard charArray[charArray.count - 1] == "d" else { return false }
    guard charArray[charArray.count - 2] == "l" else { return false }
    guard charArray[charArray.count - 3] == "r" else { return false }
    guard charArray[charArray.count - 4] == "o" else { return false }
    guard charArray[charArray.count - 5] == "w" else { return false }
    guard charArray[charArray.count - 6] == " " else { return false }
    
    return true
    }
    

    如果这些为假,则添加“Hello”和“world”:

    if !checkInputStartsHello() { textField.text = "Hello " + textField.text }
    if !checkInputEndsWorld() { textField.text = textField.text + " world" }
    

    确保每次输入文本时更新 charArray 并重新检查 textField.text。

    此代码的结果将是一个文本字段,在用户单击键盘上的“完成”后,它会自动显示您给它的开头和结尾。

    【讨论】:

      【解决方案3】:

      这可以完成,但需要一些工作。您需要处理 UITextFieldDelegate 并使用宽度约束。你可以按照大纲来实现。

      1. 您的控制器应采用 UITextFieldDelegate 并使用此方法检查用户在UITextField 中输入的字符串的长度:

        (BOOL)textField:(UITextField *)textFieldshouldChangeCharactersInRange:(NSRange)范围替换字符串:(NSString *)string

      2. 根据字符串的长度动态调整UITextField上的宽度约束。

      3. 如果您还像这样为两侧的其他标签设置约束,它的行为应该符合您的预期。 @"[Label][UITextField][Label]".

      4. 您还可以在 UITextField 上设置一个约束,使其与其父视图的 CenterX 对齐。

      检查输入的文本字段,如下所示:

      -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
      {
          // This is the string the user entered. Get the string and use string metrics
          // to figure out how long the string will be based on font and 
          // font size and adjust the width constraint on the UITextField
          // accordingly.
          return YES;
       }
      

      【讨论】:

      • 谢谢@Cliff。我认为这比乔纳斯的回答更好,但是我对您的第 2 点和第 3 点有点困惑。您能否制作一个虚拟示例项目来展示您的方式?我会非常感激..
      • 是的更好,这是正确的做法。我不会为你编写你的程序,但我会稍微扩展一下。
      • 如果您也扩展它,我将不胜感激。当然,它会给我一个理解的火花
      【解决方案4】:

      您应该使用 leftviewrighttview 的文本字段。例如,

       UIView *paddingView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 10, 40)]; 
      
       // create one label and add it to padding view and then set that padding as left view   
      
      datePickerField.leftView = paddingView;  //here datepicker field is my textfield
      datePickerField.leftViewMode = UITextFieldViewModeAlways;
      

      同样你可以为 rightview 做。

      根据需要的框架创建标签和填充视图,然后将该标签添加到填充视图并将该填充视图设置为文本字段的leftviewrightview

      所以,它会随着文本字段的变化而自动改变它们的位置和大小。

      希望这会有所帮助:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-01-17
        • 2017-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多