[英]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
包装带标题的UILabel
, searchBarWrapperView
包装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
. 我使用的解决方案是将
UISearchBar
和UISearchController
子类化。 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.