2013-05-03 104 views
18

我对表格视图单元格有一个UITextField,当文本变得太长时,我希望字体大小减小。我想说清楚,我正在谈论的是UITextField,而不是UILabelUITextView。我之所以这样说是因为我看到这个问题出现了几次,答案都是基于UILabel而不是UITextField。例如,有人问“我不能让我的UITextField自动收缩”,答案是“确保它的numberOfLines设置为1”。据我所知,UITextField甚至没有该属性,并且是单行控制。无法让UITextField自动显示文字

我曾尝试:

  • 在IB中tableView:cellForRowAtIndexPath:
ptCell.name.font = [UIFont systemFontOfSize: 14.0]; 
ptCell.name.adjustsFontSizeToFitWidth = YES; 
ptCell.name.minimumFontSize = 7.0;
的字体设置为系统14.0, minFontSize至7和检查 “调整到适合” 框
  • 在代码

    但这些都没有工作。我的意思是,而不是文本缩小它截断尾巴。

    有人知道我失踪了吗?大概这应该工作,因为我看到其他问题抱怨说,当用户不希望它这样做。

  • +0

    您是否使用了属性串? – HalR 2013-05-03 03:29:07

    +0

    不,我不是。我应该是?我只是试了一下,注意到当我开始在字段宽度之外打字时,它缩小了一些卷轴,但是一旦我辞去第一响应者,它就会回到原始字体大小。 – hvanbrug 2013-05-03 04:35:12

    +0

    可能重复的[UITextField最小字体大小](http://stackoverflow.com/questions/6045176/uitextfield-minimum-fontsize) – Harris 2016-07-15 17:43:10

    回答

    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); 
    } 
    
    +4

    真正糟糕的是UITextField控件应该已经自动执行此操作,而不必手动重新创建此功能。 – hvanbrug 2013-05-03 10:12:04

    +0

    这是我正在寻找的答案。我只会添加一件事。我会添加 fontSize = self.minimumFontSize; 在最后的'if'语句中。这可以确保返回的字体大小永远不会小于minimumFontSize。 – 2014-03-24 17:43:38

    +0

    好抓@MattBecker。我的代码可以让它比最小尺寸小一分。我会更新答案(和我自己的代码) – hvanbrug 2014-03-24 21:33:22

    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; 
    } 
    
    +0

    您是否建议我继承UITextField并捕获textdidchange通知以调用此方法,还每次我手动设置文本?内置功能是否正式不起作用? – hvanbrug 2013-05-03 04:39:10

    +1

    是的,你需要为uitextfield – Purva 2013-05-03 09:22:33

    +0

    确定类别。我已经有了一个子类,所以把它放在那里是有道理的。然后,我可以在内部捕获更改通知并调整大小。我正在尝试它,所以我想我们会看到它的工作效果。除非我读错了代码,否则看起来你正在检查高度而不是宽度。 – hvanbrug 2013-05-03 09:25:39

    8

    我想你想设置的adjustsFontSizeToFitWidth属性为您UITextField为YES,并指定minimumFontSize。适用于我,但我以编程方式添加UITextField - IB问题?

    +0

    是的,我会认为它也应该起作用,但它不会在IB也不在代码中。我倾向于同意有一个错误/问题阻止了这些设置的工作。 – hvanbrug 2013-07-23 19:05:15

    +1

    这适用于我: 'emailAddress = [[UITextField alloc] initWithFrame:CGRectMake(15,117,247,30)]; emailAddress.delegate = self; emailAddress.textAlignment = NSTextAlignmentCenter; emailAddress.font = [UIFont fontWithName:@“Helvetica”size:21]; emailAddress.minimumFontSize = 10.0f; emailAddress.adjustsFontSizeToFitWidth = YES; emailAddress.textColor = [UIColor whiteColor]; emailAddress.backgroundColor = [UIColor clearColor]; [scrollView addSubview:emailAddress];' – 2013-07-24 18:25:31

    +0

    我无法获得这种工作。我可以再试一次,因为我不喜欢我必须编写我所做的解决方案的事实。这就是说,我不是手动创建文本框。它在IB。事实上,我只是在代码中设置参数。 – hvanbrug 2013-07-25 00:57:05

    13

    我有同样的问题。 UITextField在文本太长时停止缩短文本长度,而是重新调整自己的大小并超出其“范围”。

    帮助我的解决方案是在给定的UITextField上设置宽度约束。之后,它不再增长,而是内部的文字变得更小了。 (当然你必须设置minFontSize并为您在故事板“调整到适合”复选框。)

    我知道这是怎样的一个迟到的,但如果其他人将通过谷歌,因为我没有找到这个问题...它可能只是帮助。

    0

    我在运行iOS 7.0.4的Xcode 5.0.2中的StoryBoard中创建的UITextFields有同样的问题。我想通过StoryBoard,viewDidLoad或viewWillAppear无法更改.minimumFontSize属性,但是可以在viewDidAppear中更改可能会更改。所以下面的代码解决我的问题:

    - (void) viewDidAppear:(BOOL)animated { 
        [super viewDidAppear:animated]; 
        self.myTextField.minimumFontSize = 4.0; 
        [self.myTextField setNeedsLayout]; 
        [self.myTextField layoutIfNeeded]; 
    } 
    
    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; 
        } 
    
    
        } 
    
    -2

    这里美中不足的是,minimumFontSize是一个比值和应为0和1之间:)

    f.adjustsFontSizeToFitWidth = true 
    f.minimumFontSize = 0.5 
    

    作品完美:)

    +0

    否 - 您正在将已弃用的* size *参数(以点为单位)与更新的* scale *(即您所说的比例)相混淆。这个非常古老的线程似乎是由于故事板中的一个错误,这是多年前AFAIK修复的。你所做的是设置一个非常小的字体*大小 - 当然它“起作用”(因为这个bug不再存在),但是你的答案也允许文本变得非常小 - 不可读。或者,您没有注意到您正在调整的参数的名称,并将* scale *设置为0.5。今天这确实是一个非常合理的解决方案。 ;) – ToolmakerSteve 2017-04-09 01:18:24

    0

    雨燕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 
         } 
        } 
    } 
    
    1

    试试这个它的工作对我来说(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 
        } 
    
    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获取所有文本字段并自动缩短文本。

    也许有人会需要此代码。

    对我而言,它是完美的。

    的代码是从@马立克Manduch在这个网站,并从

    @Kunal库马尔在这个网站: How to get all the textfields from a view in swift