使用UISearchController自定义UISearchBar

时间:2014-09-18 04:32:16

标签: ios ios8 uisearchbar uisearchcontroller

UISearchController的文档说明您可以覆盖- searchBar以提供UISearchBar的自定义子类供控制器使用。确实使用了自定义搜索栏,并且正确调用了自己的委托方法,但在搜索栏更改时不再调用UISearchResultsUpdating方法。我是否需要手动进行大量的布线操作,或者是否有一些我缺少的东西让控制器的行为与本机提供的搜索栏一样?

4 个答案:

答案 0 :(得分:4)

覆盖自定义UISearchController类中的SearchBar getter,它必须返回自定义SearchBar并且必须已经初始化,然后只在UISearchController init之后设置其属性,这样就保留了所有UISearchController功能:

public class DSearchController: UISearchController {

    private var customSearchBar = DSearchBar()
    override public var searchBar: UISearchBar {
        get {
            return customSearchBar
        }
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }
    public init(searchResultsController: UIViewController?,
                searchResultsUpdater: UISearchResultsUpdating?,
                delegate: UISearchControllerDelegate?,
                dimsBackgroundDuringPresentation: Bool,
                hidesNavigationBarDuringPresentation: Bool,
                searchBarDelegate: UISearchBarDelegate?,
                searchBarFrame: CGRect?,
                searchBarStyle: UISearchBarStyle,
                searchBarPlaceHolder: String,
                searchBarFont: UIFont?,
                searchBarTextColor: UIColor?,
                searchBarBarTintColor: UIColor?, // Bar background
                searchBarTintColor: UIColor) { // Cursor and bottom line

        super.init(searchResultsController: searchResultsController)

        self.searchResultsUpdater = searchResultsUpdater
        self.delegate = delegate
        self.dimsBackgroundDuringPresentation = dimsBackgroundDuringPresentation
        self.hidesNavigationBarDuringPresentation = hidesNavigationBarDuringPresentation        

        customSearchBar.setUp(searchBarDelegate,
                              frame: searchBarFrame,
                              barStyle: searchBarStyle,
                              placeholder: searchBarPlaceHolder,
                              font: searchBarFont,
                              textColor: searchBarTextColor,
                              barTintColor: searchBarBarTintColor,
                              tintColor: searchBarTintColor)

    }
}

这是我自定义的searchBar:

public class DSearchBar: UISearchBar {

    var preferredFont: UIFont?
    var preferredTextColor: UIColor?

    init(){
        super.init(frame: CGRect.zero)
    }

    func setUp(delegate: UISearchBarDelegate?,
               frame: CGRect?,
               barStyle: UISearchBarStyle,
               placeholder: String,
               font: UIFont?,
               textColor: UIColor?,
               barTintColor: UIColor?,
               tintColor: UIColor?) {

        self.delegate = delegate
        self.frame = frame ?? self.frame
        self.searchBarStyle = searchBarStyle
        self.placeholder = placeholder
        self.preferredFont = font
        self.preferredTextColor = textColor
        self.barTintColor = barTintColor ?? self.barTintColor
        self.tintColor = tintColor ?? self.tintColor
        self.bottomLineColor = tintColor ?? UIColor.clearColor()

        sizeToFit()

        //        translucent = false
        //        showsBookmarkButton = false
        //        showsCancelButton = true
        //        setShowsCancelButton(false, animated: false)
        //        customSearchBar.backgroundImage = UIImage()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }


    let bottomLine = CAShapeLayer()
    var bottomLineColor = UIColor.clearColor()

    override public func layoutSubviews() {
        super.layoutSubviews()

        for view in subviews {
            if let searchField = view as? UITextField { setSearchFieldAppearance(searchField); break }
            else {
                for sView in view.subviews {
                    if let searchField = sView as? UITextField { setSearchFieldAppearance(searchField); break }
                }
            }
        }

        bottomLine.path = UIBezierPath(rect: CGRectMake(0.0, frame.size.height - 1, frame.size.width, 1.0)).CGPath
        bottomLine.fillColor = bottomLineColor.CGColor
        layer.addSublayer(bottomLine)
    }

    func setSearchFieldAppearance(searchField: UITextField) {
        searchField.frame = CGRectMake(5.0, 5.0, frame.size.width - 10.0, frame.size.height - 10.0)
        searchField.font = preferredFont ?? searchField.font
        searchField.textColor = preferredTextColor ?? searchField.textColor
        //searchField.backgroundColor = UIColor.clearColor()
        //backgroundImage = UIImage()
    }

}

Init示例:

searchController = DSearchController(searchResultsController: ls,
                                     searchResultsUpdater: self,
                                     delegate: self,
                                     dimsBackgroundDuringPresentation: true,
                                     hidesNavigationBarDuringPresentation: true,
                                     searchBarDelegate: ls,
                                     searchBarFrame: CGRectMake(0.0, 0.0, SCREEN_WIDTH, 44.0),
                                     searchBarStyle: .Minimal,
                                     searchBarPlaceHolder: NSLocalizedString("Search a location...", comment: ""),
                                     searchBarFont: nil,
                                     searchBarTextColor: nil,
                                     searchBarBarTintColor: UIColor.whiteColor(),
                                     searchBarTintColor: iconsColor)
searchController.searchBar.keyboardAppearance = .Dark
definesPresentationContext = true
tableView.tableHeaderView = searchController.searchBar

答案 1 :(得分:3)

这是一个已知的错误。不幸的是,没有涉及私有API的解决方法。

答案 2 :(得分:2)

当您继承UISearchController时,您可以在getter中自定义UISearchBar(setter不存在)。

示例 - 在子类实现中:

-(UISearchBar*)searchBar{
     UISearchBar *baseSearchBar = [super searchBar];
    if (baseSearchBar.showsScopeBar) {
        baseSearchBar.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 88);
    }else{
        baseSearchBar.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 44);
    }
    return baseSearchBar;
}

希望这有助于某人。

答案 3 :(得分:-1)

我认为它应该表现得那样。

这是来自UISearchController.h

// You are free to become the search bar's delegate to monitor for text changes and button presses.
@property (nonatomic, retain, readonly) UISearchBar *searchBar;

所有委托方法(updateSearchResultsForSearchController :)都会返回您的搜索控制器,以便您可以访问其搜索栏。

您可以通过自定义搜索栏委托方法执行此操作。