Ios 计算NSString大小以调整UITextField帧

Ios 计算NSString大小以调整UITextField帧,ios,objective-c,nsstring,uitextfield,Ios,Objective C,Nsstring,Uitextfield,我在计算UITextField中显示的NSString的准确大小时遇到问题 我的目标是以编程方式(不使用sizeToFit)根据字符串大小更新textfield帧大小。我正在使用sizeWithFont功能 -(void)resizeTextFieldAccordingToText:(NSString*)textFieldString { CGPoint originalCenter = self.textField.center; UIFont* currentFont =

我在计算UITextField中显示的NSString的准确大小时遇到问题

我的目标是以编程方式(不使用sizeToFit)根据字符串大小更新textfield帧大小。我正在使用sizeWithFont功能

-(void)resizeTextFieldAccordingToText:(NSString*)textFieldString {

    CGPoint originalCenter = self.textField.center;

    UIFont* currentFont = [textField font];
    CGSize newSize = [textFieldString sizeWithFont:currentFont];

    //Same incorrect results with the extended version of sizeWithFont, e.g.
    //[textFieldString sizeWithFont:currentFont constrainedToSize:CGSizeMake(300.0, 100.0) lineBreakMode:NSLineBreakByClipping];

    [self.textField setFrame:(CGRectMake(self.textField.frame.origin.x, self.textField.frame.origin.y, newSize.width, newSize.height))];
    [self.textField setCenter:originalCenter];

} 
问题:虽然这个返回正确大小的结果一开始会因为添加字符而变得越来越不精确,因此最终开始剪切字符串(如右图所示)


如何获得textField字符串的准确大小以正确调整其大小?

问题在于您没有考虑UITextField的contentInset。您的代码适用于标签而不是文本字段

例如:一种方法可以是:

CGPoint originalCenter = self.textField.center;

UIFont* currentFont = [textField font];
CGSize oldSize = [self.textField.text sizeWithFont:currentFont];
CGSize newSize = [textFieldString sizeWithFont:currentFont];

CGRect finalFrame = self.textField.frame
finalFrame.size.width -= oldSize.width;
finalFrame.size.width += newSize.width;
finalFrame.size.height -= oldSize.height;
finalFrame.size.height += newSize.height;
[self.textField setFrame:finalFrame];

[self.textField setCenter:originalCenter];

ios7不推荐使用
sizeWithFont:currentFont
,因此它是
sizeWithAttributes:@{NSFontAttributeName:currentFont}
如果使用borderStyle,UITextField内部有自己的布局!=UITextBorderStyleNone。在这种情况下,必须将文本大小尺寸增加一些常量

有了UITextBorderStyleNone,您就不会有这个问题,下面的代码工作起来很有魅力(iOS 7引入了一种新的方法来获取文本大小,-sizeWithFont:不推荐使用)


可能这篇文章对你的目的有用:我知道这一点,但即使使用sizeWithFont的扩展版本(例如CGSize newSize=[textFieldString sizeWithFont:currentFont constrainedToSize:CGSizeMake(300.0,100.0)lineBreakMode:NSLineBreakByClipping];)也会返回相同的稍微不正确的大小。是的,因为它不考虑填充,当您调整文本字段的大小时?请记住,委托方法
-textField:shouldChangeCharactersRange:replacementString:
在文本字段的文本实际更改之前被调用,因此如果您在此处计算新的大小,则需要使用
NSString
-StringByReplacingCharactersRange:withString:
构建修改后的文本。否则,您的大小将始终是一个字符“late”。内联编写,未经测试——但原则应该变得明确:大小不仅仅是字符串的大小。不幸的是,问题仍然存在。静态填充没有帮助。我需要根据每个字符串的变化调整填充,因为sizeWithFont的精度随着每个字符的变化而变化。您使用哪种字体?我试过几种标准字体-没有剪辑,一切似乎都很好。这真令人费解。在我的示例中,我使用了非系统字体(字体系列:“SourceSansPro ExtraLight”;字体重量:正常;字体样式:正常;字体大小:38.00pt)。但是,当我使用默认字体(字体系列:“.HelveticaNeueInterface-M3”;字体重量:正常;字体样式:正常;字体大小:17.00pt)时,我有一个非常相同的问题。在我的回答中,我解决了同样的问题,但我不关心使用什么边框样式。尽管如此,如果没有边框,这听起来还是合理的。我不喜欢常数:D
- (IBAction)textChanged:(UITextField *)field
{
    UIFont *font = field.font;
    NSString *string = field.text;

    CGSize size = [string sizeWithAttributes:
            [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]];

    CGPoint center = field.center;
    CGRect frame = field.frame;
    frame.size = size; // or CGSizeMake(size.width + WIDTH_PADDING * 2, size.height + HEIGHT_PADDING * 2)
    field.frame = frame;
    field.center = center;
}