2009-07-30 2 views
3

Я использую UISearchBar для ввода адреса для установления сетевого подключения. Пока соединение сделано, я хочу показать индикатор активности вместо крошечного BookmarkButton в правой части панели поиска. Насколько я вижу, нет публичного объявленного свойства, которое дало бы мне доступ к правильному подсмотру поисковой панели. Я видел, как это было сделано, какие-то мысли?Заменить закладку с помощью ActivityInicator в UISearchBar

+0

где вы видели это было сделано? –

+0

Приложение «Википедия» (бесплатно) делает это. – Monobono

+0

- это приложение для iphone для приложений или веб-приложение? –

ответ

10

Как насчет замены значка поиска на левой стороне индикатором активности во время поиска или соединений?

SearchBarWithActivity.h:

#import <UIKit/UIKit.h> 

@interface SearchBarWithActivity : UISearchBar 

- (void)startActivity; // increments startCount and shows activity indicator 
- (void)finishActivity; // decrements startCount and hides activity indicator if 0 

@end 

SearchBarWithActivity.m:

#import "SearchBarWithActivity.h" 

@interface SearchBarWithActivity() 

@property(nonatomic) UIActivityIndicatorView *activityIndicatorView; 
@property(nonatomic) int startCount; 

@end 


@implementation SearchBarWithActivity 

- (void)layoutSubviews { 
    UITextField *searchField = nil; 

    for(UIView* view in self.subviews){ 
     if([view isKindOfClass:[UITextField class]]){ 
      searchField= (UITextField *)view; 
      break; 
     } 
    } 

    if(searchField) { 
     if (!self.activityIndicatorView) { 
      UIActivityIndicatorView *taiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      taiv.center = CGPointMake(searchField.leftView.bounds.origin.x + searchField.leftView.bounds.size.width/2, 
             searchField.leftView.bounds.origin.y + searchField.leftView.bounds.size.height/2); 
      taiv.hidesWhenStopped = YES; 
      taiv.backgroundColor = [UIColor whiteColor]; 
      self.activityIndicatorView = taiv; 
      [taiv release]; 
      _startCount = 0; 

      [searchField.leftView addSubview:self.activityIndicatorView]; 
     } 
    } 

    [super layoutSubviews]; 
} 

- (void)startActivity { 
    self.startCount = self.startCount + 1; 
} 

- (void)finishActivity { 
    self.startCount = self.startCount - 1; 
} 

- (void)setStartCount:(int)startCount { 
    _startCount = startCount; 
    if (_startCount > 0) 
     [self.activityIndicatorView startAnimating]; 
    else { 
     [self.activityIndicatorView stopAnimating]; 
    } 
} 

@end 
+0

Это не совсем сработало для меня - у моего UISearchBar было только одно subview (другое UIView), поэтому мне пришлось использовать рекурсивный (в ширину) поиск, чтобы найти UITextField. Не уверен, что это связано с тем, что компонент изменился, или я просто делаю что-то неправильно. Но спасибо, что указал мне в правильном направлении. –

1

Только для записи:

for(UIView* view in self.subviews){ 
    if([view isKindOfClass:[UITextField class]]){ 
     searchField=view; 
     break; 
    } 
} 

if(searchField !=)) { 
    searchField.leftView = myCustomView; 
} 

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

+0

О, пожалуйста, используйте for-in цикл 'for (UIView * view в self.subviews) {if ([view isKindOfClass: [UITextField class]]) {searchField = view; break;}} '. – kennytm

2

Я обновил answer от @JohnLemberger работать с прошивкой 7 (примечание: Я проверил только это на прошивкой 7), а также сводка моих изменений:

ПРИМЕЧАНИЕ: это не очень надежный код для начала, поскольку Apple может изменить иерархию представлений UISearchBar в любом выпуске (как и между iOS 6 и 7).

SearchBarWithActivity.h (ничего не изменилось):

@interface SearchBarWithActivity : UISearchBar 

- (void)startActivity; // increments startCount and shows activity indicator 
- (void)finishActivity; // decrements startCount and hides activity indicator if 0 

@end 

@interface XXTreatmentHeaderViewController : XXViewController 

@property (nonatomic, strong, readonly) SearchBarWithActivity *searchBar; 

@end 

SearchBarWithActivity.m:

1) Показать/скрыть значок "увеличительное стекло", когда индикатор активности появляется

2) Добавить глубину в иерархии представлений Поиск по UITextField

@interface SearchBarWithActivity() 

@property(nonatomic) UIActivityIndicatorView *activityIndicatorView; 
@property(nonatomic) int startCount; 

@end 

@implementation SearchBarWithActivity 

- (void)layoutSubviews { 
    UITextField *searchField = nil; 

    for(UIView* view in self.subviews){ 

     // on iOS 6, the UITextField is one-level deep 
     if ([view isKindOfClass:[UITextField class]]){ 
      searchField= (UITextField *)view; 
      break; 
     } 

     // on iOS 7, the UITextField is two-levels deep 
     for (UIView *secondLevelSubview in view.subviews) { 
      if([secondLevelSubview isKindOfClass:[UITextField class]]){ 
       searchField= (UITextField *)secondLevelSubview; 
       break; 
      } 
     } 
    } 

    if(searchField) { 
     if (!self.activityIndicatorView) { 
      UIActivityIndicatorView *taiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; 
      taiv.center = CGPointMake(searchField.leftView.bounds.origin.x + searchField.leftView.bounds.size.width/2, 
             searchField.leftView.bounds.origin.y + searchField.leftView.bounds.size.height/2); 
      taiv.hidesWhenStopped = YES; 
      self.activityIndicatorView = taiv; 
      _startCount = 0; 

      [searchField.leftView addSubview:self.activityIndicatorView]; 
     } 
    } 

    [super layoutSubviews]; 
} 

