Iphone UISearchBar透明背景视图

Iphone UISearchBar透明背景视图,iphone,objective-c,ios,ipad,Iphone,Objective C,Ios,Ipad,在UISearchBar中,默认情况下应显示背景视图。如何隐藏?我只需要UISearchBar中的search textview部分。UISearchBar背景不能通过公共方法隐藏(将透明颜色指定为tintColor将没有帮助) 如果想要精确控制文本字段的样式,应该使用UITextField。我尝试使用遮罩层,以便使搜索栏中实际文本字段周围的所有内容都透明(从而显示下面视图中的内容)。它可以工作,但我会很紧张,在一个航运应用程序中使用它,因为你必须匹配的形状,你的面具完全的文本字段在UISear

在UISearchBar中,默认情况下应显示背景视图。如何隐藏?我只需要UISearchBar中的search textview部分。

UISearchBar背景不能通过公共方法隐藏(将透明颜色指定为
tintColor
将没有帮助)


如果想要精确控制文本字段的样式,应该使用UITextField。

我尝试使用遮罩层,以便使搜索栏中实际文本字段周围的所有内容都透明(从而显示下面视图中的内容)。它可以工作,但我会很紧张,在一个航运应用程序中使用它,因为你必须匹配的形状,你的面具完全的文本字段在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);
}

我伪造了图层的位置,只是想看看它是什么样子,但是你可以根据需要计算这些大小和位置。

更新:从iOS 5.0开始,如果你有背景图像,现在就可以这样做了

[[searchBar.subviews objectAtIndex:0] removeFromSuperview];
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>>
)
为了使它更加健壮,检查类是否是文本字段之类的子类可能是一个好主意,但除非它中断,否则我就简单了


编辑:按照tipycalFlow的建议,将
objectAtIndex:2
切换到
lastObject

Brandon的答案仍然有效,但符合Timothy Groote提到的条件。它非常简单,只需删除下面两个子视图,并确保样式设置为半透明黑色(我在IB中这样做了,但我假设在代码中这样做会起作用)


只是出于好奇为什么你们认为这不会得到批准?该解决方案只使用公共API。

除了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点到卡尔。(竖起大拇指)

供未来的访客寻找答案。我发现以下内容在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];
// transparency for UISearchBar
self.translucent = YES;
self.backgroundImage = [UIImage new];
self.scopeBarBackgroundImage = [UIImage new];
以下是我对这个问题的看法

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

您可以将
UISearchBar
子类化,如下所示:

在UITransparentBackgroundSearchBar.h中:

#import <UIKit/UIKit.h>
@interface UITransparentBackgroundSearchBar : UISearchBar
@end
在您的故事板中,将搜索栏类设置为UITransparentBackgroundSearchBar和voilá


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

这里有一个解决方案适用于iOS 5iOS 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];
    }
}

通过为
backgroundImage
属性设置1px*1px的透明图像,可以很容易地进行设置。 在ios 5、6上测试

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

从iOS5开始,我建议使用以下方法,避免弄乱未记录的子视图。如果要子类化UISearchBarController而不是UISearchBar本身,请将
self
替换为
self.searchBar

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];
// 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];
这里没有黑客:

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

这在与以下行一起使用时对我有效:searchBar.backgroundColor=[UIColor clearColor];我使用的是Xcode 4.01和iOS 4.3。这对我不管用。正如上面所建议的,我也尝试过使用clearColor,但没有任何进展。我验证了4.2和4.3之间没有任何变化-如果没有其他变化消失,您可能没有正确设置IB连接。这似乎可行,但有一个奇怪的先决条件,即搜索栏样式设置为
黑色半透明
,这对我有效(iOS 6.1模拟器,Xcode 5.0.2),没有任何黑客攻击,但要小心!在iOS 7中,它会删除搜索栏本身,因此您应该在使用此黑客攻击之前检查iOS版本。如果遇到编译错误,请确保包含quartzcore框架:天哪,这很有效!边缘有点粗糙,因此kalperin,如果您有更新版本,请共享:)同时,我将尝试看看是否可以拨弄一下,使其适合我的需要。不幸的是,在视图大小发生变化时(例如从纵向到横向),附加此遮罩会阻止uisearchbar自动调整大小。对我来说不可行,但很酷@英,我没有最新消息。我仍然不想发布这样的东西(不管你的自动调整大小有多麻烦),但是图层屏蔽仍然是一个有用的工具!这很奇怪,但是删除索引2处的子视图不应该一直有效,因为数组大小显然不是固定的。更好的方法是
UITextField*sbTextField=(UITextField*)[searchBar.subviews lastObject]
Daniel:在应用商店中有一个应用程序在使用这个,正如我们所说的。有一个少得多的黑客解决方案,请检查@Coeur的回答设置
backgroundImage
是否有黑客行为,并且@Coeur的回答在iOS 7下对我也不起作用。即使
半透明
设置为
,条色也会被清除。如果您仍然支持iOS 4.x.+1,就像其他5个(设置图像等…)不起作用的条色一样尝试过,但这一条在iOS 6中立即起作用,这一点非常重要!有一个少得多的黑客解决方案,检查@Coeur的回答这是可行的,但我发现你必须将
搜索栏。scopeBarBackgroundImage
设置为相同的透明图像。我喜欢这个解决方案,因为它不涉及任何黑客行为。这比其他黑客更脆弱。惊人的答案。T
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];
}