このようなカスタム検索バーを作成する必要があります。私が抱えている問題は、プレースホルダーテキストを左揃えにすることと、右側に検索アイコンを配置することです。 UIImageView
で使用しようとした検索アイコンのpngがあり、そのUIImageView
をrightView
のUISearchBar
として設定しますUITextField
。この解決策は機能せず、アイデアが不足しました。誰かが解決策を持っていますか?
これらの種類のカスタマイズを行う必要がある場合は、UISearchBar
を使用しないでください。 UITextField
とUIImageView
を使用して独自に作成し、デリゲートの呼び出しに応答する必要があります。
スウィフト3
Swift 3では、プレースホルダープロパティをオーバーライドできません。これはDrix Answerの修正版です。
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");
@DevCからプレースホルダーの最後にスペースを追加するように求められたMohittomarの回答に基づいています。ここではSwiftのコードを示します。
UISearchBarでプレースホルダーをサブクラス化し、値を設定した後、最後の文字がスペースかどうかを確認します。次に、1つのスペースのサイズと、左揃えに追加する必要があるスペースの数を取得します。
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
}
}
}
}
}
実用的なSwift Drix回答の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
}
*/
}
Drix Answerの実用的なソリューション
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
}
}
}
}
}
}
}
このメソッドのAppearanceWhenContainedInInstancesOfClassesはiOS 8では使用できません。iOS8には回避策があります here
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;
}
カスタマイズする必要はありません...
searchBar.placeholder=@"Search ";
searchbarのplace-hoderは中央にテキストが配置されているので、大きなテキストを入力します。テキストが小さい場合は、プレースホルダーテキストの後にスペースを入れてください。
ストーリーボードから実行できます。検索バーの属性インスペクターにセマンティックな名前のコンボボックスがあり、右から左に強制するように設定すると、検索バーが右揃えになり、左から整列する場合と同様のことが行われます。
コントロールが希望どおりに応答するようにしたい場合は、おそらく独自のカスタムコントロールを作成する必要があります。このコントロールは3つの部分に分けることができます。
UIImageView
UITextField
UIButton
これを行う最も簡単な方法は、プライベートクラスの3つの部分で新しいクラスMySearchBar
を作成することです。
@interface MySearchBar ()
@property (nonatomic, strong) UISearchBar* searchBar;
@property (nonatomic, strong) UITextField* textField;
@property (nonatomic, strong) UIButton* button;
@end
MySearchBar
では、コンポーネントを作成し、それをカスタマイズして、より良いルックアンドフィールを追加できます。検索結果を取得するには、コントロールにデリゲートid<UISearchBarDelegate>
(your UIViewController
)これは、基本的に標準のUISearchBarを持つことをシミュレートします。
あとは、コントローラーでMySearchBar
を作成し、デリゲートをビューコントローラーに設定するだけです。 UISearchBarDelegate
からのメッセージは、MySearchBar
に送信してフィルタリングするか、UIViewController
に送信する前に前処理を行うか、直接UIViewController
に送信できます。