2012-10-19 57 views
10

我試圖自定義UISearchbar的文本字段。下面的圖片顯示了我的一半完成的工作。 strong text自定義UISearchbar的UITextfield - iOS

我有UISearchbar的子類,並從我的視圖控制器調用它。我試圖從文本字段中刪除那些黑灰色的線條。下面是UISearchbar添加到viewcontroller子視圖的實現。

searchbar = [[SearchBar alloc] initWithFrame:CGRectMake(35,78, 250, 17)]; 
searchbar.backgroundColor = [UIColor clearColor]; 
searchbar.layer.borderColor = [[UIColor clearColor] CGColor]; 
searchbar.layer.borderWidth = 0; 

for(UIView *view in searchbar.subviews){ 
    if([view isKindOfClass:[UITextField class]]){ 
     UITextField *tf= (UITextField *)view; 
     tf.layer.borderColor = [[UIColor clearColor] CGColor]; 
     tf.delegate = self; 
     break; 
    } 
} 
[self.view addSubview:searchbar]; 
searchbar.delegate = self; 

的UISearchBar子:

- (id)initWithFrame:(CGRect)frame 
    { 
    self = [super initWithFrame:frame]; 
if (self) { 
     // Initialization code 
    } 
    return self; 
} 

-(void)layoutSubviews{ 
    UITextField *searchField; 
    [[[self subviews] objectAtIndex:0] removeFromSuperview]; 
    [self setTintColor:[UIColor clearColor]]; 
    self.clipsToBounds = YES; 
    NSUInteger numViews = [self.subviews count]; 
    for(int i = 0; i < numViews; i++) { 
     if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) { 
      searchField = [self.subviews objectAtIndex:i]; 
      searchField.leftViewMode = UITextFieldViewModeNever; 
      searchField.backgroundColor = [UIColor clearColor]; 

     } 


    } 
    if(!(searchField == nil)) {    
     searchField.backgroundColor = [UIColor clearColor]; 
     searchField.textColor = [UIColor blackColor]; 
     searchField.frame = CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height-10); 

     [searchField setBorderStyle:UITextBorderStyleRoundedRect]; 

    } 

    [super layoutSubviews]; 

} 

我想才達到這樣的事: 的文本字段不應該有任何界限。圖標被展平UIImageView。

enter image description here

回答

49

這是一種簡單的方式來獲得的UISearchBar子視圖層次文本框,並根據需要像

UITextField *txfSearchField = [searchbar valueForKey:@"_searchField"]; 
[txfSearchField setBackgroundColor:[UIColor whiteColor]]; 
    [txfSearchField setLeftView:UITextFieldViewModeNever]; 
    [txfSearchField setBorderStyle:UITextBorderStyleRoundedRect]; 
    txfSearchField.layer.borderWidth = 8.0f; 
    txfSearchField.layer.cornerRadius = 10.0f; 
     txfSearchField.layer.borderColor = [UIColor clearColor].CGColor; 
+0

圖標都像我的UIImageView的一部分說過。它是我擔心的文本字段。那些深灰色的線條將被刪除。謝謝你的回答。圖標已從搜索欄中刪除。 – DesperateLearner

+0

非常感謝你Animesh ...它解決了我的問題。 – Hari1251

+1

謝謝你,我有一天會爲你付啤酒。 –

6

從IOS-5開始,你有外觀代理設置其屬性,請參閱: http://developer.apple.com/library/ios/#documentation/uikit/reference/UISearchBar_Class/Reference/Reference.html (有兩個部分稱爲「自定義外觀」,請同時選中)。

這裏的工作的例子,它會修改所有UISearchBars在應用程序:

[[UISearchBar appearance] setSearchFieldBackgroundImage:[UIImage imageNamed:@"text_box"] forState:UIControlStateNormal]; 
[[UISearchBar appearance] setImage:[UIImage imageNamed:@"search_icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
mysearchBar.tintColor = [UIColor whiteColor]; 
12

使用下面的,如果你不希望使用無證的功能或使用的圖像:

CGSize size = CGSizeMake(30, 30); 
// create context with transparent background 
UIGraphicsBeginImageContextWithOptions(size, NO, 1); 

// Add a clip before drawing anything, in the shape of an rounded rect 
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0,30,30) 
          cornerRadius:2.0] addClip]; 
[[UIColor whiteColor] setFill]; 

UIRectFill(CGRectMake(0, 0, size.width, size.height)); 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

[self.searchBar setSearchFieldBackgroundImage:image forState:UIControlStateNormal]; 
+0

謝謝!其他答案不適合我。 – user2734823

+0

真棒answer.that解決了我的問題 – Logic

4

實現變更抵抗&高性能

對任何人閱讀此和想知道如何t他可以在Swift中輕鬆訪問搜索欄的文本字段;您可以通過使用以下一段代碼來擴展UISearchBar以添加textField屬性,該代碼可以抵抗底層實現更改並緩存找到的結果,因此它是高性能的。

import UIKit 

private var foundTextFieldAssociationKey = UInt8() 

extension UISearchBar { 

    var textField: UITextField { 
    get { 
     let value = objc_getAssociatedObject(self, &foundTextFieldAssociationKey) as? UITextField 

     if value == nil { 
     let findInView = (UIView) -> UITextField? = { view in 
      for subview in view.subviews { 
      if let textField = (subview as? UITextField) ?? findInView(subview) { 
       return textField 
      } 
      } 
      return nil 
     } 

     guard let foundTextField = findInView(self) else { 
      fatalError("UISearchBar doesn't seem to have a UITextField anywhere in the view hierarchy") 
     } 

     textField = foundTextField 
     return foundTextField 
     } 

     return value! 
    } 
    set { 
     objc_setAssociatedObject(self, &foundTextFieldAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN) 
    } 
    } 

} 

如果您希望更改屬性的名稱時,請確保你不將其更改爲searchField。這會讓你的搜索欄變得糟糕。

+0

如何只返回self.valueForKey(「_ searchField」)? UITextField'? – ton

+2

@ton這是有效的。我懷疑蘋果很快就會改變這個關鍵,但是當使用哈克解決方案時,我個人更喜歡找到一種方法來做到這一點,它對底層的實施變化有一定的適應能力。 – isair

+0

@ abishek-bedi我修改了你的修改。我的代碼是舊的,但你編輯了實現的核心,並將其完全改變爲其他東西。我的實現的核心在於不依賴_searchField來抵抗核心實現的變化。 – isair

2

我已經找到了iOS的10我需要做到這一點(從上面借來的和快速適應)

extension UISearchBar { 
    var textField: UITextField? { 

    func findInView(_ view: UIView) -> UITextField? { 
     for subview in view.subviews { 
      print("checking \(subview)") 
      if let textField = subview as? UITextField { 
       return textField 
      } 
      else if let v = findInView(subview) { 
       return v 
      } 
     } 
     return nil 
     } 

     return findInView(self) 
    } 
} 
1

簡短

extension UISearchBar { 
    var textField:UITextField { 
     guard let txtField = self.value(forKey: "_searchField") as? UITextField else { 
      assertionFailure() 
      return UITextField() 
     } 
     return txtField 
    } 
}