web-dev-qa-db-ja.com

UISearchBarの透明な背景ビュー

UISearchBarのデフォルトでは、背景ビューが表示されます。それを隠す方法は? UISearchBarの検索テキストビュー部分のみが必要です。

21
jeevanantham
[[searchBar.subviews objectAtIndex:0] removeFromSuperview];
61
Brandon

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

IOS 5以降、次の方法をお勧めします。これにより、ドキュメント化されていないサブビューが台無しになるのを防ぐことができます。 UISearchBar自体ではなくUISearchBarControllerをサブクラス化する場合は、selfself.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];
18
Cœur

更新: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>>
)

3番目のエントリはカスタムテキストフィールドであり、おそらくそれが必要なものだと思いましたが、スーパービューからサブビュー0と1を削除しても、奇妙なことに修正されませんでした。私は次のようになりました動作します

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

これをもう少し堅牢にするために、クラスがテキストフィールドなどのサブクラスであることを確認することをお勧めしますが、壊れない限り、単純なままにしておきます。

編集:tipycalFlowが提案したように、objectAtIndex:2lastObjectに切り替えました。

11
Kalle

答えを探している将来の訪問者のために。私は以下がiOS5 +で効果的であることを発見し、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];
10
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開発に不慣れなので、これが防弾であるとは言えません。別のビューで同じ透明な背景が必要な場合は、機能しているようで、コードの重複を回避できます。

2
TiMoch

UISearchBarの背景をパブリックメソッドで非表示にすることはできません(tintColorが役に立たないため、透明色を割り当てます)。

テキストフィールドのスタイルを正確に制御する場合は、UITextFieldを使用する必要があります。

2
kennytm

検索バーの実際のテキストフィールドの周囲をすべて透明にするために、マスクレイヤーを使用して実験しました(したがって、下のビューからコンテンツを表示します)。動作しますが、マスクの形状を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);
}

後であなたの方法の1つで、マスクを適用します

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

ここにハックはありません:

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];
}
1
Everton Cunha

backgroundImageプロパティに1px * 1pxの透明画像を設定することで簡単に作成できます。 iOS 5、6でテスト済み。

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

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。 (いいぞ)

1
thesummersign

ブランドンの答えはまだ機能しますが、ティモシー・グルートが述べた条件で。下の2つのサブビューを削除し、スタイルが半透明の黒に設定されていることを確認するのと同じくらい簡単です(IBで実行しましたが、コードで実行すると機能すると思います)。

好奇心から、なぜこれが承認されないと思いますか?このソリューションは、パブリックAPIのみを使用します。

0
mjisrawi