UISearchBar是由两个subView组成的,一个是UISearchBarBackGround,另一个是UITextField. 要IB中没有直接操作背景的属性,在此我总结了几个方法去假改它。
1. 只显示UITextField.采用了layer mask.代码如下:
//first make sure you include core animation so that the compiler will know about your view's layer #import <QuartzCore/QuartzCore.h> //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 @interface SearchMaskLayer : CALayer { } @end @implementation SearchMaskLayer - (void)drawInContext:(CGContextRef)context { CGRect imageBounds = CGRectMake(0, 0, 310, 34); CGRect bounds = imageBounds; CGFloat alignStroke; CGFloat resolution; CGMutablePathRef path; CGPoint point; CGPoint controlPoint1; CGPoint controlPoint2; UIColor *color; resolution = 0.5 * (bounds.size.width / imageBounds.size.width + bounds.size.height / imageBounds.size.height); CGContextSaveGState(context); CGContextTranslateCTM(context, bounds.origin.x, bounds.origin.y); CGContextScaleCTM(context, (bounds.size.width / imageBounds.size.width), (bounds.size.height / imageBounds.size.height)); // Layer 1 alignStroke = 0.0; path = CGPathCreateMutable(); point = CGPointMake(295.0, 32.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; CGPathMoveToPoint(path, NULL, point.x, point.y); point = CGPointMake(310.0, 17.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; controlPoint1 = CGPointMake(303.229, 32.0); controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution; controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution; controlPoint2 = CGPointMake(310.0, 25.229); controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution; controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution; CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y); point = CGPointMake(310.0, 17.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; CGPathAddLineToPoint(path, NULL, point.x, point.y); point = CGPointMake(295.0, 2.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; controlPoint1 = CGPointMake(310.0, 8.771); controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution; controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution; controlPoint2 = CGPointMake(303.229, 2.0); controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution; controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution; CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y); point = CGPointMake(15.0, 2.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; CGPathAddLineToPoint(path, NULL, point.x, point.y); point = CGPointMake(0.0, 17.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; controlPoint1 = CGPointMake(6.771, 2.0); controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution; controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution; controlPoint2 = CGPointMake(0.0, 8.771); controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution; controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution; CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y); point = CGPointMake(0.0, 17.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; CGPathAddLineToPoint(path, NULL, point.x, point.y); point = CGPointMake(15.0, 32.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; controlPoint1 = CGPointMake(0.0, 25.229); controlPoint1.x = (round(resolution * controlPoint1.x + alignStroke) - alignStroke) / resolution; controlPoint1.y = (round(resolution * controlPoint1.y + alignStroke) - alignStroke) / resolution; controlPoint2 = CGPointMake(6.771, 32.0); controlPoint2.x = (round(resolution * controlPoint2.x + alignStroke) - alignStroke) / resolution; controlPoint2.y = (round(resolution * controlPoint2.y + alignStroke) - alignStroke) / resolution; CGPathAddCurveToPoint(path, NULL, controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, point.x, point.y); point = CGPointMake(295.0, 32.0); point.x = (round(resolution * point.x + alignStroke) - alignStroke) / resolution; point.y = (round(resolution * point.y + alignStroke) - alignStroke) / resolution; CGPathAddLineToPoint(path, NULL, point.x, point.y); CGPathCloseSubpath(path); color = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0]; [color setFill]; CGContextAddPath(context, path); CGContextFillPath(context); CGPathRelease(path); } 然后在你的controller中应用这个mask layer到你的UISearchBar - (void)viewDidLoad { [super viewDidLoad]; SearchMaskLayer *maskLayer = [[SearchMaskLayer alloc] init]; [maskLayer setFrame:CGRectMake(0, 0, 310, 34)]; [maskLayer setPosition:CGPointMake(162,21)]; [maskLayer setNeedsDisplay]; [self.searchBar.layer setNeedsDisplay]; [self.searchBar.layer setMask:maskLayer]; [maskLayer release]; }
2. 隐藏背景。非官方的方法。
for (UIView *subview in searchBar.subviews) { if ([subview isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) { [subview removeFromSuperview]; break; } }
3. 改变UISearchBar外观。 你可以子类化或category UISearchBar,然后实现两个方法,见代码。
- (void)drawRect:(CGRect)rect { // UIImage *image = [UIImage imageNamed: @"background.png"]; // [image drawInRect:rect]; } - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx { UIImage *img = [UIImage imageNamed: @"background.png"]; UIImageView *v = [[[UIImageView alloc] initWithFrame:CGRectZero] autorelease]; [v setImage:img]; v.bounds = CGRectMake(0, 0, img.size.width, img.size.height); NSLog([NSString stringWithFormat:@"%f:%f",img.size.width, img.size.height]); NSArray *subs = self.subviews; for (int i = 0; i < [subs count]; i++) { id subv = [self.subviews objectAtIndex:i]; if ([subv isKindOfClass:NSClassFromString(@"UISearchBarBackground")]) { CGRect viewRect = [subv frame]; [v setFrame:viewRect]; [self insertSubview:v atIndex:i]; } } [v setNeedsDisplay]; [v setNeedsLayout]; }
UISearchBar也是一个UIView,所以你可以像对待UIView一样对待它。