搜索栏在活动时移动

Posted

技术标签:

【中文标题】搜索栏在活动时移动【英文标题】:SearchBar moves when active 【发布时间】:2017-11-16 10:32:08 【问题描述】:

我有一个带有 SegmentedControl、UITableView 和 UISearchController 的 UIViewController。 SegmentedControl 位于主视图的顶部,tableView 位于其下方。 searchController 的 searchBar 放在 tableView.tableHeaderView 中,如下所示:

当 searchBar 被点击(激活)时,它会向下移动,在上方留下一个间隙:

此外,如果 searchBar 处于活动状态,然后点击了 segmentedConrol(过滤表格数据并重新加载 tableView),则 tableView 加载但顶部有间隙。 (我在选择“类别”过滤器时,我已经故意将搜索栏设置为隐藏。

如果在 searchBar 未激活时选择了 segmentedControl 'Category',这就是它的外观(并且应该看起来):

我需要两件事(我认为它们是相关的),1)搜索栏在活动时不移动,2)搜索栏在选择“类别”时不存在,并且 tableView 在顶端。

.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];

我已经尝试更改各种视图的插图并强制手动更改各种视图的框架(这是最接近修复的方法,但看起来很hacky)。我做错了什么?

编辑:也试过了:

-(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];

【问题讨论】:

您是否在点击段时尝试关闭_searchController 或取消选择_searchController.searchBar 我只是将搜索栏隐藏或移动了。您的意思是完全删除 _searchController / searchBar(作为视图),然后在再次点击分段控件(到主过滤器)时重建? 我的意思是[_searchController dismissViewControllerAnimated:NO completion:^];,您可以在完成块中更改为段2 当我添加该函数调用并为第二个段包装 segmentedControlValueHasChanged 的​​内容时,searchBar 现在填补了 tableView 的“类别”过滤侧的空白(添加了对问题的编辑)。跨度> 你解决了问题真是太好了:) 【参考方案1】:

因为您使用UISearchController,所以searchBar 在激活时总是会移动。为避免这种情况,请使用UISearchBar。而当你使用UISearchBar时,选择Category tab时很容易隐藏

【讨论】:

我停止使用 UISearchController 而只是使用了 UISearchBar,现在一切正常。

以上是关于搜索栏在活动时移动的主要内容,如果未能解决你的问题,请参考以下文章

UISearchController 搜索栏在出现时向下移动

在 iOS 11 上,导航项中的搜索栏在导航弹出时折叠并卡在状态栏下

移动开发中导航栏和搜索栏在设计中应该注意哪些问题?

Swift Navigationbar 搜索栏在单击时关闭搜索文本

搜索栏在点击时隐藏

UISearchBar 在活动时与 UITableView 内容重叠