我需要创建一个像这样的自定义搜索栏。我的问题在于左对齐占位符文本,以及将搜索图标放在右侧。我有一个搜索图标的png文件,我已经尝试将其用作UIImageView
,并将该UIImageView
设置为UISearchBar
的UITextField
的rightView
。但是这个解决方案没有起作用,我想不出更好的方法了。请问有人有解决方案吗?
我需要创建一个像这样的自定义搜索栏。我的问题在于左对齐占位符文本,以及将搜索图标放在右侧。我有一个搜索图标的png文件,我已经尝试将其用作UIImageView
,并将该UIImageView
设置为UISearchBar
的UITextField
的rightView
。但是这个解决方案没有起作用,我想不出更好的方法了。请问有人有解决方案吗?
如果需要进行这些自定义操作,请不要使用 UISearchBar
。您需要使用UITextField
和UIImageView
创建自己的搜索栏,并响应委托调用。
根据Mohittomar的回答,@DevC要求在占位符末尾添加空格,在这里提供Swift代码:
我在UISearchBar中子类化了占位符,在设置值后,检查最后一个字符是否为空格。然后获取一个空格的大小以及需要添加到左侧对齐的空格数量。
class SearchBar: UISearchBar, UISearchBarDelegate {
override var placeholder:String? {
didSet {
if let text = placeholder {
if text.last != " " {
// get the font attribute
let attr = UITextField.s_appearanceWhenContainedIn(SearchBar).defaultTextAttributes
// define a max size
let maxSize = CGSizeMake(UIScreen.mainScreen().bounds.size.width - 60, 40)
// get the size of the text
var widthText = text.boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
// get the size of one space
var widthSpace = " ".boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
let spaces = floor((maxSize.width - widthText) / widthSpace)
// add the spaces
let newText = text + (" " * spaces)
// apply the new text if nescessary
if newText != text {
placeholder = newText
}
}
}
}
}
import Foundation
import UIKit
class LeftAlignedSearchBar: UISearchBar, UISearchBarDelegate {
override var placeholder:String? {
didSet {
if #available(iOS 9.0, *) {
if let text = placeholder {
if text.characters.last! != " " {
// get the font attribute
let attr = UITextField.appearanceWhenContainedInInstancesOfClasses([LeftAlignedSearchBar.self]).defaultTextAttributes
// define a max size
let maxSize = CGSizeMake(UIScreen.mainScreen().bounds.size.width - 87, 40)
// let maxSize = CGSizeMake(self.bounds.size.width - 92, 40)
// get the size of the text
let widthText = text.boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
// get the size of one space
let widthSpace = " ".boundingRectWithSize( maxSize, options: .UsesLineFragmentOrigin, attributes:attr, context:nil).size.width
let spaces = floor((maxSize.width - widthText) / widthSpace)
// add the spaces
let newText = text + ((Array(count: Int(spaces), repeatedValue: " ").joinWithSeparator("")))
// apply the new text if nescessary
if newText != text {
placeholder = newText
}
}
}
}
}
}
}
在iOS 8中,方法appearanceWhenContainedInInstancesOfClasses不可用,但是有一个解决方法可以在iOS 8中使用,在这里。
以下是Drix答案的可行的Swift 3解决方案:
import Foundation
import UIKit
class LeftAlignedSearchBar: UISearchBar, UISearchBarDelegate {
override var placeholder:String? {
didSet {
if #available(iOS 9.0, *) {
if let text = placeholder {
if text.characters.last! != " " {
// get the font attribute
let attr = UITextField.appearance(whenContainedInInstancesOf: [LeftAlignedSearchBar.self]).defaultTextAttributes
// define a max size
let maxSize = CGSize(width: UIScreen.main.bounds.size.width - 87, height: 40)
// let maxSize = CGSize(width:self.bounds.size.width - 92,height: 40)
// get the size of the text
let widthText = text.boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:attr, context:nil).size.width
// get the size of one space
let widthSpace = " ".boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:attr, context:nil).size.width
let spaces = floor((maxSize.width - widthText) / widthSpace)
// add the spaces
let newText = text + ((Array(repeating: " ", count: Int(spaces)).joined(separator: "")))
// apply the new text if nescessary
if newText != text {
placeholder = newText
}
}
}
}
}
}
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
}
SWIFT 3
Swift 3不允许覆盖占位符属性。以下是Drix答案的修改版本。
func setPlaceHolder(placeholder: String)-> String
{
var text = placeholder
if text.characters.last! != " " {
// define a max size
let maxSize = CGSize(width: UIScreen.main.bounds.size.width - 97, height: 40)
// let maxSize = CGSizeMake(self.bounds.size.width - 92, 40)
// get the size of the text
let widthText = text.boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:nil, context:nil).size.width
// get the size of one space
let widthSpace = " ".boundingRect( with: maxSize, options: .usesLineFragmentOrigin, attributes:nil, context:nil).size.width
let spaces = floor((maxSize.width - widthText) / widthSpace)
// add the spaces
let newText = text + ((Array(repeating: " ", count: Int(spaces)).joined(separator: "")))
// apply the new text if nescessary
if newText != text {
return newText
}
}
return placeholder;
}
然后调用该函数:
searchBar.placeholder = self.setPlaceHolder(placeholder: "your placeholder text");
如果您想让控件按照您的意愿进行响应,那么您可能需要创建自己的自定义控件。
该控件可以分为三个部分:
UIImageView
UITextField
UIButton
,如果您希望用户与之交互,则用于搜索图标最简单的方法可能是创建一个新类MySearchBar
,并在私有接口中包含这三个部分:
@interface MySearchBar ()
@property (nonatomic, strong) UISearchBar* searchBar;
@property (nonatomic, strong) UITextField* textField;
@property (nonatomic, strong) UIButton* button;
@end
MySearchBar
中,你可以创建自己的组件,自定义它,使其外观更好。为了获取搜索结果,你的控件可以有一个委托id<UISearchBarDelegate>
(你的UIViewController
),它将基本上模拟具有标准UISearchBar的情况。MySearchBar
并将委托设置为你的视图控制器。来自UISearchBarDelegate
的消息可以直接发送到你的UIViewController
,也可以先经过MySearchBar
进行过滤或预处理。可以从故事板完成,搜索栏的属性检查器上有名为“语义”的组合框,如果将其设置为强制从右到左,则可以实现右对齐的搜索栏,并且它还具有类似的功能,可以从左侧对齐。
不需要任何定制,只需这样做...
searchBar.placeholder=@"Search ";
Xamarin 版本
SearchBar.MovePlaceHolderLeft();
public static void MovePlaceHolderLeft(this UISearchBar searchbar)
{
NSAttributedString text = new NSAttributedString(searchbar.Placeholder ?? "");
// define a max size
var maxSize = new CGSize(width: UIScreen.MainScreen.Bounds.Size.Width - 97, height: 40);
// get the size of the text
var widthText = text.GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size.Width;
// get the size of one space
var widthSpace = new NSAttributedString(" ").GetBoundingRect(maxSize, NSStringDrawingOptions.UsesLineFragmentOrigin, null).Size.Width;
var spaces = Math.Floor((maxSize.Width - widthText) / widthSpace);
// add the spaces
string newText = searchbar.Placeholder;
for (double i = 0; i < spaces; i++)
{
newText += " ";
}
searchbar.Placeholder = newText;
}
虽然现在已经太晚了,但如果有人仍然在寻找解决方案,可以按照以下步骤操作。
UITextField *searchTextField = [searchBarController.searchBar valueForKey:@"_searchField"];
您可以使用上面的代码来获取搜索字段。现在只需使用您想要使用的属性,比如。
searchTextField.layer.cornerRadius = 10.0f;
searchTextField.textAlignment = NSTextAlignmentLeft;
附注:文本对齐属性用于文本和占位符。
谢谢。
UIButton
,放置在搜索栏的顶部,并作为“输入”按钮工作。我遇到过一些这样做的应用程序,我总是很喜欢有不必点击搜索字段、打开键盘并从那里点击“搜索”重新运行搜索的选项。 - Nerrolken