2015-11-19 41 views
11

我有UITextField與更長的文本設置爲佔位符。我希望這個佔位符文本在字段寬度太小時調整其字體大小。UITextField佔位符文本:調整爲適合

我已經嘗試過這種解決方案中的其他職位(編程和IB)

self.fieldTest.adjustsFontSizeToFitWidth = true 
self.fieldTest.minimumFontSize = 10.0 

描述我缺少的是在這裏嗎?

+0

剛嘗試檢測設備並根據該文件調整文本域佔位符。這將幫助您。 –

+0

也許[that](http://stackoverflow.com/a/33993111/826716)可以提供幫助。 – bteapot

+0

你能分享一下使用'fieldTest'對象的代碼嗎?也許我們可以從那裏找到缺少的東西 – Ayazmon

回答

0

嘗試使用歸因佔位符代替普通佔位

試試這個

let attributedplaceholder = NSAttributedString(string: "placeholdertext", attributes: [NSFontAttributeName: UIFont(name: "FontName", size: 10)!]) 
self.fieldTest.attributedPlaceholder = attributedplaceholder 

您可以像文本顏色等

+1

這對原始問題沒有幫助。佔位符文本太長時,佔位符仍不會自動縮放以適合寬度。 – ninjaneer

2

的佔位符添加附加屬性審查的UITextField的類的引用後,似乎adjustsFontSizeToFitWidth隻影響UITextField的text屬性而不影響佔位符屬性。雖然我不知道如何讓佔位符響應adjustsFontSizeToFitWidth,但我可以提出兩個可能會讓你看起來像是希望的黑客想法。請注意,我現在不在Mac附近,所以我沒有測試過這些想法:

1:
由於佔位符只是具有70%灰色的文本,因此您可以設置標籤的文本屬性無論你需要它,然後實現UITextFieldDelegate的textFieldShouldBeginEditing方法來清除文本並將顏色恢復到正常。您還必須實現textFieldShouldClear和textFieldDidEndEditing方法,以將僞佔位符替換回UITextField,並將文本顏色更改回70%灰色。

2:
在viewWillAppear中你可以設置的UITextField的文字到您PLACEHOLD應該是什麼,創建一個UIFont對象,並設置它等於的UITextField的字體屬性,清除的UITextField的文本,並設置佔位符是一個NSAttributedString以字體對象作爲屬性。下面是我的意思的一個例子:

-(void)viewWillAppear:(BOOL) animated { 
    [super viewWillAppear:animated]; 
    someTextField.adjustsFontSizeToFitWidth = YES; 
    someTextField.text = @"placeholderText"; 
    UIFont *font = someTextField.font; 
    someTextField.text = nil; 
    NSDictionary * attributes = [NSDictionary dictionaryWithObject:color forKey:NSFontAttributeName]; 
    NSAttributedString *placeholderString= [[NSAttributedString alloc] initWithString:@"placeholderText" attributes:attributes]; 
    someTextField.placeholder = palceholderString; 
} 

編輯:剛纔注意到了swift標籤。我在Objective-C中編寫了我的代碼,但您應該可以輕鬆地將其轉換爲Swift。

+0

我認爲你的解決方案更好。它根本不依賴於UITextField實現。 –

14

您可以創建UITextField一個子類:

class AutoSizeTextField: UITextField { 
    override func layoutSubviews() { 
     super.layoutSubviews() 

     for subview in subviews { 
      if let label = subview as? UILabel { 
       label.minimumScaleFactor = 0.3 
       label.adjustsFontSizeToFitWidth = true 
      } 
     } 
    } 
}  

或者你也可以添加一些代碼在您的視圖控制器的viewDidAppear

override func viewDidAppear(_ animated: Bool) { 
    super.viewDidAppear(animated) 

    for subview in fieldTest.subviews { 
     if let label = subview as? UILabel { 
      label.minimumScaleFactor = 0.3 
      label.adjustsFontSizeToFitWidth = true 
     } 
    } 
} 
+0

好的解決方案... – KSR

+0

第一種解決方案並不錯,但最好是添加函數來遞歸查找所有UILabels子視圖,並應用相同的設置。 –

+0

@TimurBernikowich https://stackoverflow.com/a/47646907/3046504 –

0

您可以使用這兩個解決方案:

1.如果文本字段大小小於佔位符文本,則固定字號:

let placeholderString = testTF.placeholder 

    print(placeholderString!) 

    let font = UIFont(name: (testTF.font?.fontName)!, size: 16)! 

    let fontAttributes = [NSFontAttributeName: font] 

    let size = (placeholderString! as NSString).sizeWithAttributes(fontAttributes) 

    print(size) 
    print(testTF.frame.size.width) 
    if(size.width > testTF.frame.size.width) 
    { 
     let font = UIFont(name: (testTF.font?.fontName)!, size: 4)! 
     let attributes = [ 
      NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
      NSFontAttributeName : font] 

     testTF.attributedPlaceholder = NSAttributedString(string: placeholderString!, 
                  attributes:attributes) 


    } 
    else 
    { 
    let attributes = [ 
     NSForegroundColorAttributeName: UIColor.lightGrayColor(), 
     NSFontAttributeName : font] 

    testTF.attributedPlaceholder = NSAttributedString(string: placeholderString!, 
                 attributes:attributes) 
    } 

2)如果你想要動態字體大小,你只需檢查上述條件寬度的文本框和佔位符文本size.width。如果佔位符文本大小大於文本字段大小,那麼在文本字段內創建一個標籤並在其上設置最小字體。

