UISearchbarのテキストフィールドをカスタマイズしようとしています。下の写真は私の半分の仕事を示しています。
UISearchbarのサブクラスがあり、ViewControllerから呼び出しました。テキストフィールドからこれらの濃い灰色の線を削除しようとしています。以下は、ビューコントローラのサブビューに追加するUISearchbarの実装です。
searchbar = [[SearchBar alloc] initWithFrame:CGRectMake(35,78, 250, 17)];
searchbar.backgroundColor = [UIColor clearColor];
searchbar.layer.borderColor = [[UIColor clearColor] CGColor];
searchbar.layer.borderWidth = 0;
for(UIView *view in searchbar.subviews){
if([view isKindOfClass:[UITextField class]]){
UITextField *tf= (UITextField *)view;
tf.layer.borderColor = [[UIColor clearColor] CGColor];
tf.delegate = self;
break;
}
}
[self.view addSubview:searchbar];
searchbar.delegate = self;
UISearchBarサブクラス:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
-(void)layoutSubviews{
UITextField *searchField;
[[[self subviews] objectAtIndex:0] removeFromSuperview];
[self setTintColor:[UIColor clearColor]];
self.clipsToBounds = YES;
NSUInteger numViews = [self.subviews count];
for(int i = 0; i < numViews; i++) {
if([[self.subviews objectAtIndex:i] isKindOfClass:[UITextField class]]) {
searchField = [self.subviews objectAtIndex:i];
searchField.leftViewMode = UITextFieldViewModeNever;
searchField.backgroundColor = [UIColor clearColor];
}
}
if(!(searchField == nil)) {
searchField.backgroundColor = [UIColor clearColor];
searchField.textColor = [UIColor blackColor];
searchField.frame = CGRectMake(self.frame.Origin.x,self.frame.Origin.y,self.frame.size.width,self.frame.size.height-10);
[searchField setBorderStyle:UITextBorderStyleRoundedRect];
}
[super layoutSubviews];
}
私はこのようなことを達成しようとしています:テキストフィールドには境界があってはなりません。アイコンはフラット化されたUIImageViewです。
これは、UISearchBarサブビュー階層からテキストフィールドを取得し、必要に応じてそのプロパティを次のように設定する簡単な方法です。
UITextField *txfSearchField = [searchbar valueForKey:@"_searchField"];
[txfSearchField setBackgroundColor:[UIColor whiteColor]];
[txfSearchField setLeftView:UITextFieldViewModeNever];
[txfSearchField setBorderStyle:UITextBorderStyleRoundedRect];
txfSearchField.layer.borderWidth = 8.0f;
txfSearchField.layer.cornerRadius = 10.0f;
txfSearchField.layer.borderColor = [UIColor clearColor].CGColor;
文書化されていない機能を使用したくない場合、または画像を使用したくない場合は、以下を使用してください。
CGSize size = CGSizeMake(30, 30);
// create context with transparent background
UIGraphicsBeginImageContextWithOptions(size, NO, 1);
// Add a clip before drawing anything, in the shape of an rounded rect
[[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0,30,30)
cornerRadius:2.0] addClip];
[[UIColor whiteColor] setFill];
UIRectFill(CGRectMake(0, 0, size.width, size.height));
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.searchBar setSearchFieldBackgroundImage:image forState:UIControlStateNormal];
IOS-5以降、外観プロキシがあります。以下を参照してください。 http://developer.Apple.com/library/ios/#documentation/uikit/reference/UISearchBar_Class/Reference/Reference.html (そこに「外観のカスタマイズ」と呼ばれる2つのセクションです。両方を確認してください)。
これが実際の例です。アプリ内のすべてのUISearchBarを変更します。
[[UISearchBar appearance] setSearchFieldBackgroundImage:[UIImage imageNamed:@"text_box"] forState:UIControlStateNormal];
[[UISearchBar appearance] setImage:[UIImage imageNamed:@"search_icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
mysearchBar.tintColor = [UIColor whiteColor];
まだ答えを探している人のために、AppleはiOS13のUISearchBarにsearchTextField
プロパティを追加しました。searchTextField
は ISeachTextField これはUITextFieldから継承します。
let searchBar = UISearchBar()
var searchField : UITextField
if #available(iOS 13.0, *) {
searchField = searchBar.searchTextField
} else {
searchField = //One of the other methods listed
}
実装変更耐性と高性能
これを読んで、検索バーのテキストフィールドにSwiftで簡単にアクセスする方法を知りたい人には。次の部分を使用して、UISearchBarを拡張してtextFieldプロパティを追加できます基盤となる実装の変更に耐性があり、見つかった結果をキャッシュするため、パフォーマンスが向上します。
import UIKit
private var foundTextFieldAssociationKey = UInt8()
extension UISearchBar {
var textField: UITextField {
get {
let value = objc_getAssociatedObject(self, &foundTextFieldAssociationKey) as? UITextField
if value == nil {
let findInView = (UIView) -> UITextField? = { view in
for subview in view.subviews {
if let textField = (subview as? UITextField) ?? findInView(subview) {
return textField
}
}
return nil
}
guard let foundTextField = findInView(self) else {
fatalError("UISearchBar doesn't seem to have a UITextField anywhere in the view hierarchy")
}
textField = foundTextField
return foundTextField
}
return value!
}
set {
objc_setAssociatedObject(self, &foundTextFieldAssociationKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_ASSIGN)
}
}
}
プロパティの名前を変更する場合は、searchFieldに変更しないでください。それはあなたの検索バーを台無しにするでしょう。
私はiOS10でこれを行う必要があることを発見しました(上から借りてすぐに適応しました)
extension UISearchBar {
var textField: UITextField? {
func findInView(_ view: UIView) -> UITextField? {
for subview in view.subviews {
print("checking \(subview)")
if let textField = subview as? UITextField {
return textField
}
else if let v = findInView(subview) {
return v
}
}
return nil
}
return findInView(self)
}
}
短くて単純
extension UISearchBar {
var textField:UITextField {
guard let txtField = self.value(forKey: "_searchField") as? UITextField else {
assertionFailure()
return UITextField()
}
return txtField
}
}
iOS 13.x&Swift 5.x:
UITextField
のUISearchBar
にアクセスするには、次の手順を実行します。
extension UISearchBar {
/// Returns the`UITextField` that is placed inside the text field.
var textField: UITextField {
if #available(iOS 13, *) {
return searchTextField
} else {
return self.value(forKey: "_searchField") as! UITextField
}
}
}
IOS 13では、テキストフィールドに直接アクセスするためのsearchTextField
プロパティがあります。