2012-10-19 56 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 
    } 
}