ios - UISearchDisplayController does not entirely cover a child view controller -


i have root view controller composes search bar on top , child table view controller on bottom. used composition instead of assigning search bar table view's header these reasons:

  1. i didn't want index overlap search bar (like contacts app).
  2. i wanted search bar sticky. is, doesn't move when scroll table view (again contacts app).
  3. my table view had header.

since search bar in root view controller, instantiate search display controller in root view controller also. there 2 problems search ui seek advice:

  1. the translucent gray overlay not cover entire child table view. leaves top portion of header , index visible.
  2. likewise, search results table not cover entirety of child table view. know how manually change frame of results table view, doing fixes ... gray translucent overlay's frame not linked results table view frame. no property access overlay.

1) idle

enter image description here

2) enter search bar

enter image description here

3) start typing

enter image description here

#import "contactsrootviewcontroller.h" #import "contactsviewcontroller.h" #import "uiview+position.h" #import "user.h" #import "usercellview.h" #import "userviewcontroller.h"  @interface contactsrootviewcontroller ()  @property(nonatomic, strong) uisearchbar* searchbar; @property(nonatomic, strong) contactsviewcontroller* contactsviewcontroller; @property(nonatomic, strong) uisearchdisplaycontroller* searchcontroller; @property(nonatomic, strong) nsmutablearray* matchedusers;  @end  @implementation contactsrootviewcontroller  #pragma mark uiviewcontroller  - (nsstring*)title {     return @"contacts"; }  - (void)viewdidload {     [super viewdidload];      self.matchedusers = [nsmutablearray array];      self.searchbar = [[uisearchbar alloc] init];     self.searchbar.placeholder = @"search";     [self.searchbar sizetofit];     [self.view addsubview:self.searchbar]; }  - (void)viewdidappear:(bool)animated {     [super viewdidappear:animated];      if (self.contactsviewcontroller == nil) {         self.contactsviewcontroller = [[contactsviewcontroller alloc] init];         [self addchildviewcontroller:self.contactsviewcontroller];         self.contactsviewcontroller.view.frame = cgrectmake(             0.0,             self.searchbar.bottomy,             self.view.frame.size.width,             self.view.frame.size.height - self.searchbar.bottomy         );         self.contactsviewcontroller.view.autoresizingmask = uiviewautoresizingflexiblewidth | uiviewautoresizingflexibletopmargin;         [self.view addsubview:self.contactsviewcontroller.view];         [self.contactsviewcontroller didmovetoparentviewcontroller:self];          self.searchcontroller = [[uisearchdisplaycontroller alloc] initwithsearchbar:self.searchbar contentscontroller:self.contactsviewcontroller];         self.searchcontroller.delegate = self;         self.searchcontroller.searchresultsdatasource = self;         self.searchcontroller.searchresultsdelegate = self;     } }  #pragma mark uitableviewdatasource  - (nsinteger)tableview:(uitableview *)tableview numberofrowsinsection:(nsinteger)section {     return self.matchedusers.count; }  - (uitableviewcell*)tableview:(uitableview *)tableview cellforrowatindexpath:(nsindexpath *)indexpath {     static nsstring* identifier = @"contactsrootviewusercell";     usercellview* cell = [tableview dequeuereusablecellwithidentifier:identifier];     if (cell == nil) {         cell = [[usercellview alloc] initwithidentifier:identifier];     }     cell.user = [self.matchedusers objectatindex:indexpath.row];     return cell; }  #pragma mark uitableviewdelegate  - (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath {     [self.navigationcontroller pushviewcontroller:[[userviewcontroller alloc] initwithuser:[self.matchedusers objectatindex:indexpath.row]] animated:yes]; }  - (cgfloat)tableview:(uitableview *)tableview heightforrowatindexpath:(nsindexpath *)indexpath {     return [usercellview height]; }  #pragma mark uisearchdisplaycontrollerdelegate  - (bool)searchdisplaycontroller:(uisearchdisplaycontroller*)controller shouldreloadtableforsearchstring:(nsstring *)searchstring {     [self.matchedusers removeallobjects];      searchstring = [searchstring stringbytrimmingcharactersinset:[nscharacterset whitespaceandnewlinecharacterset]];      if (searchstring.length > 0) {         (user* user in self.contactsviewcontroller.allusers) {             nsrange match = [user.userdisplayname rangeofstring:searchstring options:nscaseinsensitivesearch];             if (match.location != nsnotfound) {                 [self.matchedusers addobject:user];             }         }     }      return yes; }  - (void)searchdisplaycontrollerdidendsearch:(uisearchdisplaycontroller *)controller {     [self.searchbar resignfirstresponder]; }  @end 

