20

我有UITextField一个表格视图单元格,当它的文本变得太长时,我希望减小字体大小。我想非常清楚地表明我在谈论 a UITextField,而不是 aUILabel或 a UITextView。我之所以这么说是因为我已经多次看到这个问题弹出并且答案都是基于UILabel而不是UITextField。例如,有人问“我无法UITextField自动收缩”,答案是“确保它numberOfLines设置为1”。据我所知, aUITextField甚至没有该属性并且是单行控件。

我努力了:

  • 在 IB 中将字体设置为系统 14.0,设置minFontSize为 7 并选中“调整以适应”框
  • 在代码中tableView:cellForRowAtIndexPath:
ptCell.name.font = [UIFont systemFontOfSize: 14.0];
ptCell.name.adjustsFontSizeToFitWidth = YES;
ptCell.name.minimumFontSize = 7.0;

但这些都没有奏效。我的意思是,不是缩小文本,而是截断尾部。

有谁知道我错过了什么?大概这应该可行,因为我已经看到其他问题抱怨当用户不希望它这样做时它正在这样做。

4

11 回答 11

15

我有同样的问题。UITextField 在文本太长时停止缩小文本,而是调整自身大小并超出其“边界”。

帮助我的解决方案是在给定的 UITextField 上设置宽度约束。之后它不再增长,而是里面的文字按预期变小了。(当然,您必须设置 minFontSize 并选中情节提要中的“调整以适应”框。)

我知道这有点晚了,但如果其他人会像我一样通过谷歌找到这个问题......它可能会有所帮助。

于 2013-11-01T09:39:48.633 回答
10

我以@Purva 发布的答案为起点,提出了这种方法,该方法从配置的字体大小开始提供所需的字体大小,而不是低于配置的最小字体大小。而@Purva 测试了文本的高度,我需要适合的宽度。此方法可以放在 UITextField 的类别或子类中。我将它放在一个子类中,该子类也捕获UITextFieldTextDidChangeNotification. 从这个通知处理程序中,我调用新方法并在需要时调整字体大小。当我将新文本分配给文本字段以确保它适合子类化时,我也会调用它- (void)setText: (NSString*)text

在每种情况下,当我调用它时,我都使用以下代码:

    CGFloat requiredFontSize = self.requiredFontSize;
    if( self.font.pointSize != requiredFontSize )
    {
        self.font = [self.font fontWithSize: requiredFontSize];
    }

这是新方法:

- (CGFloat)requiredFontSize
{
    const CGRect  textBounds = [self textRectForBounds: self.frame];
    const CGFloat maxWidth   = textBounds.size.width;

    if( _originalFontSize == -1 ) _originalFontSize = self.font.pointSize;

    UIFont* font     = self.font;
    CGFloat fontSize = _originalFontSize;

    BOOL found = NO;
    do
    {
        if( font.pointSize != fontSize )
        {
            font = [font fontWithSize: fontSize];
        }

        CGSize size = [self.text sizeWithFont: font];
        if( size.width <= maxWidth )
        {
            found = YES;
            break;
        }

        fontSize -= 1.0;
        if( fontSize < self.minimumFontSize )
        {
            fontSize = self.minimumFontSize;
            break;
        }

    } while( TRUE );

    return( fontSize );
}
于 2013-05-03T09:53:35.500 回答
8

我认为您想将adjustsFontSizeToFitWidth您的属性设置UITextField为 YES,并指定一个minimumFontSize. 对我有用,但我以UITextField编程方式添加 - IB 问题?

于 2013-07-23T17:42:50.803 回答
2

Swift 3.0 调整字体大小以适应的方式:

let startFontSize = 14.0
let minFontSize = 7.0

func resizeFont() {
    guard let font = self.font, let text = self.text else {
        return
    }

    let textBounds = self.textRect(forBounds: self.bounds)
    let maxWidth = textBounds.size.width

    for fontSize in stride(from: startFontSize, through: minFontSize, by: -0.5) {
        let size = (text as NSString).size(attributes: [NSFontAttributeName: font.withSize(CGFloat(fontSize))])
        self.font = font.withSize(CGFloat(fontSize))
        if size.width <= maxWidth {
            break
        }
    }
}
于 2017-01-20T01:30:56.667 回答
2

