Tencent / QMUI_iOS

QMUI iOS——致力于提高项目 UI 开发效率的解决方案
http://qmuiteam.com/ios
Other
7.09k stars 1.38k forks source link

[UIKit Bug] 当 UISearchController.searchBar 作为 tableHeaderView 使用时,顶部可能出现 1px 的间隙导致露出背景色 #950

Closed MoLice closed 4 years ago

MoLice commented 4 years ago

如何重现

  1. 使用一张透明图片(例如 UIImage.new)作为 UINavigationBar.shadowImage,避免导航栏分隔线挡住 searchBar 导致无法观察到 bug 现象。
  2. 为了便于观察,可以把 searchBar 的背景图设置为纯色,但这一步非必须,可以保持系统默认的外观。
  3. 创建一个 UITableViewController 界面,初始化一个 UISearchController 并将它的 searchBar 属性赋值给 tableView.tableHeaderView。为了便于观察,可将 tableView.backgroundColor 设置为显眼的颜色。
  4. 进入该列表界面,可看到一开始 searchBarnavigationBar 是贴合在一起的。
  5. 上下滚动列表,会触发 searchBar 重新布局,当列表停止滚动后可以看到 searchBar 顶部出现一个 1px 的间隙。

截图

测试 Demo TestSearchBar.zip

注意 如果直接初始化一个 UISearchBar 并赋值给 tableHeaderView,则不会出现该问题。

其他信息

MoLice commented 4 years ago

image

断点观察到在滚动列表时,UISearchController 内部确实有一套机制去根据 UIScrollView 的滚动动作调整 UISearchBar 内部的 maskView 布局,从而保证即便 navigationBar 背景透明,searchBar 也不会透出到 navigationBar 背后。目前暂时通过 swizzle - [UISearchBar _setMaskBounds:] 来优化这种调整,不管有没有 shadowImage,maskView 都没必要留出顶部的 1px 间隙,下个版本会给出对应的接口。

RomanticEncounter commented 4 years ago

Bug 表现 searchControl导致navBar的关联性问题

iOS 11及以上系统,滑动UITableView会出现LargeTitle动画效果

self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeNever;
    [self.view addSubview:self.tableView];
    if (@available(iOS 11.0, *)) {
        self.navigationItem.searchController = self.searchController;
    } else {
        // Fallback on earlier versions
       // 设置为HeaderView则不会出现此问题
        self.tableView.tableHeaderView = self.searchController.searchBar;
    }

截图

第一次进来 首次进入的效果

滑动后的效果 滑动后的效果

触发UINavigationController(LargeTitleCompatibility)swizzle方法 scrollView滑动时代码

ziecho commented 4 years ago

Bug 表现 searchControl导致navBar的关联性问题

iOS 11及以上系统,滑动UITableView会出现LargeTitle动画效果

你是指 navigationBar 变透明了吗,这个是 iOS 11 设置了 navigationItem.searchController 后的系统默认特性,和 QMUI 无关,如果你不需要这个特性请写上

self.navigationItem.hidesSearchBarWhenScrolling = NO;
MoLice commented 4 years ago

已发布 4.1.2 修复该问题。