代码改变世界

修改UISearchBar背景

2013-06-21 10:46  三戒1993  阅读(173)  评论(0编辑  收藏  举报
转载:http://blog.csdn.net/favormm/archive/2010/11/30/6045463.aspx

UISearchBar是由两个subView组成的,一个是UISearchBarBackGround,另一个是UITextField. 而IB中没有直接操作背景的属性,在此我总结了几个方法去修改它。

1. 只显示UITextField.采用了layer mask.代码如下:

  1. //first make sure you include core animation so that the compiler will know about your view's layer  
  2. #import <QuartzCore/QuartzCore.h>  
  3. //now make a mask.  this is basically just a solid colored shape.  When you apply the mask, anywhere where the color is solid will become transparent in your view.  i used the excellent Opacity (http://likethought.com/opacity/) to generate this code, but you can do it any way you'd like  
  4. @interface SearchMaskLayer : CALayer {  
  5. }  
  6. @end  
  7. @implementation SearchMaskLayer  
  8. - (void)drawInContext:(CGContextRef)context  
  9. {  
  10.   
  11.     CGRect imageBounds = CGRectMake(0, 0, 310, 34);  
  12.     CGRect bounds = imageBounds;  
  13.     CGFloat alignStroke;  
  14.     CGFloat resolution;  
  15.     CGMutablePathRef path;  
  16.     CGPoint point;  
  17.     CGPoint controlPoint1;  
  18.     CGPoint controlPoint2;  
  19.     UIColor *color;  
  20.     resolution = 0.5 * (bounds.size.width / imageBounds.size.width + bounds.size.height / imageBounds.size.height);  
  21.     CGContextSaveGState(context);  
  22.     CGContextTranslateCTM(context, bounds.origin.x, bounds.origin.y);  
  23.     CGContextScaleCTM(context, (bounds.size.width / imageBounds.size.width), (bounds.size.height / imageBounds.size.height));  
  24.     // Layer 1  
  25.     alignStroke = 0.0;  
  26.     path = CGPathCreateMutable();  
  27.     point = CGPointMake(295.0, 32.0);  
  28.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  29.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  30.     CGPathMoveToPoint(path, NULL, point.x, point.y);  
  31.     point = CGPointMake(310.0, 17.0);  
  32.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  33.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  34.     controlPoint1 = CGPointMake(303.229, 32.0);  
  35.     controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution;  
  36.     controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution;  
  37.     controlPoint2 = CGPointMake(310.0, 25.229);  
  38.     controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution;  
  39.     controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution;  
  40.     CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y);  
  41.     point = CGPointMake(310.0, 17.0);  
  42.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  43.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  44.     CGPathAddLineToPoint(path, NULL, point.x, point.y);  
  45.     point = CGPointMake(295.0, 2.0);  
  46.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  47.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  48.     controlPoint1 = CGPointMake(310.0, 8.771);  
  49.     controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution;  
  50.     controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution;  
  51.     controlPoint2 = CGPointMake(303.229, 2.0);  
  52.     controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution;  
  53.     controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution;  
  54.     CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y);  
  55.     point = CGPointMake(15.0, 2.0);  
  56.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  57.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  58.     CGPathAddLineToPoint(path, NULL, point.x, point.y);  
  59.     point = CGPointMake(0.0, 17.0);  
  60.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  61.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  62.     controlPoint1 = CGPointMake(6.771, 2.0);  
  63.     controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution;  
  64.     controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution;  
  65.     controlPoint2 = CGPointMake(0.0, 8.771);  
  66.     controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution;  
  67.     controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution;  
  68.     CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y);  
  69.     point = CGPointMake(0.0, 17.0);  
  70.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  71.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  72.     CGPathAddLineToPoint(path, NULL, point.x, point.y);  
  73.     point = CGPointMake(15.0, 32.0);  
  74.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  75.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  76.     controlPoint1 = CGPointMake(0.0, 25.229);  
  77.     controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution;  
  78.     controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution;  
  79.     controlPoint2 = CGPointMake(6.771, 32.0);  
  80.     controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution;  
  81.     controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution;  
  82.     CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y);  
  83.     point = CGPointMake(295.0, 32.0);  
  84.     point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution;  
  85.     point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution;  
  86.     CGPathAddLineToPoint(path, NULL, point.x, point.y);  
  87.     CGPathCloseSubpath(path);  
  88.     color = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0];  
  89.     [color setFill];  
  90.     CGContextAddPath(context, path);  
  91.     CGContextFillPath(context);  
  92.     CGPathRelease(path);  
  93. }  
  94. 然后在你的controller中应用这个mask layer到你的UISearchBar  
  95. - (void)viewDidLoad {  
  96.     [super viewDidLoad];  
  97.     SearchMaskLayer *maskLayer = [[SearchMaskLayer alloc] init];  
  98.     [maskLayer setFrame:CGRectMake(0, 0, 310, 34)];  
  99.     [maskLayer setPosition:CGPointMake(162,21)];  
  100.     [maskLayer setNeedsDisplay];      
  101.     [self.searchBar.layer setNeedsDisplay];  
  102.     [self.searchBar.layer setMask:maskLayer];  
  103.     [maskLayer release];  
  104. }  
 

2. 隐藏背景。非官方的方法。

  1. for (UIView *subview in searchBar.subviews) {  
  2.     if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) {  
  3.         [subview removeFromSuperview];  
  4.         break;  
  5.     }  
  6. }  
 

3. 改变UISearchBar外观。 你可以子类化或category UISearchBar,然后实现两个方法,见代码。

  1. - (void)drawRect:(CGRect)rect {  
  2. //  UIImage *image = [UIImage imageNamed: @"background.png"];  
  3. //  [image drawInRect:rect];  
  4. }  
  5. - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {       
  6.     UIImage *img = [UIImage imageNamed: @"background.png"];       
  7.     UIImageView *v = [[[UIImageView alloc] initWithFrame:CGRectZero] autorelease];       
  8.     [v setImage:img];   
  9.     v.bounds = CGRectMake(0, 0, img.size.width, img.size.height);  
  10.     NSLog([NSString stringWithFormat:@"%f:%f",img.size.width, img.size.height]);  
  11.     NSArray *subs = self.subviews;       
  12.     for (int i = 0; i < [subs count]; i++) {           
  13.         id subv = [self.subviews objectAtIndex:i];           
  14.         if ([subv isKindOfClass:NSClassFromString(@"UISearchBarBackground")])   
  15.         {               
  16.             CGRect viewRect = [subv frame];               
  17.             [v setFrame:viewRect];               
  18.             [self insertSubview:v atIndex:i];           
  19.         }       
  20.     }   
  21.     [v setNeedsDisplay];       
  22.     [v setNeedsLayout];   
  23. }  
 

UISearchBar也是一个UIView,所以你可以像对待UIView一样对待它。