ios UISearchBar 透明背景视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2913475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:17:01  来源:igfitidea点击:

UISearchBar transparent background view

iphoneobjective-ciosipad

提问by jeevanantham

In UISearchBar default a background view should present. How to hide that? I need only the search textview part, in UISearchBar.

在默认的UISearchBar背景视图应该呈现。怎么隐藏呢?我只需要 UISearchBar 中的搜索文本视图部分。

回答by Brandon

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

回答by prodos

Here there is a solution working for iOS 5and iOS 6. I have checked that it is not necessary to change any other property (like setting the backgroundColor to [UIColor clearColor]) to make it work.

这里有一个适用于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];
    }
}

回答by C?ur

Starting iOS 5, I would recommend the following way of doing, which avoids messing up with the undocumentedsubviews. Replace selfwith self.searchBarif you're subclassing the UISearchBarController instead of the UISearchBar itself.

从 iOS 5 开始,我建议使用以下方法,以避免弄乱未记录的子视图。更换selfself.searchBar,如果你继承了UISearchBarController,而不是本身的UISearchBar的。

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

And as a bonus:

作为奖励:

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

回答by Kalle

Update: as of iOS 5.0, if you have a background image available, you can now do

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

searchBar.backgroundImage = someUIImage;

(only tested on iOS 6, so may be bugged on 5 though! Will check around.)

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

Brandon's answer no longer works (or doesn't for me, anyway), so I looked around a bit and noted:

布兰登的回答不再有效(或者对我不起作用),所以我环顾四周并注意到:

(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>>
)

The 3rd entry is a custom text field and presumably it is the one I want, I thought, but removing subview 0 AND 1 from superview didn't fix it oddly enough. I ended up with the following, which does work:

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

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

To make that a bit more robust, it's probably a good idea to check that the class is a subclass of text field and such, but unless it breaks I'm just leaving it simple.

为了使它更健壮,检查该类是否是文本字段等的子类可能是个好主意,但除非它中断,否则我只是让它保持简单。

Edit: switched objectAtIndex:2to lastObjectas tipycalFlow suggested.

编辑:切换objectAtIndex:2lastObject建议的tipycalFlow。

回答by Weaverfish

For future visitors looking for an answer. I have found the following to be effective in iOS 5+ and prefer it as it doesn't involve messing with the layout of the UISearchBar itself.

对于未来的访客寻找答案。我发现以下在 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];

回答by TiMoch

Here is my blog postconcerning this issue.

这是我关于这个问题的博客文章

I followed a similar approach to Weaverfish. However, I encapsulated the process of setting the subviews alpha property in a class of its own.

我对 Weaverfish 采取了类似的方法。不过我把设置subviews alpha 属性的过程封装在了自己的一个类中。

You can subclass UISearchBaras follow:

您可以UISearchBar按如下方式进行子类化:

in UITransparentBackgroundSearchBar.h:

在 UITransparentBackgroundSearchBar.h 中:

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

and in UITransparentBackgroundSearchBar.m:

在 UITransparentBackgroundSearchBar.m 中:

#import "UITransparentBackgroundSearchBar.h"
@implementation UITransparentBackgroundSearchBar

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

@end

In your storyboard, set the search bar class to be UITransparentBackgroundSearchBar and voilà.

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

Now, I am new to iOS development so I can't say this is bulletproof. It seems to work and it avoids code duplication if I need the same transparent background in another view.

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

回答by kennytm

The UISearchBar background cannot be hidden by public methods (assigning a transparent color as the tintColorwon't help).

UISearchBar 背景不能被公共方法隐藏(分配透明颜色tintColor无济于事)。

You should use a UITextField if you want precise control on the text field's style.

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

回答by kalperin

I experimented with using a mask layer in order to make everything around the actual text field in the search bar transparent (thus showing the content from the view underneath). It works, but i'd be nervous to use it in a shipping app since you have to match the shape of your mask exactly to the shape of the text field in UISearchBar. If Apple changes the shape of the text field at all, then your mask won't fit and you'll see parts of the search bar gradient that you don't want and/or you won't see parts of the text field that you do want. That said, here's how i did it:

我尝试使用遮罩层使搜索栏中实际文本字段周围的所有内容都透明(从而显示下方视图中的内容)。它可以工作,但我会担心在运输应用程序中使用它,因为您必须将掩码的形状与 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);
}

Later in one of your methods, apply the mask

稍后在您的一种方法中,应用面膜

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

I fudged the positioning of the layer just to see what it would look like, but you could calculate those sizes and positions to suit your needs.

我捏造了图层的位置只是为了看看它会是什么样子,但是您可以计算这些大小和位置以满足您的需要。

回答by JastinBall

It is easily made by setting transparent image of 1px * 1px for backgroundImageproperty. Tested on ios 5, 6.

通过为backgroundImage属性设置 1px * 1px 的透明图像很容易制作。在 ios 5、6 上测试。

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

回答by Everton Cunha

No hack here:

这里没有黑客:

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