if(size.width> testTF。frame.size.width) {

 placeholder = UILabel(frame: CGRect(x: 0, y: 0, width: testTF.bounds.width, height: testTF.bounds.height)) 
     placeholder.text = placeholderString 
     placeholder.numberOfLines = 1; 
     //placeholder.minimumScaleFactor = 8; 
     placeholder.adjustsFontSizeToFitWidth = true 
     placeholder.textColor = UIColor.grayColor() 
     placeholder.hidden = !testTF.text!.isEmpty 
     placeholder.textAlignment = .Center 
     testTF.addSubview(placeholder) 

}

10

在這裏你去:

_myTextField.placeholder = @"SomeTextSomeTextSome"; 
UILabel *label = [_myTextField valueForKey:@"_placeholderLabel"]; 
label.adjustsFontSizeToFitWidth = YES; 

乾杯!

+0

最好的解決方案!謝謝,我的朋友! –

2

下面是一個解決方案,取決於UITextField有一個孩子UILabel(實際UITextFieldLabel)呈現佔位符的無證事實。這種解決方案相對於其他解決方案的優勢在於,如果Apple的實施方式發生變化,則它會優雅地降級它也不會假定無證件的存在。

基本上我們通過一個類別來擴展UILabel。如果我們看到自己被授予UITextField,那麼我們打開adjustFontSizeToFitWidth

@interface UILabel (TS) 
@end 

@implementation UILabel (TS) 

- (void) didMoveToSuperview 
{ 
    [super didMoveToSuperview]; 

    if ([self.superview isKindOfClass: [UITextField class]]) { 

     self.adjustsFontSizeToFitWidth = YES; 
    } 
} 

@end 
+0

這將改變整個項目的行爲。同時它不比wj2061的解決方案更好,因爲你們都是遞歸迭代子視圖。 –

+0

@TimurBernikowich你是非常正確的 - 它會改變應用程序中的全局行爲。如果您不希望在其他地方出現這種行爲,則可能不是完整的解決方案。這將是直截了當的,使其更加強大;我只提出一個基本技巧。國際海事組織,在任何可能發生的地方調整超長佔位符文本的字體大小並不是一個壞習慣。 – TomSwift

1
override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 
     for subView in fieldTest.subviews{ 
     if subView .isKind(of: UILabel.self){ 
      let label = subView as! UILabel 
      label.adjustsFontSizeToFitWidth = true 
      label.minimumScaleFactor = 0.2 
     } 
    }  
} 
+0

如果Apple更改視圖層次結構,這將會崩潰。 –

+0

@Iulian Onofrei非常感謝。我已經更新了代碼。 – KSR

0

在斯威夫特

yourTextField.subviews 
     .filter { $0 is UILabel } 
     .flatMap { $0 as? UILabel } 
     .forEach { 
      $0.adjustsFontSizeToFitWidth = true 
      $0.minimumScaleFactor = 0.5 
     } 

工程:)

+1

我試過了,但不知何故不起作用 –

+0

你真的需要** **過濾器**和** flatMap嗎?在這種情況下,單獨的'flatMap'應該不會很好嗎?也就是說,將'UIView'的數組映射到'UILabel'的數組中(刪除失敗的元素)? –

0

整個逼近或縮小字體大小以適合在白天和無障礙的年齡誤導。

首先,您首先沒有指定文本大小的零業務,更不用說進一步縮小:您必須依賴可訪問性API。

因此,如果佔位符可能不適合,則必須將其放置爲 作爲UITextField之前的UILabel。佔位符應該是簡短的,並且沒有障礙。我想你可以使用 - (CGRect)placeholderRectForBounds:(CGRect)bounds;(CGRect)placeholderRectForBounds:(CGRect)但你是在使用蘋果公司說,你應該只覆蓋一個API的 渾水(但不是叫自己,即使它可能didlayoutsubviews方法[S]的範圍內有意義的和安全的 )

如果佔位符文本動態(服務器服務)將其轉儲到UILabel中。

+1

使用「智障」作爲貶義品的味道很差,在社區中沒有地位,例如堆棧溢出等尊重話語的指導方針。請考慮你在這裏使用的語言。只要你不主動選擇冒犯,你的實際答案中就沒有什麼能保證你所預測的降價。 –

+0

沒錯,但我在代碼中看到了這種字體縮小方法。我想知道是誰開始的。蘋果?當可訪問性推出時,他們已經不再使用adjustsFontSizeToFitWidth –

+1

如果您想對某種模式或方法不喜歡,可以寫博客帖子或使用其他任何媒體。但是堆棧溢出的答案不是這樣做的地方,特別是如果你要使用可能冒犯或疏遠讀者的語言。答案應該是內容豐富,公民和主題 - 你的答案中包含所有這些內容,但這是你應該切斷它的地方。 –

0

斯威夫特

隨意提高擴展 - 相當肯定有遍歷子視圖更優雅的方式。

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    tfCountryCode.allSubviewsOfClass(UILabel.self).forEach { 
     $0.adjustsFontSizeToFitWidth = true 
     $0.minimumScaleFactor = 0.5 
    } 
} 

extension UIView { 
    func allSubviewsOfClass<K: UIView>(_ clazz: K.Type) -> [K] { 
     var matches = [K]() 
     if subviews.isEmpty { return matches } 
     matches.append(contentsOf: subviews.filter { $0 is K } as! [K]) 
     let matchesInSubviews = subviews.flatMap { return $0.allSubviewsOfClass(clazz) } 
     matches.append(contentsOf: matchesInSubviews.flatMap { $0 }) 
     return matches 
    } 
} 
1

基於答案9:故事板到文本字段元素的身份檢查選項卡,然後在「用戶自定義運行屬性」部分,添加以下內容:

enter image description here