搜索栏在活动时移动
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 上,导航项中的搜索栏在导航弹出时折叠并卡在状态栏下