i re-implemented uisearchdisplaycontroller, calling implementation searchcontroller. same thing , has similar delegate callbacks, frame of search results can controlled programmer.

header

#import <foundation/foundation.h>  @class searchcontroller;  @protocol searchcontrollerdelegate <nsobject>  @required - (bool)searchcontroller:(searchcontroller*)controller shouldreloadtableforsearchstring:(nsstring*)searchtext;  @optional - (void)searchcontroller:(searchcontroller*)controller didshowsearchresultstableview:(uitableview*)tableview; - (void)searchcontroller:(searchcontroller *)controller didhidesearchresultstableview:(uitableview *)tableview; - (void)searchcontrollerdidbeginsearch:(searchcontroller*)controller; - (void)searchcontrollerdidendsearch:(searchcontroller*)controller;  @end  @interface searchcontroller : uiviewcontroller <uisearchbardelegate>  @property(nonatomic, weak) nsobject<searchcontrollerdelegate>* delegate; @property(nonatomic, weak) nsobject<uitableviewdatasource>* searchresultsdatasource; @property(nonatomic, weak) nsobject<uitableviewdelegate>* searchresultsdelegate; @property(nonatomic, strong, readonly) uitableview* searchresultstableview;  - (id)initwithsearchbar:(uisearchbar*)searchbar;  @end 

implementation

