UITextField在iOS 7的UISearchBar中

我正在尝试使用其中的TextField完成与UISearchBar相同的外观,就像在我的iOS 6应用程序中一样。 我试图用几种方法编码,但还没有成功。 问题是,自iOS 7以来,我无法以任何方式更改TextField的框架。结果是,我的TextField获取了NavigationBar中的所有空间,并覆盖了右侧的UIBarButtonItem(菜单button)。 见下图:

截图http://oi44.tinypic.com/2ufewx0.jpg

iOS 6代码: 这是我在iOS 6中编写的代码,我可以将TextFields框架设置为我喜欢的任何内容。

UITextField *sbTextField = (UITextField *)[searchBar.subviews lastObject]; [sbTextField removeFromSuperview]; CGRect rect = searchBar.frame; rect.size.height = 32; rect.size.width = 210; sbTextField.frame = rect; [sbTextField setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin]; UIBarButtonItem *searchBarNavigationItem = [[UIBarButtonItem alloc] initWithCustomView:sbTextField]; [[self navigationItem] setLeftBarButtonItem:searchBarNavigationItem]; 

以上代码在iOS 7中的结果: ![iOS 7 look]

iOS 7代码: 与iOS 7不同的是,您需要使用子视图才能将UITextField添加到UISearchBar / UINavigationBar。 通过这样做,我还没有能够改变它的框架。 它目前重叠menuButton的权利,可以看到这个代码下面的图片…

 UITextField* sbTextField; CGRect rect = subView.frame; rect.size.height = 32; rect.size.width = 115; for (UIView *subView in self.searchBar.subviews){ for (UIView *ndLeveSubView in subView.subviews){ if ([ndLeveSubView isKindOfClass:[UITextField class]]) { sbTextField = (UITextField *)ndLeveSubView; sbTextField.backgroundColor =[UIColor whiteColor]; UIBarButtonItem *searchBarNavigationItem = [[UIBarButtonItem alloc] initWithCustomView:sbTextField]; sbTextField.frame = rect; self.navigationItem.leftBarButtonItem = searchBarNavigationItem; self.navigationItem.rightBarButtonItem = menuButton; [sbTextField removeFromSuperview]; break; } } } [self.searchBar reloadInputViews]; 

在这里输入图像说明 所以…有没有可能以任何方式更改子视图的框架(TextField)? 🙁

编辑

答案有点蹩脚。 为了使代码在ios7中使用TextField右侧的button,必须将TextField设置为navigationBar的titleView。 这是不是在iOS 6的情况。但是会有其他毛刺,不build议在iOS7的search栏内使用TextField。 改用searchDispalyController。 在下面我的答案

  self.navigationItem.titleView = sbTextField; 

你不应该把UITextField放在iOS 7的UINavigationBar中,这个小部件已经由Apple提供了。

在iOS 7中,您可以简单地使用带有UISearchDisplayControllerUISearchBar ,并设置:

 searchDisplayController.displaySearchBarInNavigationBar = YES 

search栏会出现在你的UINavigationBar ,并且与其他的UIBarButtonItem ,在你原来的iOS 6解决scheme中没有所有的黑客和手动框架大小。

需要注意的一点是,如果你要将这个添加到一个仍然支持iOS 7之前的操作系统的项目中,那么你需要确保你能够检查这个调用,否则你的应用会在老的操作系统上运行时崩溃。

 if([searchDisplayController respondsToSelector:@selector(displaysSearchBarInNavigationBar)]) { searchDisplayController.displaysSearchBarInNavigationBar = YES; } 

请参阅iOS 7转换指南的这一部分: https : //developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/Bars.html

在iOS 7中,UISearchDisplayController包含了displaysSearchBarInNavigationBar属性,您可以使用它来在导航栏中放置search栏,类似于iPhone上的Calendar:

另一个注意事项 – 你应该考虑向前移动到AutoLayout,所以你不必做所有那些枯燥乏味的框架操作。 苹果推荐它,可能是有很好的理由(未来的屏幕更大的设备…?)

在iOS 7中访问文本字段,你不得不在水平上重申更多。 像这样改变你的代码

 for (UIView *subView in self.searchBar.subviews){ for (UIView *ndLeveSubView in subView.subviews){ if ([ndLeveSubView isKindOfClass:[UITextField class]]) { searchBarTextField = (UITextField *)ndLeveSubView; break; } } } 

但清除UISearchBar的背景并在文本字段中设置search栏图标的最佳方法是:

 [searchBar setBackgroundImage:[[UIImage alloc] init] ];//if you want to remove background of uisearchbar UIImage *image = [UIImage imageNamed: @"search_icon.png"]; [searchBar setImage:image forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 

创build一个UIView * textFieldContainer与您的目标框架,将您的文本字段添加到该UIView,然后添加该textFieldContainer作为导航项目。 即你的方法保持不变,只是文本框出现在容器中,并且使用该容器进行播放。

试试这个我不知道,但这应该工作,因为在iOS 7的search栏有子视图,并在该子视图中有两个子视图其中之一是UITextField

 UIView *searchbarview = [searchBar.subviews objectAtIndex:0]; UITextField *sbTextField = (UITextField *)[searchbarview.subviews lastObject]; [sbTextField removeFromSuperview]; CGRect rect = searchBar.frame; rect.size.height = 32; rect.size.width = 210; sbTextField.frame = rect; [sbTextField setAutoresizingMask:UIViewAutoresizingFlexibleBottomMargin]; UIBarButtonItem *searchBarNavigationItem = [[UIBarButtonItem alloc] initWithCustomView:sbTextField]; [[self navigationItem] setLeftBarButtonItem:searchBarNavigationItem]; 

iOS6和iOS7兼容的解决scheme:

 - (void)setTextFieldAsDelegate:(UIView *)inputView { for (UIView *view in inputView.subviews) { if ([view isKindOfClass:[UITextField class]]) { searchBarTextField = (UITextField *)view; searchBarTextField.delegate = self; break; } else { [self setTextFieldAsDelegate:view]; } } } 

迅速的解决scheme

 for subView in searchBar.subviews{ for deeperView in subView.subviews{ if let searchField:UITextField = deeperView as? UITextField{ searchField.layer.borderWidth = 1.0 searchField.layer.borderColor = UIColor(red: 134/255, green: 14/255, blue: 75/255, alpha: 1).CGColor searchField.layer.cornerRadius = 5.0 } } } 

感谢spotdog13。 我终于设法使其适用于iOS 7在以下方面:

 #define TABLE_BOTTOM_MARGIN 5 #define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame) #define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending) #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending) @interface HomeViewController () @end @implementation HomeViewController @synthesize searchBar; @synthesize searchResults; - (void)viewDidLoad { if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) { [searchBar sizeToFit]; // standard size searchBar.delegate = self; // Add search bar to navigation bar self.navigationItem.titleView = searchBar; } } - (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar { // Manually activate search mode // Use animated=NO so we'll be able to immediately un-hide it again [self.searchDisplayController setActive:YES animated:NO]; // Hand over control to UISearchDisplayController during the search // searchBar.delegate = (id <UISearchBarDelegate>)self.searchDisplayController; return YES; } #pragma mark <UISearchDisplayDelegate> - (void) searchDisplayControllerDidBeginSearch:(UISearchDisplayController // Un-hide the navigation bar that UISearchDisplayController hid [self.navigationController setNavigationBarHidden:NO animated:NO]; } - (void) searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller { searchBar = (UISearchBar *)self.navigationItem.titleView; // Manually resign search mode [searchBar resignFirstResponder]; // Take back control of the search bar searchBar.delegate = self; }