鉴于UISearchBar样式修改不好操作,以及它的一些系统默认处理不符合实际产品需求,和iOS 11之后UISearchBar的placeholder居中问题跟之前版本不一样,特此封装了一个UISearchBar的子类,以后用的时候直接拿来用就方便多了。附上地址项目地址
先总结:本demo封装、修改的内容
1、UISearchBar 样式
2、iOS11之前placeholder文字默认是居左的,iOS 11默认居中的,为了样式统一,且两个样式都支持,做了一下封装。只要继承该控件,控件内部已经实现placeholder居中和居左方案。
3、UISearchBar 的clearBtn的显示方式
4、取消按钮的title 文字内容、颜色
5、UISearchBar当失去焦点时,系统会把取消按钮的enable设为no,这样点击取消按钮的时候默认输入框会获得焦点,而不是取消搜索,实际应用中很少这样用,所以封装的控件中对改功能做了支持,既可以支持原系统默认事件,亦可以直接响应取消事件。
具体支持哪些修改,详见头文件
@interfaceFLJSearchBar :UISearchBar
/**
这里根据实际应用来做的封装,一般情况都是 UITextFieldViewModeWhileEditing和UITextFieldViewModeNever
yes-UITextFieldViewModeNever no-UITextFieldViewModeWhileEditing
默认 no
*/
@property(nonatomic,assign)BOOL clearBtnHidden;
//placeHolder 是否居中 iOS11之前默认是居中的 iOS11之后居左
@property(nonatomic,assign)BOOL placeHolderCenter;
//placeHolder文字
@property(nonatomic,copy)NSString* placeHolderString;
//placeHolder字号 默认16 和输入框文字字号一样
@property(nonatomic,strong)UIFont* placeHolderStringFont;
//placeHolder文字颜色
@property(nonatomic,strong)UIColor* placeHolderStringColor;
//取消按钮文字 系统默认cancel,这里默认 取消
@property(nonatomic,copy)NSString* cancelBtnTitle;
//取消按钮文字颜色
@property(nonatomic,strong)UIColor* cancelBtnTitleColor;
//圆角
@property(nonatomic,assign)CGFloat cornerRadius;
//边框颜色
@property(nonatomic,strong)UIColor* borderColor;
//边框宽度
@property(nonatomic,assign)CGFloat borderWidth;
//记录默认情况下的搜索图片偏移
@property(nonatomic,assign)UIOffsetoriginPositionSearchOffSet;
//系统searchbar,如果search没有获得焦点,点击取消默认会获得焦点(而不会响应取消事件)
//cancelInputDisabled yes 直接响应取消事件
@property(nonatomic,assign)BOOL cancelInputDisabled;
.m实现
#import "FLJSearchBar.h"
#import "UIImage+Extension.h"
#define kDefaultBorderColor [UIColor colorWithRed:(225)/255.0green:(226)/255.0blue:(227)/255.0alpha:1.0]
#define kDefaultPlaceHolderTextFont [UIFont systemFontOfSize:16]
#define kDefaultPlaceHolerTextColor [UIColor colorWithRed:(187)/255.0green:(187)/255.0blue:(187)/255.0alpha:1.0]
#define kDefaultCancelBtnTitleFont [UIFont systemFontOfSize:16]
#define kDefaultCancelBtnTitleColor [UIColor colorWithRed:(102)/255.0green:(102)/255.0blue:(102)/255.0alpha:1.0]
@interface FLJSearchBar ()
@property(nonatomic,assign)BOOL hideClearBtn;
@end
@implementation FLJSearchBar
-(instancetype)initWithFrame:(CGRect)frame
{
if(self== [superinitWithFrame:frame]) {
[self setBackgroundColor:[UIColor whiteColor]];
//cancel按钮显示
self.showsCancelButton = YES;
//光标颜色tintColor
// self.tintColor = [UIColor clearColor];
self.backgroundImage = [UIImage imageWithColor:[UIColor whiteColor] size:CGSizeMake(100, self.bounds.size.height)];
[self setImage:[UIImage imageNamed:@"icon_search"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
[self setImage:[UIImage imageNamed:@"icon_search_clear"] forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];
//ios11 之前这个高度决定textfield高度 默认28
[self setSearchFieldBackgroundImage:[UIImage imageWithColor:[UIColor clearColor] size:CGSizeMake(100, self.bounds.size.height)] forState:UIControlStateNormal];
self.originPositionSearchOffSet = UIOffsetMake(10, 0);
//搜索图标偏移
[self setPositionAdjustment:self.originPositionSearchOffSet forSearchBarIcon:UISearchBarIconSearch];
//清除按钮偏移向左偏移10
[self setPositionAdjustment:UIOffsetMake(-10, 0) forSearchBarIcon:UISearchBarIconClear];
//整个输入框(textfield)的偏移量
// [self setSearchFieldBackgroundPositionAdjustment:UIOffsetMake(10, 0)];
//文字距离搜索图标的偏移,默认是紧挨着的
[self setSearchTextPositionAdjustment:UIOffsetMake(10, 0)];
self.placeHolderString = @"请输入搜索内容";
self.cornerRadius=self.bounds.size.height/2.f;
self.borderWidth=1.f;
self.borderColor = kDefaultBorderColor;
self.placeHolderCenter = NO;
[self setCancelBtnTitle:@"取消"];
}
return self;
}
#pragma mark setter & getter
/**
设置placeHolder
@param placeHolderString placeHolder
*/
-(void)setPlaceHolderString:(NSString*)placeHolderString
{
_placeHolderString= [placeHolderStringcopy];
UITextField*textField = [selftextField];
if(textField) {
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:_placeHolderString attributes:@{NSForegroundColorAttributeName:_placeHolderStringColor?_placeHolderStringColor:kDefaultPlaceHolerTextColor,NSFontAttributeName:_placeHolderStringFont?_placeHolderStringFont:kDefaultPlaceHolderTextFont}];
}
}
/**
设置placeHolder字号
@param placeHolderStringFont 字号
*/
-(void)setPlaceHolderStringFont:(UIFont*)placeHolderStringFont
{
_placeHolderStringFont= placeHolderStringFont;
UITextField*textField = [selftextField];
if(textField) {
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:_placeHolderString attributes:@{NSForegroundColorAttributeName:_placeHolderStringColor?_placeHolderStringColor:kDefaultPlaceHolerTextColor,NSFontAttributeName:_placeHolderStringFont}];
textField.font = _placeHolderStringFont;
}
}
/**
设置placehHolder字体颜色
@param placeHolderStringColor placehHolder字体颜色
*/
-(void)setPlaceHolderStringColor:(UIColor*)placeHolderStringColor
{
_placeHolderStringColor= placeHolderStringColor;
UITextField*textField = [selftextField];
if(textField) {
textField.attributedPlaceholder = [[NSAttributedString alloc] initWithString:_placeHolderString attributes:@{NSForegroundColorAttributeName:_placeHolderStringColor,NSFontAttributeName:_placeHolderStringFont?_placeHolderStringFont:kDefaultPlaceHolderTextFont}];
}
}
/**
设置取消按钮文字
*/
-(void)setCancelBtnTitle:(NSString*)cancelBtnTitle
{
_cancelBtnTitle= [cancelBtnTitlecopy];
UIButton*cancel = [selfcancelBtn];
if(cancel) {
[cancelsetTitle:cancelBtnTitle forState:UIControlStateNormal];
if (!self.cancelBtnTitleColor) {
[cancelsetTitleColor:kDefaultCancelBtnTitleColor forState:UIControlStateNormal];
}
cancel.titleLabel.font = kDefaultCancelBtnTitleFont;
}
}
/**
设置取消按钮文字颜色
*/
-(void)setCancelBtnTitleColor:(UIColor*)cancelBtnTitleColor
{
_cancelBtnTitleColor= cancelBtnTitleColor;
UIButton*cancel = [selfcancelBtn];
if(cancel) {
[cancelsetTitleColor:_cancelBtnTitleColor forState:UIControlStateNormal];
}
}
/**
隐藏清除按钮
@param clearBtnHidden yes隐藏 no输入的时候显示
*/
-(void)setClearBtnHidden:(BOOL)clearBtnHidden
{
_clearBtnHidden= clearBtnHidden;
self.hideClearBtn = _clearBtnHidden;
}
-(void)setHideClearBtn:(BOOL)hideClearBtn
{
_hideClearBtn= hideClearBtn;
UITextField*textField = [selftextField];
if(textField) {
if (_hideClearBtn) {
textField.clearButtonMode=UITextFieldViewModeNever;
}else
textField.clearButtonMode = UITextFieldViewModeWhileEditing;
}
}
/**
设置搜索框圆角
*/
-(void)setCornerRadius:(CGFloat)cornerRadius
{
_cornerRadius= cornerRadius;
UITextField*textField = [selftextField];
if(textField) {
textField.layer.cornerRadius=_cornerRadius;
textField.layer.masksToBounds=YES;
textField.clipsToBounds=YES;
}
}
/**
设置搜索框边框颜色
*/
-(void)setBorderColor:(UIColor*)borderColor
{
_borderColor= borderColor;
UITextField*textField = [selftextField];
if(textField) {
textField.layer.borderColor= borderColor.CGColor;
}
}
/**
设置搜索框边框 宽度
*/
-(void)setBorderWidth:(CGFloat)borderWidth
{
_borderWidth= borderWidth;
UITextField*textField = [selftextField];
if(textField) {
textField.layer.borderWidth= borderWidth;
textField.layer.masksToBounds=YES;
}
}
/**
设置placeholder是否居中显示
*/
- (void)setPlaceHolderCenter:(BOOL)placeHolderCenter
{
_placeHolderCenter= placeHolderCenter;
if(@available(iOS11.0, *)) {
UITextField* textField = [selftextField];
textField.delegate=self;
if (_placeHolderCenter) {
[self setPositionAdjustment:UIOffsetMake((textField.frame.size.width-[self placeHolderTextWidth])/2, 0) forSearchBarIcon:UISearchBarIconSearch];
}else
[self setPositionAdjustment:self.originPositionSearchOffSet forSearchBarIcon:UISearchBarIconSearch];
}else
{
SELcenterSelector =NSSelectorFromString([NSStringstringWithFormat:@"%@%@",@"setCenter",@"Placeholder:"]);
if([selfrespondsToSelector:centerSelector])
{
//方法1 [self setValue:@(_placeHolderCenter) forKeyPath:@"centerPlaceholder"];
//方法2
NSMethodSignature*signature = [[UISearchBarclass]instanceMethodSignatureForSelector:centerSelector];
NSInvocation*invocation = [NSInvocationinvocationWithMethodSignature:signature];
[invocationsetTarget:self];
[invocationsetSelector:centerSelector];
[invocationsetArgument:&_placeHolderCenteratIndex:2];
[invocationinvoke];
}
}
}
/**
设置当输入框没有获得焦点时,点击取消按钮是否直接响应取消事件,而不是响应输入事件
*/
-(void)setCancelInputDisabled:(BOOL)cancelInputDisabled
{
_cancelInputDisabled= cancelInputDisabled;
UIButton*cancelBtn = [selfcancelBtn];
cancelBtn.enabled=YES;
}
#pragma mark UITextFieldDelegate
#warning 实现这两个代理方法后 searchbar的textFieldShouldBeginEditing 和textFieldShouldEndEditing将不执行 需要代理调起方法
-(BOOL)textFieldShouldBeginEditing:(UITextField*)textField
{
if([self.delegaterespondsToSelector:@selector(searchBarShouldBeginEditing:)]) {
BOOL begin = [self.delegate searchBarShouldBeginEditing:self];
if(begin) {
if(@available(iOS11.0, *) &&self.placeHolderCenter) {
[self setPositionAdjustment:self.originPositionSearchOffSet forSearchBarIcon:UISearchBarIconSearch];
}
if(!self.clearBtnHidden) {
self.hideClearBtn=NO;
}
}
returnbegin;
}
if(@available(iOS11.0, *) &&self.placeHolderCenter) {
[self setPositionAdjustment:self.originPositionSearchOffSet forSearchBarIcon:UISearchBarIconSearch];
}
if (!self.clearBtnHidden) {
self.hideClearBtn=NO;
}
return YES;
}
-(BOOL)textFieldShouldEndEditing:(UITextField*)textField
{
if([self.delegaterespondsToSelector:@selector(searchBarShouldEndEditing:)]){
BOOL end = [self.delegate searchBarShouldEndEditing:self];
if(end) {
if(@available(iOS11.0, *) &&self.placeHolderCenter) {
if(textField.text.length==0) {
[self setPositionAdjustment:UIOffsetMake((textField.frame.size.width-[self placeHolderTextWidth])/2, 0) forSearchBarIcon:UISearchBarIconSearch];
}
}
if(self.clearBtnHidden) {
self.hideClearBtn=YES;
}
}
returnend;
}
if(@available(iOS11.0, *) &&self.placeHolderCenter) {
if(textField.text.length==0) {
[self setPositionAdjustment:UIOffsetMake((textField.frame.size.width-[self placeHolderTextWidth])/2, 0) forSearchBarIcon:UISearchBarIconSearch];
}
}
if (self.clearBtnHidden) {
self.hideClearBtn=YES;
}
return YES;
}
-(void)textFieldDidEndEditing:(UITextField*)textField
{
if (self.cancelInputDisabled) {
self.cancelInputDisabled = YES;
}
}
/**
获得搜索框
*/
-(UITextField*)textField
{
UITextField*searchField = [selfvalueForKey:@"searchField"];
// for (UIView *view in self.subviews.lastObject.subviews) {
// if([view isKindOfClass:NSClassFromString(@"UISearchBarTextField")]) {
// return (UITextField*)view;
// }
// }
returnsearchField;
}
/**
获得取消按钮
*/
-(UIButton*)cancelBtn
{
UIView* view = [selfvalueForKeyPath:@"cancelButton"];
// if ([view isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
UIButton*cancelBtn = (UIButton*)view;
// }
returncancelBtn;
}
/**
计算placeHolder的宽度
*/
-(CGFloat)placeHolderTextWidth
{
UITextField* textField = [selftextField];
return [self.placeHolderString boundingRectWithSize:textField.frame.size options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSForegroundColorAttributeName:_placeHolderStringColor?_placeHolderStringColor:kDefaultPlaceHolerTextColor,NSFontAttributeName:_placeHolderStringFont?_placeHolderStringFont:kDefaultPlaceHolderTextFont} context:nil].size.width;
}
-(void)layoutSubviews
{
[super layoutSubviews];
if(@available(iOS11.0, *) &&self.placeHolderCenter) {
UITextField* textField = [selftextField];
[self setPositionAdjustment:UIOffsetMake((textField.frame.size.width-[self placeHolderTextWidth])/2, 0) forSearchBarIcon:UISearchBarIconSearch];
}
}
网友评论