每次点击取消按钮时,搜索栏都会向下跳一排

Posted

技术标签:

【中文标题】每次点击取消按钮时,搜索栏都会向下跳一排【英文标题】: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 检查我的答案... 【参考方案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:)

【讨论】:

以上是关于每次点击取消按钮时,搜索栏都会向下跳一排的主要内容,如果未能解决你的问题,请参考以下文章

每次点击保存时,我的按钮或文本都会重复?

UISearchBar - 当点击取消按钮时,如何防止关闭 scopeBar?

UISearchController 在点击取消按钮时关闭 VC

如何关闭浏览器搜索时的百度智能小程序?

Laravel 输入类型搜索取消按钮提交表单

最小化后不在任务栏显示图标怎么办