【问题标题】:Search bar jumps down one row every time cancel button is tapped每次点击取消按钮时,搜索栏都会向下跳一排
【发布时间】:2016-10-11 16:40:39
【问题描述】:

我已经实现了一个 UISearchBar 来搜索来自外部 API 的项目目录。搜索功能按预期工作,但问题是每次我按下搜索栏文本字段右侧的取消按钮时,整个搜索栏都会向下移动一行,看起来就像是推动了整个搜索栏表视图向下为好。

因此,如果我在搜索栏文本字段中键入一个字母,然后按取消,搜索栏文本字段会向下移动 44px,即行高,并且表格视图本身也会被向下推相同的量。如果我连续按输入内容,然后按取消,搜索栏将在视图中越来越远。任何建议都会很棒!这是我的代码:

import Foundation
import UIKit
import ItemLogger


private extension Selector {
    static let dismiss = #selector(SearchVC.dismissView)
}


extension SearchVC: UISearchResultsUpdating {
    func updateSearchResultsForSearchController(searchController: UISearchController) {
        let searchBar = searchController.searchBar
        let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
        filterContentForSearchText(searchController.searchBar.text!, scope: scope)
    }
}
extension SearchVC: UISearchBarDelegate {
    func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
        filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
    }
}

class SearchVC: UITableViewController {

    let searchController = UISearchController(searchResultsController: nil)
    var searchedItems = [ItemLog]()
    var searchedImages = [UIImage]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let leftBarButtonItem = UIBarButtonItem(image: UIImage(named: "Back_Button"), style: UIBarButtonItemStyle.Plain, target: self, action: .dismiss)
        self.navigationItem.leftBarButtonItem = leftBarButtonItem
    }


    override func viewWillAppear(animated: Bool) {
        configureSearchController()
    }


    override func prefersStatusBarHidden() -> Bool {
        return true
    }


    func configureSearchController() {

        guard !searchController.active else {
            return
        }

        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        searchController.searchBar.placeholder = "Type to Search"

        definesPresentationContext = true
        searchController.searchBar.scopeButtonTitles = ["All"]
        searchController.searchBar.delegate = self
        searchController.searchBar.sizeToFit()
        tableView.tableHeaderView = searchController.searchBar

        let view: UIView = self.searchController.searchBar.subviews[0] as UIView
        for subView: UIView in view.subviews {
            if let textView = subView as? UITextField {
                textView.tintColor = UIColor.orangeColor()
                textView.textColor = UIColor.blackColor()
                textView.backgroundColor = UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.05)
            }
        }
        searchController.searchBar.barTintColor = UIColor.whiteColor()

        let cancelButtonAttributes: NSDictionary = [NSForegroundColorAttributeName: UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.33)]
        UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes as? [String : AnyObject], forState: UIControlState.Normal)
    }



    func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
        tableView.reloadData()
    }


    override func tableView(tableView:UITableView, numberOfRowsInSection section: Int) -> Int {
        if searchController.active && searchController.searchBar.text != "" {
            return searchedItems.count
        }

        return 0

    }

    override func tableView(tableView:UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        let cell = self.tableView.dequeueReusableCellWithIdentifier("items", forIndexPath: indexPath)

        let label = cell.viewWithTag(111) as! UILabel
        let nameLabel = cell.viewWithTag(222) as! UILabel
        let art = cell.viewWithTag(333) as! UIImageView

        if searchController.active && searchController.searchBar.text != "" && searchController.searchBar.text != NSCharacterSet.whitespaceCharacterSet(){

            label.text = searchedItems[indexPath.row].title
            nameLabel.text = searchedItems[indexPath.row].name
            art.image = searchedImages[indexPath.row]
        }
        return cell
    }



    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

        print(searchedItems[indexPath.row])
        self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }


    func filterContentForSearchText(searchText: String, scope: String = "All") {


        if searchController.active && searchController.searchBar.text != "" && searchController.searchBar.text != NSCharacterSet.whitespaceCharacterSet() {
            let queries: [SearchQueryOptions] = [
                .QueryString(searchController.searchBar.text!)]
            ItemLog.search(queries, completion: { (result) in
                if let itms = result.response.result where itms.count > 0 {
                    self.searchedItems.removeAll()
                    self.searchedImages.removeAll()
                    for i in 0...itms.count - 1 {

                        self.searchedItems.append(itms[i])
                        self.searchedImages.append(itms[i].img)

                    }
                }
                self.tableView.reloadData()
            })
        }
    }


    func dismissView(){
        self.navigationController?.popToRootViewControllerAnimated(true)
    }

}

【问题讨论】:

  • 用故事板和运行时结果更新您的问题。
  • @MikeG 检查我的答案...

标签: ios swift uisearchbar uisearchcontroller


【解决方案1】:

在 Swift 3 中测试的代码。

注意:我何时尝试您的代码。我面临着同样的问题。不知怎的,我设法绕过了......

class SearchVC: UITableViewController,UISearchBarDelegate,UISearchResultUpdating {

var resultSearchController = UISearchController()

override func viewDidLoad() {
    super.viewDidLoad()

     configureSearchController()
 }


override var prefersStatusBarHidden: Bool {

    return true
}


func configureSearchController() {

    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)
        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.hidesNavigationBarDuringPresentation = false
        controller.searchBar.searchBarStyle = .default
        controller.searchBar.sizeToFit()
        controller.searchBar.setShowsCancelButton(false, animated: true)
        controller.searchBar.keyboardAppearance = .default

        self.tableView.tableHeaderView = controller.searchBar

        //controller.searchBar.tintColor = UIColor(patternImage: UIImage(named: "xxxx")!)
        // controller.searchBar.setBackgroundImage(UIImage(named: "xxxx"), forBarPosition: UIBarPosition.Top, barMetrics: UIBarMetrics.Default)
        //  controller.searchBar.backgroundImage = UIImage(named: "xxxx")
        // controller.searchBar.setImage(UIImage(named: "search-icon.png"), forSearchBarIcon: UISearchBarIcon.Search, state: UIControlState.Normal)

        return controller
    })()


    for subView in self.resultSearchController.searchBar.subviews
    {
        for subsubView in subView.subviews
        {
            if let textField = subsubView as? UITextField
            {
                textField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("Search Text", comment: ""), attributes: [NSForegroundColorAttributeName: UIColor.red])

                textField.adjustsFontSizeToFitWidth = true
                textField.allowsEditingTextAttributes = true


                textField.textColor = UIColor.red
                textField.layer.borderColor = UIColor.gray.cgColor
                textField.layer.cornerRadius = 5
                textField.layer.masksToBounds = true

                textField.layer.borderWidth = 0.215

            }
         }  
      }
   }
}

更新:

  func updateSearchResults(for searchController: UISearchController) {}

以上代码的输出..希望我的回答能解决您的问题....

【讨论】:

  • 太棒了!经过一番测试后,我注意到它与 searchBar scope 有关。仍然不确定它到底是什么,但结合你的答案和一些修补就可以了。非常感谢
【解决方案2】:

我做了一个开源项目SearchTableView

self.searchController.searchBar.sizeToFit()
self.tableHeaderView = self.searchController.searchBar

searchTableView.layoutMargins = UIEdgeInsets.zero
definesPresentationContext = true
extendedLayoutIncludesOpaqueBars = true

【讨论】:

    【解决方案3】:

    尝试在viewDidLoad 中调用configureSearchController()。 并且不要忘记在您的viewWillAppear 中致电super.viewWillAppear(animated:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-13
      相关资源
      最近更新 更多