简体   繁体   English

点击后,UISearchBar跳出位置

[英]UISearchBar jumping out of position once tapped

I am trying to display a MySearchBar ( UISearchBar with added UILabel to display the title) as the navigationItem 's view: 我正在尝试显示MySearchBar (添加了UILabel UISearchBar以显示标题)作为navigationItem的视图:

// Make search bar autoresize and occupy maximum width
self.navigationItem.titleView = [[UIView alloc] initWithFrame:self.navigationController.navigationBar.bounds];
self.navigationItem.titleView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[self.navigationItem.titleView addSubview:self.mySearchBar.view];
self.mySearchBar.view.frame = self.navigationItem.titleView.frame;

The search bar sits in place until it is tapped. 搜索栏将一直放置到位,直到被点击为止。 After tapping, it moves down and it no longer occupies full width (around 16px are missing). 点击后,它向下移动,不再占据全角(丢失了16px)。

Before editing (how it should look): 编辑之前(外观):

编辑之前

Editing began (BUG - after tapping the search bar grows in height to the default 56px and loses width): 编辑开始(BUG-点击搜索栏后,高度会增加到默认的56px并失去宽度):

开始编辑

Editing ended (remains misplaced) 编辑结束(仍然放错位置)

编辑结束

Here is the initialization code of MySearchBar . 这是MySearchBar的初始化代码。 It consists of two main views, titleView wraps the UILabel with title and searchBarWrapperView wraps the UISearchBar : 它由两个主要视图组成, titleView包装带标题的UILabelsearchBarWrapperView包装UISearchBar

-(id) init {
    // Initialize the two wrapping views
    UIView *titleView = [UIView new];
    self.searchBarWrapperView = [UIView new];

    // Resize UILabel to fit its content
    self.titleLabel = [UILabel new];
    self.titleLabel.numberOfLines = 0;
    [self.titleLabel sizeToFit];

    self.searchBar = self.searchController.searchBar;
    self.searchBarTextField = [self.searchBar valueForKey:@"searchField"];// This could be the text field that gets displaced???

    // Add two main subviews (wrappers)
    [self.view addSubview:titleView];
    [self.view addSubview:self.searchBarWrapperView];

    // Add title label and search bar to the subviews
    [titleView addSubview:self.titleLabel];
    [self.searchBarWrapperView addSubview:self.searchBar];

    // Disable auto constraints
    [titleView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.searchBarWrapperView setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.titleLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

    // Set constraints for title view
    [titleView.topAnchor constraintEqualToAnchor:self.view.topAnchor].active = YES;
    [titleView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
    [titleView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor].active = YES;
    [titleView.bottomAnchor constraintEqualToAnchor:self.titleLabel.bottomAnchor].active = YES;

    // Set constraints for title label
    [self.titleLabel.topAnchor constraintEqualToAnchor:titleView.topAnchor].active = YES;
    [self.titleLabel.leftAnchor constraintEqualToAnchor:titleView.leftAnchor].active = YES;
    [self.titleLabel.rightAnchor constraintEqualToAnchor:titleView.rightAnchor].active = YES;

    // Set constraints for search bar wrapper
    [self.searchBarWrapperView.heightAnchor constraintGreaterThanOrEqualToConstant:30].active = YES;// The search bar together with the title label should occupy the whole 44px height of the navigation bar
    [self.searchBarWrapperView.topAnchor constraintEqualToAnchor:titleView.bottomAnchor].active = YES;
    [self.searchBarWrapperView.bottomAnchor constraintEqualToAnchor:self.view.bottomAnchor].active = YES;
    [self.searchBarWrapperView.leftAnchor constraintEqualToAnchor:self.view.leftAnchor].active = YES;
    [self.searchBarWrapperView.rightAnchor constraintEqualToAnchor:self.view.rightAnchor constant:16].active = YES;// Add space that is lost by setSearchFieldBackgroundPositionAdjustment

    // Configure autoresizing mask for UISearchBar
    [self.searchBar setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
    [self.searchBar setFrame:self.searchBarWrapperView.frame];

    //Remove left and right blank spaces around UISearchBar
    [self.searchBar setSearchFieldBackgroundPositionAdjustment:UIOffsetMake(-8,0)];

    // Colors for debugging        
    self.view.backgroundColor = [UIColor blueColor];
    titleView.backgroundColor = [UIColor redColor];
    searchBarWrapperView.backgroundColor = [UIColor greenColor];
    self.searchBar.backgroundColor = [UIColor yellowColor];
    self.searchBarTextField.backgroundColor = [UIColor brownColor];

    return self;
}

The solution I used was to subclass the UISearchBar and the UISearchController . 我使用的解决方案是将UISearchBarUISearchController子类化。 That way I can set the frame and control the search bar events. 这样,我可以设置框架并控制搜索栏事件。

SearchBar.swift : SearchBar.swift

import Foundation

class SearchBar : UISearchBar {

    var preferredFont:UIFont?
    var preferredTextColor:UIColor?

    init(frame: CGRect, font: UIFont, textColor: UIColor) {
        super.init(frame: frame)

        self.frame = frame
        self.preferredFont = font
        self.preferredTextColor = textColor
    }

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

SearchController.swift : SearchController.swift

import Foundation

protocol SearchControllerDelegate {
    func didStartSearching()

    func didTapOnSearchButton()

    func didTapOnCancelButton()

    func didChangeSearchText(searchText: String)
}

class SearchController : UISearchController, UISearchBarDelegate, SearchControllerDelegate {

    var customSearchBar: SearchBar!
    var customDelegate: SearchControllerDelegate!

    init(searchResultsController: UIViewController!, searchBarFrame: CGRect, searchBarFont: UIFont, searchBarTextColor: UIColor, searchBarTintColor: UIColor) {
        super.init(searchResultsController: searchResultsController)
        configureSearchBar(frame: searchBarFrame, font: searchBarFont, textColor: searchBarTextColor, bgColor: searchBarTintColor)
    }

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

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

    func configureSearchBar(frame: CGRect, font: UIFont, textColor: UIColor, bgColor: UIColor) {
        self.customSearchBar = SearchBar(frame: frame, font: font , textColor: textColor)

        self.customSearchBar.placeholder = "Search"
        self.customSearchBar.barTintColor = bgColor
        self.customSearchBar.tintColor = textColor
        self.customSearchBar.showsBookmarkButton = false
        self.customSearchBar.showsCancelButton = false

        self.customSearchBar.delegate = self
        self.customDelegate = self;

        let searchBarTextField:UITextField = self.customSearchBar.value(forKey: "searchField") as! UITextField

        searchBarTextField.font = font
        searchBarTextField.layer.borderWidth = 1
        searchBarTextField.layer.cornerRadius = 3
        searchBarTextField.layer.borderColor = UIColor.lightGray.cgColor
    }

    // UISearchBarDelegate

    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
        customDelegate.didStartSearching()
    }

    func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        customSearchBar.resignFirstResponder()
        customDelegate.didTapOnSearchButton()
    }

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        customSearchBar.resignFirstResponder()
        customDelegate.didTapOnCancelButton()
    }

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        customDelegate.didChangeSearchText(searchText: searchText)
    }

    // SearchControllerDelegate

    func didStartSearching() {

    }

    func didTapOnSearchButton() {
        var searchText:String = ""

        if (self.customSearchBar.text != nil) {
            searchText = self.customSearchBar.text!
        }

        self.search(searchQuery: searchText)
    }

    func didTapOnCancelButton() {

    }

    func didChangeSearchText(searchText: String) {
        self.search(searchQuery: searchText)
    }

    // Search
    func search(searchQuery: String) {
        // Start searching
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM