2

When you press refresh, Safari's search bar displays a progress view.

My requirements are:

  1. the progress view should have rounded corners matching the search bar's corners

  2. the progress view width should adjust itself if a cancel button is shown.

Here is my naive attempt using PureLayout for constraints:

 if let tf = sb.textField {
      tf.addSubview(progressView)

      // Match the search bar's text field height - 1
      progressView.autoPinEdgesToSuperviewEdges(
        with: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 1.0, right: 0.0)
      )
      progressView.isUserInteractionEnabled = false
      progressView.clipsToBounds = true
      progressView.layer.cornerRadius = 12

      let mask = UIView(forAutoLayout: ())
      mask.backgroundColor = UIColor(white: 0.0, alpha: 1.0)

      progressView.addSubview(mask)

      mask.autoPinEdgesToSuperviewEdges(
        with: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 1.0, right: 0.0)
      )
    }

It works but the search bar's textfield loses its gray background.

Anyone's got a better approach?

Kugutsumen
  • 878
  • 8
  • 18

2 Answers2

2

1. You can go with this way, it's completely working for me. code is below :

let backview = UIView()
backview.backgroundColor = UIColor.clear
 DispatchQueue.main.async {
        let progress = UIProgressView()

        let searchfield = (self.searchbar.value(forKey: "searchField") as? UITextField)! //searchBar's textField

        progress.frame = CGRect(x: 0, y: searchfield.frame.height - 2, width: self.searchbar.subviews[0].subviews[1].frame.width  , height: 2)
        progress.tintColor = UIColor.systemBlue //Color you want
        progress.progress = 0.0
    
        backview.frame = searchfield.frame
        backview.autoresizingMask = .flexibleWidth
        backview.layer.cornerRadius = 10
        backview.layer.masksToBounds = true
        backview.isUserInteractionEnabled = false
        backview.addSubview(self.progress)

        self.searchbar.addSubview(backview) //self.searchbar is your UISearchBar
    }

2. When you click on searchBar you can show cancel button and your progressView hidden. i hope it will help you.

Nayan Dave
  • 1,078
  • 1
  • 8
  • 30
Virani Vivek
  • 888
  • 1
  • 8
  • 22
  • Interesting approach... In iOS 13, it just display a tiny bit of the progress view in the top left corner of the searchBar.textField.. – Kugutsumen Sep 11 '19 at 10:13
  • I posted an answer based on yours that works perfectly in iOS 12 and 13. Thanks for pointing me in the right direction. – Kugutsumen Sep 11 '19 at 10:32
  • thanks,if my answer is usable please marked to right. – Virani Vivek Sep 11 '19 at 10:35
  • No it isn't useable. Your solution shows a tiny bit of progress view on the top left corner instead of showing the progress view at the bottom of the textfield. That's probably because you use 'self.searchbar.subviews[0].subviews[1]'. Also if you used constraint you don't need to hide and unhide the progress view. – Kugutsumen Sep 11 '19 at 10:39
1

Thanks to virani-vevek for pointing me in the right direction. Here is a working solution.

  if let tf = sb.textField {
      let back = UIView()
      tf.addSubview(back)

      back.autoPinEdgesToSuperviewEdges(
        with: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
      )
      back.backgroundColor = UIColor.clear
      back.isUserInteractionEnabled = false
      back.layer.cornerRadius = 12
      back.layer.masksToBounds = true
      back.addSubview(progress)

      progress.autoPinEdgesToSuperviewEdges(
        with: UIEdgeInsets(top: tf.frame.height - 1, left: 0, bottom: 0, right: 0)
      )

      progress.trackTintColor = .clear
      progress.tintColor = Theme.current.tintColor
      progress.progress = 0.5 // debug value
    }
Kugutsumen
  • 878
  • 8
  • 18