UISearchBar 在单击时修改其 frame/bounds

UISearchBar modifying its frame/bounds when clicked

我正在尝试在我的应用程序 UI 中放置一个 UISearchController。布局是:

我想将 UISearchController 的 UISearchView 放在黑色容器中。

我的代码如下:

self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsViewController];
UISearchBar* searchBar = self.searchController.searchBar;
searchBar.frame =_searchBarContainer.bounds;
[_searchBarContainer addSubview:searchBar];
[_searchBarContainer layoutIfNeeded];

它将 UISearchBar 放置在正确的位置:

但是当我 select 搜索字段时,它会将栏扩展到容器的边界上:

我怎样才能解决这个问题并避免 size/appearance 在 selected 时发生变化?

注意:尝试了一些与 translatesAutoresizingMaskIntoConstraintsclipToBounds 选项一起玩的选项,但没有成功。我不是 iOS UI 的专家,所以我希望得到准确的回答。谢谢

根据我的研究,每次你 select SearchBar,都会出现一个 UISearchController。这个 UISearchController 总是试图使 searchBar 的宽度等于 UIViewController 呈现 UISearchController.

我的解决方法是当UISearchController使SearchBar帧错误时,重新设置SearchBar'帧。您可以尝试下面的代码。

@interface ViewController () <UISearchControllerDelegate>

@property (nonatomic, strong) UISearchController* searchController;
@property (weak, nonatomic) IBOutlet UIView *searchBarContainer;

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  self.searchController = [[UISearchController alloc] initWithSearchResultsController:searchResultsViewController];
  UISearchBar* searchBar = self.searchController.searchBar;
  self.searchController.delegate = self;
  searchBar.frame =_searchBarContainer.bounds;
  [_searchBarContainer addSubview:searchBar];
  [_searchBarContainer layoutIfNeeded];



}

- (void)willPresentSearchController:(UISearchController *)searchController {
  [searchController.searchBar addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
}

- (void)willDismissSearchController:(UISearchController *)searchController{
  [searchController.searchBar removeObserver:self forKeyPath:@"frame"];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
  if (object == self.searchController.searchBar) {
    if (!CGSizeEqualToSize(self.searchController.searchBar.frame.size, _searchBarContainer.frame.size)) {
      self.searchController.searchBar.superview.clipsToBounds = NO;
      self.searchController.searchBar.frame = CGRectMake(0, 0, _searchBarContainer.frame.size.width, _searchBarContainer.frame.size.height);
    }
  }
}

@end

至少,它有效:)

  • 您可以创建另一个包含 SearchBarUIViewController,然后将其添加到 _searchBarContainer(如果您的案例对此没有任何问题)。
  • 使用 UISearchBarUITableView 而不是 UISearchController。更容易处理。

我找到了有用的信息。

点击 UISearchBar 时会调用多种方法。 当这个方法的某些部分被调用时,UISearchBar 的框架改变了他的值。

其中一种方法尝试填充等于 UIViewController 的宽度。

尝试使用以下方法之一设置帧值:

searchBarTextDidBeginEditing
searchBarShouldBeginEditing

通过这种方式您可以覆盖默认值。

再见