#import "searchcontroller.h" #import "uiview+position.h"  @interface searchcontroller ()  @property(nonatomic, strong) uisearchbar* searchbar; @property(nonatomic, strong) uibutton* searchresultsveil; @property(nonatomic, strong, readwrite) uitableview* searchresultstableview; @property(nonatomic, assign) bool searchresultstableviewhidden;  - (void)didtapsearchresultsveil; - (void)hidesearchresults;  @end  @implementation searchcontroller  #pragma mark uiviewcontroller  - (void)viewwillappear:(bool)animated {     [super viewwillappear:animated];      [self.searchresultstableview deselectrowatindexpath:[self.searchresultstableview indexpathforselectedrow] animated:yes]; }  - (void)viewdidload {     [super viewdidload];      self.view.userinteractionenabled = no; }  #pragma mark searchcontroller ()  - (void)hidesearchresults {     self.searchbar.text = nil;     [self.searchresultstableview reloaddata];     self.searchresultstableviewhidden = yes;     [self.searchbar resignfirstresponder]; }  - (void)didtapsearchresultsveil {     [self hidesearchresults]; }  - (void)setsearchresultstableviewhidden:(bool)searchresultstableviewhidden {     if (self.searchresultstableview != nil) {         if (self.searchresultstableview.hidden && !searchresultstableviewhidden) {             self.searchresultstableview.hidden = searchresultstableviewhidden;             if ([self.delegate respondstoselector:@selector(searchcontroller:didshowsearchresultstableview:)]) {                 [self.delegate searchcontroller:self didshowsearchresultstableview:self.searchresultstableview];             }         } else if (!self.searchresultstableview.hidden && searchresultstableviewhidden) {             self.searchresultstableview.hidden = searchresultstableviewhidden;             if ([self.delegate respondstoselector:@selector(searchcontroller:didhidesearchresultstableview:)]) {                 [self.delegate searchcontroller:self didhidesearchresultstableview:self.searchresultstableview];             }         }     } }  - (bool)searchresultstableviewhidden {     return self.searchresultstableview == nil || self.searchresultstableview.hidden; }  #pragma mark searchcontroller  - (id)initwithsearchbar:(uisearchbar *)searchbar {     if (self = [super init]) {         self.searchbar = searchbar;         self.searchbar.delegate = self;     }     return self; }  - (void)setsearchresultsdatasource:(nsobject<uitableviewdatasource> *)searchresultsdatasource {     _searchresultsdatasource = searchresultsdatasource;     if (self.searchresultstableview != nil) {         self.searchresultstableview.datasource = searchresultsdatasource;     } }  - (void)setsearchresultsdelegate:(nsobject<uitableviewdelegate> *)searchresultsdelegate {     _searchresultsdelegate = searchresultsdelegate;     if (self.searchresultstableview != nil) {         self.searchresultstableview.delegate = searchresultsdelegate;     } }  #pragma mark uisearchbardelegate  - (void)searchbar:(uisearchbar *)searchbar textdidchange:(nsstring *)searchtext {     if ([self.delegate searchcontroller:self shouldreloadtableforsearchstring:searchtext]) {         [self.searchresultstableview reloaddata];         self.searchresultstableviewhidden = [self.searchresultstableview.datasource tableview:self.searchresultstableview numberofrowsinsection:0] == 0;     } }  - (void)searchbartextdidbeginediting:(uisearchbar *)searchbar {     [searchbar setshowscancelbutton:yes animated:yes];     if (self.searchresultsveil == nil) {         self.searchresultsveil = [[uibutton alloc] initwithframe:self.view.bounds];         self.searchresultsveil.backgroundcolor = [uicolor colorwithwhite:0.0 alpha:0.6];         self.searchresultsveil.autoresizingmask = uiviewautoresizingflexiblewidth | uiviewautoresizingflexibleheight;         [self.searchresultsveil addtarget:self action:@selector(didtapsearchresultsveil) forcontrolevents:uicontroleventtouchupinside];          self.searchresultstableview = [[uitableview alloc] initwithframe:self.searchresultsveil.bounds style:uitableviewstyleplain];         self.searchresultstableview.autoresizingmask = uiviewautoresizingflexiblewidth | uiviewautoresizingflexibleheight;         if ([self.searchresultstableview respondstoselector:@selector(setseparatorinset:)]) {             self.searchresultstableview.separatorinset = uiedgeinsetsmake(                 0.0,                 self.searchresultstableview.width,                 0.0,                 0.0             );         }         self.searchresultstableviewhidden = yes;         if (self.searchresultsdatasource != nil) {             self.searchresultstableview.datasource = self.searchresultsdatasource;         }         if (self.searchresultsdelegate != nil) {             self.searchresultstableview.delegate = self.searchresultsdelegate;         }          [self.view addsubview:self.searchresultsveil];         [self.searchresultsveil addsubview:self.searchresultstableview];     }     self.view.userinteractionenabled = yes;     self.searchresultsveil.hidden = no;      if ([self.delegate respondstoselector:@selector(searchcontrollerdidbeginsearch:)]) {         [self.delegate searchcontrollerdidbeginsearch:self];     } }  - (void)searchbartextdidendediting:(uisearchbar *)searchbar {     [searchbar setshowscancelbutton:no animated:yes];     self.view.userinteractionenabled = no;     self.searchresultsveil.hidden = yes;      if ([self.delegate respondstoselector:@selector(searchcontrollerdidendsearch:)]) {         [self.delegate searchcontrollerdidendsearch:self];     } }  - (void)searchbarcancelbuttonclicked:(uisearchbar *)searchbar {     [self hidesearchresults]; }  @end 

usage

self.searchcontroller = [[searchcontroller alloc] initwithsearchbar:self.searchbar]; self.searchcontroller.delegate = self; self.searchcontroller.searchresultsdatasource = self; self.searchcontroller.searchresultsdelegate = self; [self addchildviewcontroller:self.searchcontroller]; self.searchcontroller.view.frame = cgrectmake(     self.searchbar.x,     self.searchbar.bottomy,     self.searchbar.width,     self.view.height - self.searchbar.bottomy ); [self.view addsubview:self.searchcontroller.view]; [self.searchcontroller didmovetoparentviewcontroller:self]; 

Comments

Popular posts from this blog

python - Subclassed QStyledItemDelegate ignores Stylesheet -

java - HttpClient 3.1 Connection pooling vs HttpClient 4.3.2 -

SQL: Divide the sum of values in one table with the count of rows in another -