2010-05-26 142 views

回答

2

UISearchBar背景不能被公共方法隱藏(指定一個透明的顏色作爲tintColor不會幫助)。

,如果你想在文本字段的風格精確的控制你應該使用的UITextField。

+0

這是非常重要的,如果你仍然支持的iOS 4.x版 – slatvick 2012-04-12 16:52:21

2

我嘗試,以便利用掩模層,使在搜索欄透明的(從而示出了從下方視圖內容)周圍的實際文本字段的一切。它的工作原理,但我很緊張,因爲你必須將你的面具的形狀與UISearchBar中的文本字段的形狀完全匹配,因此在運輸應用中使用它。如果蘋果根本改變了文本字段的形狀,那麼你的蒙版將不適合,你會看到你不想要的搜索欄漸變的一部分和/或你不會看到部分文本字段你確實需要。這就是說,這裏是我是如何做到的:

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

我捏造層的定位只是爲了看看它會是什麼樣的面具,但你可以計算出這些尺寸和位置以滿足你的需求。

+1

如果遇到編譯錯誤,請確保包含quartzcore框架:http://stackoverflow.com/questions/2968071/cant-compile-code-when-working-with-calayer – Ying 2011-05-18 19:42:30

+0

聖神,這個作品!它的邊緣粗糙,所以卡爾佩林,如果你有一個更新的版本,請分享:)在此期間,我會嘗試看看我是否可以捅過來使這符合我的需求。 – Ying 2011-05-18 19:46:13

+0

不幸的是,以某種方式附加這個蒙版可以防止uisearchbar在視圖大小發生變化時自動調整大小,比如縱向顯示。不適合我,但非常非常酷! – Ying 2011-05-18 19:56:22

61
[[searchBar.subviews objectAtIndex:0] removeFromSuperview]; 
+4

這適用於我用於以下行時: \t searchBar.backgroundColor = [UIColor clearColor]; – 2011-02-03 10:26:39

+0

我正在使用Xcode 4.01和iOS 4.3。這對我不起作用。也嘗試使用上面建議的clearColor,沒有任何進展。 – quano 2011-04-12 14:21:58

+0

我證實4.2和4.3之間沒有變化 - 如果沒有別的東西正在消失,那麼您可能沒有將IB連接設置正確。 – Brandon 2011-04-13 14:38:00

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

第3項是一個自定義文本字段,據推測它是我想要的那個,我想,但是從超級視圖中刪除子視圖0和1並不足以解決它。我結束了;下面,確實工作

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

爲了讓這個有點更健壯,它可能是一個好主意,檢查類文本字段和這樣的一個子類,但除非它休息我只是簡單的離開。

編輯:切換到objectAtIndex:2lastObject建議tipycalFlow。

+1

+1,很好!這很奇怪,但刪除索引爲2的子視圖不應該一直工作,因爲數組大小顯然不固定。更好的方法是'UITextField * sbTextField =(UITextField *)[searchBar.subviews lastObject];' – tipycalFlow 2011-11-08 06:20:29

+0

好點。更新! – Kalle 2011-12-01 09:51:57

+0

+1。需要小修改。看到我的答案。 – thesummersign 2012-05-18 05:58:52

0

布蘭登的答案仍然有效,但由蒂莫西·格魯特提到的條件。這很簡單,只需刪除兩個較低的子視圖,並確保該樣式設置爲半透明黑色(我在IB中完成,但我假設在代碼中執行此操作)。

只是出於好奇,爲什麼你們認爲這不會得到批准?該解決方案只使用公共API。

1

的答案都不爲我工作,除了卡勒年代。 但略有改進。

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。(豎起大拇指)

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]; 
+0

爲我工作!非常感謝! – acecapades 2012-09-12 08:31:40

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開發新手,所以我不能說這是防彈的。它似乎工作,它避免了代碼重複,如果我需要在另一個視圖中相同的透明背景。

24

這裏有一個解決方案,適用於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]; 
    } 
} 
+0

這是必要的瘋狂。謝謝! – pir800 2012-10-10 16:23:40

+1

+1嘗試像其他5個(設置圖像等..)沒有工作,但這一個在ios 6馬上工作! – fellowworldcitizen 2013-02-05 14:13:34

+0

精彩!!我嘗試了很多東西,但這工作:) – Pruthvid 2013-03-04 20:14:16

1

它很容易通過設定1像素1像素*的透明圖像backgroundImage屬性製成。 測試在iOS 5,6

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

這個工程,但我發現你必須設置'searchBar.scopeBarBackgroundImage'以同樣的透明圖像以及。 – Lucien 2013-07-03 17:32:01

+0

我喜歡這個解決方案,因爲它不涉及任何黑客行爲。這比其他黑客脆弱。 – Jake 2014-03-13 22:05:58

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]; 
+0

令人驚歎的答案。非常感謝您更新這篇舊文章。幸運的是,我將鏈接保存在我的代碼中,並因此與iOS7兼容。 – 2013-09-14 03:17:51

+0

在iOS 8中沒有快樂:( – 2015-02-19 08:06:39

0

沒有黑客在這裏:

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