UISearchBar прозрачный фоновый вид - PullRequest
21 голосов
/ 26 мая 2010

В UISearchBar по умолчанию должен отображаться фоновый вид. Как это скрыть? Мне нужна только часть текстового просмотра поиска в UISearchBar.

Ответы [ 12 ]

61 голосов
/ 06 июля 2010
[[searchBar.subviews objectAtIndex:0] removeFromSuperview];
24 голосов
/ 01 октября 2012

Здесь есть решение, работающее для 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];
    }
}
18 голосов
/ 13 августа 2013

Начиная с iOS 5, я бы порекомендовал следующий способ, позволяющий избежать путаницы с недокументированными подпунктами . Замените self на self.searchBar, если вы подклассифицируете UISearchBarController вместо самого UISearchBar.

// 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];
11 голосов
/ 05 мая 2011

Обновление: начиная с 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:2 на lastObject, как рекомендовано tipycalFlow.

10 голосов
/ 31 июля 2012

Для будущих посетителей, ищущих ответ. Я обнаружил, что следующее является эффективным в 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];
2 голосов
/ 05 сентября 2012

Вот мое сообщение в блоге , касающееся этой проблемы.

Я придерживался аналогичного подхода к Weaverfish. Однако я инкапсулировал процесс установки альфа-свойства subviews в свой собственный класс.

Вы можете подкласс 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 голосов
/ 04 июня 2010

Я экспериментировал с использованием маскирующего слоя, чтобы сделать все вокруг фактического текстового поля в строке поиска прозрачным (таким образом, показывая содержимое из представленного ниже представления). Это работает, но я бы нервничал, чтобы использовать его в приложении доставки, так как вы должны точно подобрать форму вашей маски к форме текстового поля в 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];
}

Я изменил положение слоя, чтобы посмотреть, как он будет выглядеть, но вы можете рассчитать эти размеры и позиции в соответствии с вашими потребностями.

2 голосов
/ 26 мая 2010

Фон UISearchBar не может быть скрыт публичными методами (назначение прозрачного цвета, так как tintColor не поможет).

Вам следует использовать UITextField, если вы хотите точно контролировать стиль текстового поля.

1 голос
/ 16 апреля 2014

Нет хака здесь:

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 голос
/ 20 декабря 2012

Это легко сделать, установив прозрачное изображение размером 1px * 1px для свойства backgroundImage. Протестировано на ios 5, 6.

searchBar.backgroundImage = [UIImage imageNamed:@"transparentImage.png"];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...