用 UIActivityViewController 替换 UISearchBar 放大图标
Posted
技术标签:
【中文标题】用 UIActivityViewController 替换 UISearchBar 放大图标【英文标题】:Replacing UISearchBar magnifying icon with UIActivityViewController 【发布时间】:2019-08-04 10:42:40 【问题描述】:我已经搜索了一整天,但找不到此代码的修复方法。 此扩展将 UISearchField 放大图标替换为 UIActivityView(为 true 时显示加载图标)
该扩展在 iOS 12、Xcode 10.3 上运行良好,但在我更改为 iOS 13、Xcode 11 之后Beta 4 停止工作。
我仍然使用这个解决方法:
if let textFieldInsideSearchBar = searchBar.value(forKey: "searchField") as? UITextField
let loadingIcon = UIActivityIndicatorView()
loadingIcon.style = .medium
loadingIcon.backgroundColor = UIColor.clear
loadingIcon.startAnimating()
textFieldInsideSearchBar.leftView = loadingIcon
但我无法理解扩展程序停止工作的原因。
我还注意到 .flatMap
在 iOS 13 中已弃用并更改为 .compactMap
但据我所知没有区别,我已经尝试过将 .flatMap
更改为 .compactMap
但仍然无效。
这是扩展名:
extension UISearchBar
private var textField: UITextField?
let subViews = self.subviews.compactMap $0.subviews
return (subViews.filter $0 is UITextField ).first as? UITextField
private var searchIcon: UIImage?
let subViews = subviews.flatMap $0.subviews
return ((subViews.filter $0 is UIImageView ).first as? UIImageView)?.image
private var activityIndicator: UIActivityIndicatorView?
return textField?.leftView?.subviews.compactMap $0 as? UIActivityIndicatorView .first
var isLoading: Bool
get
return activityIndicator != nil
set
let _searchIcon = searchIcon
if newValue
if activityIndicator == nil
let _activityIndicator = UIActivityIndicatorView()
_activityIndicator.style = .medium
_activityIndicator.startAnimating()
_activityIndicator.backgroundColor = UIColor.clear
self.setImage(UIImage(), for: .search, state: .normal)
textField?.leftView?.addSubview(_activityIndicator)
let leftViewSize = textField?.leftView?.frame.size ?? CGSize.zero
_activityIndicator.center = CGPoint(x: leftViewSize.width/2, y: leftViewSize.height/2)
else
self.setImage(_searchIcon, for: .search, state: .normal)
activityIndicator?.removeFromSuperview()
【问题讨论】:
请注意,在 ios13 中,如果您将图像设置为 UIImage(),则文本会一直向左移动(包含放大图标的视图会被移除)。然后将“leftViewSize”的初始化设置为 .zero。将空图像设置为“leftViewSize”大小的空/透明图像。 【参考方案1】:iOS 13 在 UISearchBar 方面发生了一些变化,您可以使用UISearchBar.searchTextField
代替searchBar.value(forKey: "searchField")
searchBar.searchTextField.backgroundColor = .red
或者如果你想让它与扩展一起工作,你可以这样做:
var searchTextField: UITextField?
let subViews = self.subviews.first?.subviews.last?.subviews
return subViews?.first as? UITextField
【讨论】:
感谢您的回答!我已经替换了您的扩展代码,但现在当我运行它时,UIActivityView 超出了 searchField。知道如何解决这个问题吗? 尝试为 UIActivityIndicatorView 设置一个框架。 let _activityIndicator = UIActivityIndicatorView(frame: CGRect(origin: .zero, size: CGSize(width: 24, height: 24))) 你必须取消设置 UIActivityIndicatorView 的中心点,你不能设置框架和中心 let _activityIndicator = UIActivityIndicatorView(frame: CGRect(origin: .zero, size: CGSize(width: 24, height: 24))) _activityIndicator.translatesAutoresizingMaskIntoConstraints = true _activityIndicator.style = .medium _activityIndicator.startAnimating () _activityIndicator.backgroundColor = UIColor.clear cutomTextField?.leftViewMode = .always cutomTextField?.leftView = _activityIndicator 非常感谢您的回答!我已经设法用我编写的代码(不是扩展名)获得了相同的结果,问题是当我将 UIActivityIndicatorView 设置为 false 时我无法删除它,现在我遇到了同样的问题使用您现在编写的代码。我猜是因为 cutomTextField?.leftView = _activityIndicator以上是关于用 UIActivityViewController 替换 UISearchBar 放大图标的主要内容,如果未能解决你的问题,请参考以下文章
iOS 8.3:UIActivityViewController 显示无关的行
SwiftUI完美弹出UIActivityViewController(通过微信QQ或隔空投送分享)的应用分享窗口