【问题标题】:Replacing UISearchBar magnifying icon with UIActivityViewController用 UIActivityViewController 替换 UISearchBar 放大图标
【发布时间】: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”大小的空/透明图像。

标签: swift xcode11 ios13


【解决方案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。知道如何解决这个问题吗?
  • 尝试为 UIActivityIndi​​catorView 设置一个框架。 let _activityIndi​​cator = UIActivityIndi​​catorView(frame: CGRect(origin: .zero, size: CGSize(width: 24, height: 24)))
  • 你必须取消设置 UIActivityIndi​​catorView 的中心点,你不能设置框架和中心
  • let _activityIndi​​cator = UIActivityIndi​​catorView(frame: CGRect(origin: .zero, size: CGSize(width: 24, height: 24))) _activityIndi​​cator.translatesAutoresizingMaskIntoConstraints = true _activityIndi​​cator.style = .medium _activityIndi​​cator.startAnimating () _activityIndi​​cator.backgroundColor = UIColor.clear cutomTextField?.leftViewMode = .always cutomTextField?.leftView = _activityIndi​​cator
  • 非常感谢您的回答!我已经设法用我编写的代码(不是扩展名)获得了相同的结果,问题是当我将 UIActivityIndi​​catorView 设置为 false 时我无法删除它,现在我遇到了同样的问题使用您现在编写的代码。我猜是因为 cutomTextField?.leftView = _activityIndi​​cator
猜你喜欢
  • 1970-01-01
  • 2013-03-28
  • 1970-01-01
  • 2016-08-03
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多