试试这个对我有用(swift 3.0)

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // bla bla ... anything inside method you want to do
        // reset font size of textfield
        textField.font = UIFont.systemFont(ofSize: CGFloat(15.0))
        var widthOfText: CGFloat = textField.text!.size(attributes: [NSFontAttributeName: textField.font!]).width
        var widthOfFrame: CGFloat = textField.frame.size.width
        // decrease font size until it fits (25 is constant that works for me)
        while (widthOfFrame - 25) < widthOfText {
            let fontSize: CGFloat = textField.font!.pointSize
            textField.font = textField.font?.withSize(CGFloat(fontSize - 0.5))
            widthOfText = (textField.text?.size(attributes: [NSFontAttributeName: textField.font!]).width)!
            widthOfFrame = textField.frame.size.width
        }
        return true
    }
于 2017-03-01T12:33:32.333 回答
1
-(BOOL)sizeFontToFit:(NSString*)aString minSize:(float)aMinFontSize maxSize:(float)aMaxFontSize 
{   
float fudgeFactor = 16.0;
float fontSize = aMaxFontSize;

self.font = [self.font fontWithSize:fontSize];

CGSize tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];

while (stringSize.height >= self.frame.size.height)
       {
       if (fontSize <= aMinFontSize) // it just won't fit
           return NO;

       fontSize -= 1.0;
       self.font = [self.font fontWithSize:fontSize];
       tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight);
       stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap];
       }

return YES; 
}
于 2013-05-03T03:30:02.580 回答
0

我在运行 iOS 7.0.4 的 Xcode 5.0.2 中的 StoryBoard 中创建的 UITextFields 遇到了同样的问题。我发现 .minimumFontSize 属性不能被 StoryBoard、viewDidLoad 或 viewWillAppear 更改,但它可以在 viewDidAppear 中更改。所以下面的代码解决了我的问题:

- (void) viewDidAppear:(BOOL)animated  {
    [super viewDidAppear:animated];
    self.myTextField.minimumFontSize = 4.0;
    [self.myTextField setNeedsLayout];
    [self.myTextField layoutIfNeeded];
}
于 2013-11-28T06:30:33.093 回答
0

我对这个问题的简单解决方案是这样的......(自己找到合适的字体大小 - 以适应框架的大小)我在 shouldChangeCharactersInRange:replacementString 的委托方法中制作了它:

-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string

 {

    // bla bla ... anything inside method you want to do

    // reset font size of textfield
    textField.font = [FONT_PROXY fontNormalOfSizeNormal];

    CGFloat widthOfText = [textField.text sizeWithAttributes:@{NSFontAttributeName:textField.font}].width;
    CGFloat widthOfFrame = textField.frame.size.width;

    // decrease font size until it fits (25 is constant that works for me)
    while((widthOfFrame - 25) < widthOfText){
        CGFloat fontSize = textField.font.pointSize;
        textField.font = [textField.font fontWithSize:fontSize - 0.5f];
         widthOfText = [textField.text sizeWithAttributes:@{NSFontAttributeName:textField.font}].width;
         widthOfFrame = textField.frame.size.width;
    }


  }
于 2016-02-04T15:39:09.853 回答
0

使用 XCode8 和 Swift 3.0.1 测试

func getTextfield(view: UIView) -> [UITextField] {
    var results = [UITextField]()
    for subview in view.subviews as [UIView] {
        if let textField = subview as? UITextField {
            results += [textField]
        } else {
            results += getTextfield(view: subview)
        }
    }
    return results
}

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let allTextFields = getTextfield(view: self.view)
    for textField in allTextFields
    {
        textField.font = UIFont.boldSystemFont(ofSize: 14)
        var widthOfText: CGFloat = textField.text!.size(attributes: [NSFontAttributeName: textField.font!]).width
        var widthOfFrame: CGFloat = textField.frame.size.width
        while (widthOfFrame - 15) < widthOfText { // try here to find the value that fits your needs
            let fontSize: CGFloat = textField.font!.pointSize
            textField.font = textField.font?.withSize(CGFloat(fontSize - 0.5))
            widthOfText = (textField.text?.size(attributes: [NSFontAttributeName: textField.font!]).width)!
            widthOfFrame = textField.frame.size.width
        }
    }
}

我使用 viewDidLayoutSubviews 来获取所有文本字段并自动收缩文本。

也许有人会需要这段代码。

对我来说,它完美无缺。

代码来自本网站上的@ Marek Manduch 和来自

@Kunal Kumar 在这个网站上: 如何快速从视图中获取所有文本字段

于 2017-03-25T03:04:33.377 回答
-1

这里的问题是 minimumFontSize 是一个比率,应该在 0 和 1 之间:)

f.adjustsFontSizeToFitWidth = true
f.minimumFontSize = 0.5

完美运行:)

于 2016-04-20T16:11:28.950 回答
-2

可以通过在 IB 中选择 Line Breaks = Clip 来解决

于 2014-07-03T17:19:50.293 回答