- (void)startActivity { 
    self.startCount = self.startCount + 1; 
} 

- (void)finishActivity { 
    self.startCount = self.startCount - 1; 
} 

- (void)setStartCount:(int)startCount { 
    _startCount = startCount; 
    if (_startCount > 0) { 
     [self.activityIndicatorView startAnimating]; 
     // Remove the "magnifying glass icon" 
     [self setImage:[UIImage new] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
    } else { 
     [self.activityIndicatorView stopAnimating]; 
     // Restore the "magnifying glass icon" 
     [self setImage:nil forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
    } 
} 

@end 
+0

К сожалению, это не работает на iOS 7, когда setDisplaysSearchBarInNavigationBar является истинным. Я не уверен, что в этом случае доступен поиск. – Gerhat

+0

FYI, на iOS 8, текстовое поле имеет трехуровневую глубину. –

0

Я обновляю jonsibley's answer, добавив поддержку для случаев, когда UISearchBar встроен в UINavigationBar с использованием отображаетSearchBarInNavigationBar.

SearchBarWithActivity.h (добавлено новое свойство):

@interface SearchBarWithActivity : UISearchBar 

- (void)startActivity; // increments startCount and shows activity indicator 
- (void)finishActivity; // decrements startCount and hides activity indicator if 0 

@property (nonatomic,assign) UINavigationItem *navigationItem; 

@end 

SearchBarWithActivity.m (получить searchField от navigationItem, если не ноль):

#import "SearchBarWithActivity.h" 

@interface SearchBarWithActivity() 

@property(nonatomic) UIActivityIndicatorView *activityIndicatorView; 
@property(nonatomic) int startCount; 

@end 

@implementation SearchBarWithActivity 

@synthesize navigationItem; 

- (void)layoutSubviews { 
    UITextField *searchField = nil; 

    if(self.navigationItem) { 
     searchField = (UITextField *)[self.navigationItem titleView]; 
    } else { 
     for(UIView* view in self.subviews){ 

      // on iOS 6, the UITextField is one-level deep 
      if ([view isKindOfClass:[UITextField class]]){ 
       searchField= (UITextField *)view; 
       break; 
      } 

      // on iOS 7, the UITextField is two-levels deep 
      for (UIView *secondLevelSubview in view.subviews) { 
       if([secondLevelSubview isKindOfClass:[UITextField class]]){ 
        searchField= (UITextField *)secondLevelSubview; 
        break; 
       } 

      } 
     } 
    } 

    if(searchField) { 
     if (!self.activityIndicatorView) { 
      UIActivityIndicatorView *taiv = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite]; 
      taiv.center = CGPointMake(searchField.leftView.bounds.origin.x + searchField.leftView.bounds.size.width/2, 
             searchField.leftView.bounds.origin.y + searchField.leftView.bounds.size.height/2); 
      taiv.hidesWhenStopped = YES; 
      self.activityIndicatorView = taiv; 
      _startCount = 0; 

      [searchField.leftView addSubview:self.activityIndicatorView]; 
     } 
    } 

    [super layoutSubviews]; 
} 

- (void)startActivity { 
    self.startCount = self.startCount + 1; 
} 

- (void)finishActivity { 
    self.startCount = self.startCount - 1; 
} 

- (void)setStartCount:(int)startCount { 
    _startCount = startCount; 
    if (_startCount > 0) { 
     [self.activityIndicatorView startAnimating]; 
     // Remove the "magnifying glass icon" 
     [self setImage:[UIImage new] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
    } else { 
     [self.activityIndicatorView stopAnimating]; 
     // Restore the "magnifying glass icon" 
     [self setImage:nil forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
    } 
} 

@end 

В вашем ViewController:

#import "SearchBarWithActivity.h" 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // Embed the search bar into NavigationBar and setup the navigation item in order to show the spinner 
    [self.searchDisplayController setDisplaysSearchBarInNavigationBar:YES]; 
    [(SearchBarWithActivity *)self.searchDisplayController.searchBar setNavigationItem:self.navigationItem]; 
} 

Надеюсь, это сэкономит время.

0

Поскольку кажется, что глубина UITextField продолжает меняться, я решил, что добавлю рекурсивное решение.

-(NSArray *) findAllSubviewsForView:(UIView *) view{ 
    NSMutableArray * views = [[NSMutableArray alloc] init]; 

    for(UIView * subview in view.subviews){ 
     [views addObjectsFromArray:[self findAllSubviewsForView:subview]]; 
    } 
    [views addObject:view]; 
    return views; 
} 

Вы можете использовать этот массив, чтобы найти UITextField,

UITextField * searchField = nil; 
for(UIView * view in [self findAllSubviewsForView:self]){ 
    if([view isKindOfClass:[UITextField class]]){ 
      searchField = (UITextField *) view; 
     } 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^