iOS 7 中 UISearchBar 中的 UITextField

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19008155/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:41:27  来源:igfitidea点击:

UITextField within UISearchBar in iOS 7

iosuitextfielduinavigationbarios7uisearchbar

提问by Jesper Martensson

I am trying to accomplish the same look of my UISearchBar with a TextField within it, as in my iOS 6 app. I have tried to code it in several ways and not yet been successful. The problem is, I am not able to change the TextField's frame in any way since iOS 7. The result is, my TextField takes all the space in the NavigationBar and overrides the UIBarButtonItem (menu button) to the right. See pictures below:

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

Screenshots

截图

iOS 6 code:This is how I coded it in iOS 6, where I could set the TextFields frame to whatever I liked!

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];

The result from the code above in iOS 7:![iOS 7 look]

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

iOS 7 code:The difference in iOS 7, is that you need to use subViews in order to add the UITextField to the UISearchBar/UINavigationBar. By doing this I have not yet been able to change its frame. It currently overlaps the menuButton to the right which can be seen in the picture below this code...

iOS 7 代码:iOS 7的不同之处在于,您需要使用 subViews 才能将 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];

enter image description hereSO...Is it possible to change a subView's frame (TextField) in any way ? :(

在此处输入图片说明SO...是否可以以任何方式更改子视图的框架(TextField)?:(

EDIT

编辑

The answer is kinda lame. In order to make the code work in ios7 with a button to the right of the TextField, the TextField must be set as the titleView of the navigationBar. Which was not the case in ios 6. But there will be other glitches and it is not recommended to use TextField within searchBars in iOS7. Use searchDispalyController instead. Se my answer below

答案有点蹩脚。为了使代码在 ios7 中使用 TextField 右侧的按钮工作,必须将 TextField 设置为导航栏的 titleView。在 ios 6 中不是这种情况。但是会有其他故障,不建议在 iOS7 中的 searchBars 中使用 TextField。请改用 searchDispalyController。下面是我的回答

 self.navigationItem.titleView = sbTextField;

采纳答案by Jesper Martensson

Thanx to spotdog13. I finally managed to make it work for iOS 7 properly in the following way:

感谢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;
}

回答by Adnan Aftab

in iOS 7 to access Text Field you have to reiterate on level more. Change your code like this

在 iOS 7 中访问文本字段,您必须在级别上重申更多。像这样改变你的代码

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

But best way to clear backgournd of UISearchBar and setting searchbar icon in text field is:

但是清除 UISearchBar 的 backgournd 并在文本字段中设置搜索栏图标的最佳方法是:

[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];

回答by DiscDev

You should not put a UITextFieldin the UINavigationBarin iOS 7, this widget is already provided by Apple.

你不应该把一个UITextFieldUINavigationBariOS中7,这个小部件已经由苹果公司提供。

In iOS 7, you can simply use a UISearchDisplayControllerwith a UISearchBar, and set:

在 iOS 7 中,你可以简单地使用 aUISearchDisplayController和 a UISearchBar,然后设置:

searchDisplayController.displaySearchBarInNavigationBar = YES

The search bar will appear in your UINavigationBar, and it will play nice with the other UIBarButtonItems without all the hacks and manual frame sizing in your original iOS 6 solution.

搜索栏会出现在你的UINavigationBar,它会起到很好的与其它UIBarButtonItem•不用所有的黑客,并在原始iOS 6的解决方案手册帧大小。

One thing to note - if you are going to add this to a project that still supports OSes older than iOS 7, you'll want to make sure that you put a check around the call or your app will crash when running on older OSes.

需要注意的一件事 - 如果您要将其添加到仍然支持早于 iOS 7 的操作系统的项目中,您需要确保对调用进行检查,否则您的应用程序在旧操作系统上运行时会崩溃。

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

See this section of the iOS 7 transition guide: https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/Bars.html

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

In iOS 7, UISearchDisplayController includes the displaysSearchBarInNavigationBar property, which you can use to put a search bar in a navigation bar, similar to the one in Calendar on iPhone:

在 iOS 7 中,UISearchDisplayController 包含 displaySearchBarInNavigationBar 属性,您可以使用它在导航栏中放置搜索栏,类似于 iPhone 日历中的搜索栏:

One other note - you should consider migrating to AutoLayout going forward so you don't have to do all that tedious frame manipulation. Apple recommends it, and probably for good reason (future devices with larger screens...?)

另一个注意事项 - 您应该考虑迁移到 AutoLayout,这样您就不必进行所有繁琐的框架操作。Apple 推荐它,而且可能是有充分理由的(未来的设备将具有更大的屏幕......?)

回答by Javier Querol

iOS6 & iOS7 compatible solution:

iOS6 & iOS7 兼容解决方案:

- (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];
        }
    }
}

回答by Syed Absar

Create a UIView *textFieldContainer with your target frame, add your textfield to that UIView and then add that textFieldContainer as a navigation item. i.e. your approach remains the same just the textfield comes inside a container and you play with that container.

使用您的目标框架创建一个 UIView *textFieldContainer,将您的文本字段添加到该 UIView,然后将该 textFieldContainer 添加为导航项。即您的方法保持不变,只是文本字段位于容器内,您可以使用该容器。

回答by Bhumit Mehta

Try this out i am not sure but this should work as in iOS 7 searchbar has subview and inside that subview there are two subviews one of which is UITextField

试试这个我不确定,但这应该可以工作,因为在 iOS 7 中搜索栏有子视图,在该子视图中有两个子视图,其中一个是 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];

回答by Tialtous

Swift solution

迅捷解决方案

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
            }
        }
    }