Agamemnon
Agamemnon

Reputation: 607

SearchBar moves when active

I have a UIViewController with a SegmentedControl, UITableView and a UISearchController. The SegmentedControl is at the top of the main View with the tableView just beneath it. The searchController's searchBar is placed in the tableView.tableHeaderView and looks like this:

enter image description here

When the searchBar is tapped (made active) it moves down leaving a gap just above:

enter image description here

Also, if the searchBar is active and then the segmentedConrol is tapped (filtering the table data and reloading the tableView) then the tableView loads but with a gap at the top. (I have purposely set the searchBar to hidden when the 'Category' filter is selected.

enter image description here

If the segmentedControl 'Category' is selected when the searchBar is not active this is how it looks (and should look):

enter image description here

I need two things (I think they are related), 1) for the searchBar to NOT move when active and 2) for the searchBar to not be present when 'Category' is selected and for the tableView to have no gap at the top.

.h:

@interface ExhibitorViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
{
    // DATA
    NSMutableArray *arrayOfExhibitors;
    NSMutableArray *arrayOfExhibitorsFiltered;
    NSMutableArray *arrayOfCategories;
    NSMutableArray *arrayOfCategoriesFiltered;

    // VARS
    int selectedSegment;
    float searchBarHeight;
    float tableViewY;
    NSString *currentCategory;
    CGRect tableViewStartRect;

    // UI
    UISegmentedControl *segmentedControl;
    UIView *categorySelectedView;
    UIView *headerView;

}

@property (nonatomic, strong) UITableView *tableView;
@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, readonly) NSArray *searchResults;
@property (strong, nonatomic) NSString *sponsorsOnly;

@end

.m:

-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.navigationController setNavigationBarHidden:NO animated:NO];
    if (selectedSegment == 0) {
        self.searchController.searchBar.hidden = FALSE;
    }
    if (!_searchController.searchBar.superview) {
        self.tableView.tableHeaderView = self.searchController.searchBar;
    }
}

