xcode iOS 13 奇怪的搜索控制器差距
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/57521967/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS 13 strange search controller gap
提问by UrosMi
When running the App on iOS 13 beta 6, using Xcode 11 beta 5 I'm encountering the strange gap when presenting search results view controller:
在 iOS 13 beta 6 上运行应用程序时,使用 Xcode 11 beta 5 我在呈现搜索结果视图控制器时遇到了奇怪的差距:
Here's a bit of how this is set up:
这是如何设置的一些内容:
let searchResultsController = BLSearchResultsController()
let ret = UISearchController(searchResultsController: searchResultsController)
ret.searchResultsUpdater = self
ret.delegate = self
ret.searchBar.delegate = self;
ret.searchBar.autocapitalizationType = .none
ret.searchBar.placeholder = NSLocalizedString("SearchMsg", comment: "")
ret.searchBar.enablesReturnKeyAutomatically = true
if #available(iOS 13.0, *) {
ret.searchBar.showsScopeBar = false
ret.searchBar.backgroundColor = .white
let searchTextField = ret.searchBar.searchTextField
searchTextField.font = UIFont.tuttiRegularFont(16)
searchTextField.accessibilityIdentifier = "Main Search Field"
if let searchImageView = searchTextField.leftView as? UIImageView {
searchImageView.image = UIImage(named: "home-search-icon")
}
}
The results search controller is a normal UITableViewController
and is just added to the navigationItem.searchController
. There is no fancy presentation code. When building on latest live Xcode and running on the iOS 11/12 device this issue is not present which lead me to believe some underlying iOS 13 change might be causing this glitch.
结果搜索控制器是一个普通的UITableViewController
,只是添加到navigationItem.searchController
. 没有花哨的演示代码。在最新的实时 Xcode 上构建并在 iOS 11/12 设备上运行时,此问题不存在,这让我相信一些底层的 iOS 13 更改可能会导致此故障。
When debugging the view hierarchy it looks like the result view controller does not reach to the top of the moved search bar.
在调试视图层次结构时,结果视图控制器似乎没有到达移动的搜索栏的顶部。
I've tried fiddling with the modalPresentationModes
trying to exclude the possibility that the changes to the presentation could be the cause, had no luck there.
我试过摆弄modalPresentationModes
试图排除演示文稿的更改可能是原因的可能性,但没有运气。
Has anyone encountered this issue and had luck fixing it?
有没有人遇到过这个问题并且很幸运地修复了它?
回答by DrS
Setting
环境
extendedLayoutIncludesOpaqueBars = true
in the UIViewController
used to show the search results, fixed the issue for me.
在UIViewController
用于显示搜索结果中,为我解决了问题。
回答by TodayMorning
回答by mirkobraic
For me the problem was that UISearchController didn't update it's frame when search bar moved upwards. I fixed it by setting frame of UISearchController to the frame of it's presenting view controller.
对我来说,问题是当搜索栏向上移动时 UISearchController 没有更新它的框架。我通过将 UISearchController 的框架设置为其呈现视图控制器的框架来修复它。
extension UISearchController {
open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if let presentingVC = self.presentingViewController {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
self.view.frame = presentingVC.view.frame
}
}
}
}
In viewWillAppear animation of search bar did not start so you have to wait for a split second. When animation starts, frame of presenting VC is set to the correct value and then you can update frame of your UISearchController. The solution is a hack but it works fine for me.
在 viewWillAppear 中,搜索栏的动画没有开始,所以你必须等待一秒钟。当动画开始时,呈现 VC 的帧被设置为正确的值,然后您可以更新 UISearchController 的帧。解决方案是一个黑客,但它对我来说很好用。
回答by Baby Groot
extendedLayoutIncludesOpaqueBars = true
did help to some extent.
extendedLayoutIncludesOpaqueBars = true
确实在一定程度上有所帮助。
Along with this, I had to update
与此同时,我不得不更新
navigationController?.navigationBar.prefersLargeTitles = false
navigationController?.navigationBar.prefersLargeTitles = false
when we start searching and set it back to true
when search bar is dismissed.
当我们开始搜索并将其设置回true
搜索栏关闭时。
回答by Nostradamus
FYI I filed a bug report to apple - according to the WWDC presentation that describes the newly re-written SearchController and some other UI updates, it sounds like the architecture of the SearchController has been re-written from the ground up. I can't believe that this gap we are seeing is expected behavior- I've wasted the better part of two days trying to move past this, and I'm not bothering any further - my app store app is a free app that has a number of users and I wasn't able to devote time to tracking changes/behavior in the API during the beta period, I'm somewhat tired of Apple doing this kind of thing on a yearly basis.
仅供参考,我向苹果提交了一份错误报告——根据描述新重写的 SearchController 和其他一些 UI 更新的 WWDC 演示文稿,听起来 SearchController 的架构已经从头开始重写。我不敢相信我们看到的这种差距是预期的行为- 我已经浪费了两天的大部分时间来试图克服这一点,而且我不再打扰 - 我的应用程序商店应用程序是一个免费的应用程序许多用户在测试期间我无法花时间跟踪 API 中的更改/行为,我对 Apple 每年都做这种事情感到有些厌倦。
回答by Raydemo
Finally get through the tough. Just to make the first controller contains the UISearchController to have a translucent navigationBar. Work for me perfectly!
终于熬过了难关。只是为了让第一个控制器包含 UISearchController 有一个半透明的导航栏。完美地对我来说有效!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.isTranslucent = false
}
回答by Alexander Survillo
- As it was mentioned in above answers, set Extend Edges Under Opaque Bars flag as On for UIViewController which presents search results. For me it was not enough because I use NOT translucent navigation bar.
- So I added the following implementation for methods of UISearchControllerDelegate:
- 正如在上面的答案中提到的那样,将显示搜索结果的 UIViewController 的“不透明条下的扩展边缘”标志设置为“开”。对我来说这还不够,因为我使用 NOT 半透明导航栏。
- 所以我为 UISearchControllerDelegate 的方法添加了以下实现:
- (void)willPresentSearchController:(UISearchController *)searchController
{
if (@available(iOS 13.0, *))
{
self.navigationController.navigationBar.translucent = YES;
}
}
- (void)willDismissSearchController:(UISearchController *)searchController
{
if (@available(iOS 13.0, *))
{
self.navigationController.navigationBar.translucent = NO;
}
}
回答by Reimond Hill
Just bringing my solution. In my case:
只是带来我的解决方案。就我而言:
edgesForExtendedLayout = .all
on the UIViewController that contains the UISearchController worked.
在包含 UISearchController 的 UIViewController 上工作。
//MARK: - Properties
var presenter: ExplorePresenting?
var searchController: UISearchController?
var searchUpdater: SearchUpdating?
//MARK: - Lifecycle methods
public override func viewDidLoad() {
super.viewDidLoad()
headerTitle = "explore".localised
tableView.allowsSelection = false
registerCell(cellClass: ExploreTableViewCell.self, with: tableView)
if let searchController = searchController {
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "explore_search_placeholder".localised
definesPresentationContext = true
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController
edgesForExtendedLayout = .all
}
presenter?.viewReady()
}
回答by Rodge
I finally solved this by replacing the UISearchController with a simple(r) UISearchBar.
我最终通过用简单的(r)UISearchBar 替换 UISearchController 解决了这个问题。
Maybe not the answer you wanted to hear, but the UISsearchController was already a mess on iOS12, the same code on iOS13 works but give horrible UI artifacts. Like disapearing or overlapping searchbar with the header, white space between the searchbar and the first element of the table, or hiding the first list-item under the scope buttons, ... All different issues between iOS12 and 13, but never looking good.
也许不是您想听到的答案,但 UISsearchController 在 iOS12 上已经一团糟,iOS13 上的相同代码可以工作,但会产生可怕的 UI 工件。就像搜索栏与标题消失或重叠,搜索栏和表格的第一个元素之间的空白,或隐藏范围按钮下的第一个列表项,...... iOS12 和 13 之间的所有不同问题,但永远不会好看。
So overall I spent 6 hours trying to fix the searchcontroller, failed, then spent 30 mins migrating to the Searchbar.
所以总的来说,我花了 6 个小时试图修复搜索控制器,失败了,然后花了 30 分钟迁移到搜索栏。
I added the UISearchBar simply using Interface Builder in Xcode10.3. For the refactoring, mostly I had to simply replace searchController.searchBar.xxby searchBar.xx . The main effort was to reimplement the UISeachBarDelegates. Just to only show the scopebuttons and cancel button while the user is searching, and removing them afterwards. The code below gives a good overview of what I did:
我只是在 Xcode10.3 中使用 Interface Builder 添加了 UISearchBar。对于重构,大多数情况下我不得不简单地替换 searchController.searchBar。xx通过 searchBar.xx 。主要的努力是重新实现 UISeachBarDelegates。只是在用户搜索时仅显示范围按钮和取消按钮,然后将其删除。下面的代码很好地概述了我所做的事情:
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate {
var fetchedItemsController: NSFetchedResultsController<Item>! = NSFetchedResultsController()
@IBOutlet weak var searchBar: UISearchBar! //hooked up to IB
//GONE IS: let searchController = UISearchController(searchResultsController: nil)
override func viewDidLoad() {
super.viewDidLoad()
initializeFetchedResultsControllerForItems()
//Enable search controller
searchBar.scopeButtonTitles = [NSLocalizedString("Name", comment: ""),
NSLocalizedString("Birthdate", comment: ""),
NSLocalizedString("Employer", comment: "") ]
searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.delegate = self
searchBar.showsScopeBar = false
searchBar.showsCancelButton = false
tableView.contentInsetAdjustmentBehavior = .automatic
self.tableView.tableHeaderView = searchBar //add the searchbar as tableheader view
self.initializeFetchedResultsControllerForItems()
}
// MARK: - Data loading from CoreData
private func initializeFetchedResultsControllerForItems(searchText: String = "", scopeIndex: Int = 0) {
//print("FETCH RESULTS WITH FILTER: \(searchText) en SCOPE: \(scopeIndex)")
//Do whatever searches you need to do to update the FetchedResultsController
//..
self.tableView.reloadData()
}
}
extension MasterViewController: UISearchBarDelegate { //the delegates for the searchbar
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
searchBar.showsScopeBar = true //show the scopebar when users adds text to searchbar
searchBar.showsCancelButton = true //also show the cancel button
searchBar.sizeToFit()
self.tableView.reloadData() //since the scopebar is there, the table needs to move a bit down
}
func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
}
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
switch (selectedScope) {
case 0: searchBar.placeholder = NSLocalizedString("Seach on name", comment: "")
case 1: searchBar.placeholder = NSLocalizedString("Search on birthdate", comment: "")
case 2: searchBar.placeholder = NSLocalizedString("Search on employer", comment: "")
default: searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.showsScopeBar = true
searchBar.sizeToFit()
}
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: selectedScope)
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searchBar.placeholder = NSLocalizedString("Search", comment: "")
searchBar.showsScopeBar = false
searchBar.showsCancelButton = false
searchBar.endEditing(true)
searchBar.text = ""
searchBar.sizeToFit()
initializeFetchedResultsControllerForItems(searchText: searchBar.text!, scopeIndex: searchBar.selectedScopeButtonIndex)
}
}
回答by user3187971
You must set yours navigationBar.standardAppearance to an UINavigationBarAppearance object that describes a white background.
您必须将您的 navigationBar.standardAppearance 设置为描述白色背景的 UINavigationBarAppearance 对象。
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .white
self.navigationController?.navigationBar.standardAppearance = appearance
}