【问题标题】:Calculate NSString size to adjust UITextField frame计算 NSString 大小以调整 UITextField 框架
【发布时间】:2013-10-19 09:28:55
【问题描述】:

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

我的目标是以编程方式根据字符串大小更新文本字段框架大小(不使用 sizeToFit)。我正在使用 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 字符串的准确大小以正确调整其大小?

【问题讨论】:

  • 这篇文章可能对您有用:stackoverflow.com/questions/1435544/…
  • 我知道这一点,但即使使用 sizeWithFont 的扩展版本(例如 CGSize newSize = [textFieldString sizeWithFont:currentFont constrainedToSize:CGSizeMake(300.0, 100.0) lineBreakMode:NSLineBreakByClipping];) 也会稍微返回相同的结果尺寸不正确。
  • 是的,因为它不考虑填充
  • 何时调整文本字段的大小?请记住,委托方法-textField:shouldChangeCharactersInRange:replacementString: 在文本字段的文本实际更改之前 被调用,因此如果您在那里计算新大小,则需要使用NSString-stringByReplacingCharactersInRange:withString: 构建修改后的文本.否则,您的尺寸将始终是一个字符“迟到”。

标签: ios objective-c nsstring uitextfield


【解决方案1】:

如果你使用borderStyle != UITextBorderStyleNone,UITextField 里面有它自己的布局。在这种情况下,您必须将文本大小尺寸增加一些常数。

使用 UITextBorderStyleNone 你没有这个问题,下面的代码就像一个魅力(iOS 7 引入了获取文本大小的新方法,-sizeWithFont: 已弃用)

- (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;
}

【讨论】:

  • 不幸的是,问题仍然存在。静态填充没有帮助。我需要随着每个字符串的变化调整填充,因为 sizeWithFont 的精度会随着每个字符的变化而变化。
  • 您使用哪种字体?我尝试了几种标准字体 - 没有剪裁,一切似乎都很好
  • 嗯。这很令人费解。在我的示例中,我使用了非系统字体(字体系列:“SourceSansPro-ExtraLight”;字体粗细:正常;字体样式:正常;字体大小:38.00pt)。但是,当我使用默认字体(字体系列:“.HelveticaNeueInterface-M3”;字体粗细:正常;字体样式:正常;字体大小:17.00pt)时,我遇到了同样的问题。
  • 在我的回答中我解决了同样的问题,但我不在乎使用什么边框样式。
  • 仍然 - 当您没有边框时,这听起来很合理。我不喜欢常量:D
【解决方案2】:

问题是您没有考虑 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}

【讨论】:

  • 内联编写,未经测试——但原则应该很清楚:大小不仅仅是字符串的大小
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
  • 1970-01-01
  • 1970-01-01
  • 2012-10-13
  • 1970-01-01
  • 2012-12-16
  • 2015-06-08
相关资源
最近更新 更多