UISearchBar透明背景视图

时间:2010-05-26 13:42:01

标签: iphone objective-c ios ipad

在UISearchBar中,默认情况下应显示背景视图。怎么隐藏?我只需要在UISearchBar中搜索textview部分。

12 个答案:

答案 0 :(得分:61)

[[searchBar.subviews objectAtIndex:0] removeFromSuperview];

答案 1 :(得分:24)

此处有适用于 iOS 5 iOS 6 的解决方案。我已经检查过没有必要更改任何其他属性(比如将backgroundColor设置为[UIColor clearColor])以使其正常工作。

for (UIView * v in searchBar.subviews) {
    if ([v isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) {
        v.superview.alpha = 0;
        UIView *containerView = [[UIView alloc] initWithFrame:searchBar.frame];
        [containerView addSubview:v];
        [self.view addSubview:containerView];
    }
}

答案 2 :(得分:18)

启动iOS 5,我建议采用以下方式,这样可以避免弄乱未记录的子视图。如果您正在继承UISearchBarController而不是UISearchBar本身,请将self替换为self.searchBar

// transparency for UISearchBar
self.translucent = YES;
self.backgroundImage = [UIImage new];
self.scopeBarBackgroundImage = [UIImage new];

作为奖励:

// transparency for UIToolbar
self.translucent = YES;
[self setBackgroundImage:[UIImage new] forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
[self setShadowImage:[UIImage new] forToolbarPosition:UIToolbarPositionAny];

// transparency for UINavigationBar
self.translucent = YES;
[self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.shadowImage = [UIImage new];

// transparency for UITabBar
self.backgroundImage = [UIImage new];
self.shadowImage = [UIImage new];

答案 3 :(得分:11)

更新:从iOS 5.0开始,如果您有可用的背景图片,现在可以

searchBar.backgroundImage = someUIImage;

(仅在iOS 6上测试过,所以可能会在5上进行测试!会检查一下。)

布兰登的回答不再适用(或者不适合我,所以我环顾四周并注意到:

(gdb) po [searchBar subviews]
<__NSArrayM 0x665ab80>(
<UISegmentedControl: 0x63aad80; frame = (0 0; 225 44); opaque = NO; layer = <CALayer: 0x6368420>>,
<UISearchBarBackground: 0x6347280; frame = (0 0; 225 44); layer = <CALayer: 0x638a230>>,
<UISearchBarTextField: 0x6331110; frame = (0 0; 0 0); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x63a20f0>>
)

第三个条目是一个自定义文本字段,大概是我想要的那个,我想,但是从superview中删除子视图0和1并没有奇怪地修复它。我最终得到了以下内容,其中可行

UITextField *sbTextField = (UITextField *)[searchBar.subviews lastObject];
[sbTextField removeFromSuperview];
[self.view addSubview:sbTextField];
sbTextField.frame = searchBar.frame;
[searchBar removeFromSuperview];

为了使其更加健壮,检查该类是文本字段的子类可能是个好主意,但除非它中断,我只是简单地说。

编辑:将tip objectAtIndex:2切换为lastObject,如tipycalFlow所示。

答案 4 :(得分:10)

为将来的访客寻找答案。我发现以下内容在iOS 5+中有效并且更喜欢它,因为它不涉及搞乱UISearchBar本身的布局。

UISearchBar * search = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
[search setBackgroundColor:[UIColor clearColor]];
[search setPlaceholder:@"Search"];

for (UIView * v in [search subviews]) {
    if (![v isKindOfClass:[UITextField class]]) {
        v.alpha = 0;
    }
}

[header addSubview:search];
[search release];

答案 5 :(得分:2)

公共方法无法隐藏UISearchBar背景(指定透明色,因为tintColor无效)。

如果要对文本字段的样式进行精确控制,则应使用UITextField。

答案 6 :(得分:2)

我尝试使用遮罩层,以使搜索栏中实际文本字段周围的所有内容都透明(从而显示下方视图中的内容)。它可以工作,但我很担心在运送应用程序中使用它,因为你必须将你的面具的形状与UISearchBar中的文本字段的形状完全匹配。如果Apple完全更改了文本字段的形状,那么您的掩码将不适合您将看到您不想要的搜索栏渐变的部分和/或您将看不到文本字段的部分你真的想要。那就是说,我就是这样做的:

//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);
}

稍后在您的一个方法中,应用蒙版

- (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];
}

我捏造了图层的位置只是为了看看它的样子,但你可以根据自己的需要计算这些尺寸和位置。

答案 7 :(得分:2)

以下是关于此问题的blog post

我对Weaverfish采用了类似的方法。但是,我封装了将子视图alpha属性设置在自己的类中的过程。

您可以将UISearchBar子类化如下:

在UITransparentBackgroundSearchBar.h中:

#import <UIKit/UIKit.h>
@interface UITransparentBackgroundSearchBar : UISearchBar
@end

并在UITransparentBackgroundSearchBar.m中:

#import "UITransparentBackgroundSearchBar.h"
@implementation UITransparentBackgroundSearchBar

-(void)didAddSubview:(UIView *)subview {
    if (![subview isKindOfClass:[UITextField class]]) {
        subview.alpha = 0;
    }
}

@end

在您的故事板中,将搜索栏类设置为UITransparentBackgroundSearchBar和voilà。

现在,我是iOS开发的新手,所以我不能说这是防弹的。它似乎工作,如果我需要在另一个视图中使用相同的透明背景,它可以避免代码重复。

答案 8 :(得分:1)

除了Kalle的答案之外,没有一个答案对我有用。 但经过细微的改进。

UITextField *sbTextField = (UITextField *)[self.mSearchBar.subviews lastObject];
[sbTextField removeFromSuperview];
[self.view addSubview:sbTextField];
CGRect sbFrame = self.mSearchBar.frame;
// Set the default height of a textfield
sbFrame.size.height = 31;   

/* 8 is the top padding for textfield inside searchbar
 * You may need to add a variable to 8 according to your requirement.
 */
sbFrame.origin.y = 8+ self.mSearchBar.superview.frame.origin.y;
sbTextField.frame = sbFrame;

[sbTextField setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];  //to support different orientations.
[self.mSearchBar removeFromSuperview];

+1给Kalle。 (竖起大拇指)

答案 9 :(得分:1)

通过为backgroundImage属性设置1px * 1px的透明图像,可以轻松完成。 在ios 5,6上测试。

searchBar.backgroundImage = [UIImage imageNamed:@"transparentImage.png"];

答案 10 :(得分:1)

没有黑客攻击:

if (([[[UIDevice currentDevice] systemVersion] compare:@"7.0" options:NSNumericSearch] == NSOrderedAscending)) {
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(1, 1), NO, 0.0);
    UIImage *blank = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    searchBar.backgroundImage = blank;
    searchBar.backgroundColor = [UIColor clearColor];
}
else {
    searchBar.barTintColor = [UIColor clearColor];
}

答案 11 :(得分:0)

布兰登的回答仍然有效,但是蒂莫西·格罗特提到了这个条件。它就像删除两个较低的子视图一样简单,并确保样式设置为半透明黑色(我在IB中做过,但我假设在代码中执行它会起作用)。

出于好奇,你们为什么认为这不会被批准?该解决方案仅使用公共API。