1

I have to maintain a quite old and large objective-c project. Every thing works fine until iOS12 but from iOS13 the scope-button-bar of UISearchBar does not work with UISearchDisplayController.

I know that UISearchDisplayController is deprecated but I really don't want to migrate it to UIDisplayController because of some reasons. I did some test and find out the problem might related to UIDisplayController as it block the user touch on the scope button.

My code as below:

@implementation MyUISearchDisplayController

- (void)setActive:(BOOL)visible animated:(BOOL)animated
{
    if(self.active == visible){ return; }
    [self.searchContentsController.navigationController setNavigationBarHidden:YES animated:NO];
    [super setActive:visible animated:animated];
    [self.searchContentsController.navigationController setNavigationBarHidden:NO animated:NO];
    if (visible)
    {
        [self.searchBar becomeFirstResponder];
    }
    else
    {
        [self.searchBar resignFirstResponder];
    }
}
@end

@interface TopBarViewController ()
@property (strong, nonatomic) IBOutlet UISearchBar *searchBar;
@property (strong, nonatomic) UISearchDisplayController *searchController;

@end

@implementation TopBarViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //The default state for show-cancel-button and show-scope-bar of searchBar is false (not showing)
    self.searchBar.scopeButtonTitles = @[@"scope1", @"scope2", @"scope3", @"scope4"];
    self.searchController = [[MyUISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
    self.searchController.delegate = self;
}

The code above works as well until IOS12, but from IOS13 I cannot touch the scope button. I guess the problem related to the UIDisplayController class. So I'm thinking of overwrite some method of UIDisplayController but don't know how to start. Any body have experience with that. Any information would be appreciated. Thanks.

I'm quite new to Objective-C and IOS, I did a lot of search on google but no luck.

updated: After some days debugging I solved my problem by overwriting the hitTest method of UISearchBar class. The following should do the trick (also it's not a documented way)

@implementation MyUISearchBar

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView * touchedView = [super hitTest:point withEvent:event];
    if(check version stuff){
        return touchedView;
    }
    UIView * scopeBar = [self performSelector:NSSelectorFromString(@"_scopeBar")];
    if(user touched the scopeBar){
        return scopeBar;
    }
    return touchedView;
}

Hope it helps some one.

harunaga
  • 141
  • 1
  • 1
  • 10

0 Answers0