-(void)loadTableView
{
    [self printStats:@"loadTableView START"];
    searchBarHeight = self.searchController.searchBar.frame.size.height;
    Settings *settingsInstance = [Settings new];

    if(!_tableView) {        
        segmentedControl = [UISegmentedControl new];
        segmentedControl = [[UISegmentedControl alloc]initWithItems:[NSArray arrayWithObjects:@"Exhibitor", @"Category", nil]];
        [segmentedControl setFrame:CGRectMake(0, 0, self.view.frame.size.width, 35)];
        segmentedControl.selectedSegmentIndex = 0;
        [segmentedControl addTarget:self action:@selector(segmentedControlHasChangedValue) forControlEvents:UIControlEventValueChanged];

        self.automaticallyAdjustsScrollViewInsets = YES;
        self.edgesForExtendedLayout = UIRectEdgeNone;
        self.searchController.hidesNavigationBarDuringPresentation = NO;
        //self.definesPresentationContext = NO;

        float tvX = self.view.frame.origin.x;
        float tvY = self.view.frame.origin.y + segmentedControl.frame.size.height;
        float tvWidth = self.view.frame.size.width;
        float frameHeight = self.view.frame.size.height;
        float tvHeight = self.view.frame.size.height - segmentedControl.frame.size.height;
        tableViewStartRect = CGRectMake(tvX, tvY, tvWidth, tvHeight);

        _tableView = [UITableView new];
        _tableView = [[UITableView alloc]     initWithFrame:tableViewStartRect];
        //_tableView.contentInset = UIEdgeInsetsMake(0, 0, 44, 0);
        _tableView.separatorColor = [UIColor clearColor];
        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

        [self.view addSubview:segmentedControl];
        [self.view addSubview:_tableView];
        [_tableView setTag:1];
        [_tableView setDataSource:self];
        [_tableView setDelegate:self];
    }

    if (!categorySelectedView) {
        float levelOneStart = (0);
        categorySelectedView = [[UIView alloc] initWithFrame:CGRectMake(0, levelOneStart, self.view.frame.size.width, (screenHeight * 0.05))];
        [categorySelectedView setBackgroundColor:[UIColor grayColor]];
        [categorySelectedView setTag:4];
        MyLabel *catSelectedLabel = [[MyLabel alloc]     initWithFrame:categorySelectedView.frame];
        [catSelectedLabel setFont:[UIFont systemFontOfSize:[settingsInstance getFontSizeFor:@"Label"]]];
        [catSelectedLabel setTag:5];
        [catSelectedLabel setBackgroundColor:[UIColor lightTextColor]];
        [catSelectedLabel setTextColor:[UIColor darkGrayColor]];
        UIButton *categoryBackButton = [[UIButton alloc] initWithFrame:CGRectMake((screenWidth * 0.6), levelOneStart, (screenWidth * 0.4), (screenHeight * 0.05))];
        [categoryBackButton setTitle:@"^ Back ^" forState:UIControlStateNormal];
        [categoryBackButton setTitleColor:[UIColor darkGrayColor] forState:UIControlStateNormal];
        [categoryBackButton addTarget:self action:@selector(resetTableViewCategories) forControlEvents:UIControlEventTouchUpInside];
        [catSelectedLabel addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(resetTableViewCategories)]];
        [categoryBackButton.titleLabel setFont:[UIFont systemFontOfSize:[settingsInstance getFontSizeFor:@"Label"]]];
        [categorySelectedView addSubview:catSelectedLabel];
        [categorySelectedView addSubview:categoryBackButton];
        [categorySelectedView setHidden:TRUE];
    }

    if (!headerView) {
        headerView = [[UIView alloc] initWithFrame:CGRectMake(0, (0), screenWidth, (searchBarHeight))];
        [headerView addSubview:categorySelectedView];
        [self.view addSubview:headerView];
        [headerView setBackgroundColor:[UIColor purpleColor]];
        [self.view sendSubviewToBack:headerView];
    }

    [self.view setTag:11];

    tableViewY = _tableView.frame.origin.y;
    [self printStats:@"loadTableView END"];
}

-(UISearchController*)searchController
{
    if (!_searchController) {
        _searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
        _searchController.searchResultsUpdater = self;
        _searchController.dimsBackgroundDuringPresentation = NO;
        _searchController.searchBar.delegate = self;
        [_searchController.searchBar sizeToFit];
    }

    return _searchController;
}

-(void)segmentedControlHasChangedValue
{
    [self.searchController setActive:NO];
    if ((segmentedControl.selectedSegmentIndex == 0)) {
        selectedSegment = 0;
        currentCategory = @"";
        [self resetTableViewExhibitors];
        [_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
    } else {
        selectedSegment = 1;
        [self resetTableViewCategories];
        [_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
        //[_tableView setContentOffset:CGPointMake(0, 56) animated:NO];
        [_tableView setTableFooterView:nil];
    }

    [_tableView reloadData];
}

I have tried changing the insets of various views and forcing a manual changes to the frames of various views (this is the closest thing to a fix but seems very hacky). What am I doing wrong?

Edit: Have also tried :

-(void)segmentedControlHasChangedValue
{
    [self.searchController setActive:NO];
    if ((segmentedControl.selectedSegmentIndex == 0)) {
        selectedSegment = 0;
        currentCategory = @"";
        [self resetTableViewExhibitors];
        [_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
    } else {
        selectedSegment = 1;
        [_searchController dismissViewControllerAnimated:NO completion^() {
            [self resetTableViewCategories];
            [_tableView setContentOffset:CGPointMake(0, -1) animated:NO];
            [_tableView setTableFooterView:nil];
        }];
    }
    [_tableView reloadData];
}

Upvotes: 2

Views: 994

Answers (1)

trungduc
trungduc

Reputation: 12144

Because you use UISearchController so searchBar will always move when it actives. To avoid it, use UISearchBar. And when you use UISearchBar, it's easy to hide when you select Category tab

Upvotes: 2

Related Questions