2013-05-03 64 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