UISearchBar是由两个subView组成的,一个是UISearchBarBackGround,另一个是UITextField.要IB中没有直接操作背景的属性,在此我总结了几个方法去假改它。
1. 只显示UITextField.采用了layermask.代码如下:
- //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.
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一样对待它。
首先,SearchBar有几个常用的委托方法:
-(void)searchBarSearchButtonCli
- (void)searchBar:(UISearchBar*)searchBar
-(void)searchBarCancelButtonCli
实现搜索的方法有很多种,NoteSection中是采用将不符合搜索条件的内容全删掉,然后再ReloadData将TableView中的值改变;
这就涉及到深度拷贝,我们首先得把原数据拷贝一份副本,对副本进行搜索。
代码:深度拷贝
- (NSMutableDictionary *) mutableDeepCopy
{
NSMutableDictionary*mtd=[NSMutableDictionarydictionaryWithCapacity:[selfcount]];
NSArray *keys=[selfallKeys];
for(id key in keys)
{
id oneValue =[selfvalueForKey:key];
id oneCopy=nil;
if([oneValuerespondsToSelector:@selector(mutableDeepCopy)])
oneCopy=[oneValue mutableDeepCopy];
else
if([oneValuerespondsToSelector:@selector(mutableCopy)])
oneCopy=[oneValue mutableCopy];
if (oneCopy==nil)
oneCopy=[oneValue copy];
[mtd setValue:oneCopy forKey:key];
}
return mtd;
}