今天的内容也是关于首页架构的实现,大概分为三块.
- 第一点是关于自定义的searchBar 由于大家项目中经常有些控件是系统控件不能实现的,或者是经常使用的,但是不是在一个页面.所以我会使用自定义控件的方法进行封装.
- 第二点是关于自定义的menu蒙版的效果,也是对于不同的view回头内容的封装,大家可以进行思考.
- 最后一点的就是关于TabBar条上添加一个加号按钮,这个时候也是采取的自定义TabBar的方法,强行在中间添加一个按钮.
今天的内容都是有关于控件的自定义跟封装,看起来很简单,但是相比知识点是少了一点,但是对于思想上的提升也是很有帮助,对于大家的代码逻辑以及以后代码的严谨也很有基础.
GIF
代码如下
- 第一点有关于自定义的searchBar的封装,在此之前博主想说对于这种经常使用到的控件如果是想多次利用封装好是用分类还是用继承好呢.博主觉得如果是UI控件的话就使用继承,一个是在创建的时候,不需要知道你内部是怎么实现,二是知道你使用的名字就跟想用的完全一样.一看就知道这个控件是做什么的,不要点进去看是什么控件.
+ (instancetype)searchBar {
WKSearchBar *searchBar = [[WKSearchBar alloc]init];
searchBar.background = [UIImage resizableImage:@"searchbar_textfield_background"];
searchBar.width = [UIScreen mainScreen].bounds.size.width;
searchBar.height = 30;
UIImageView *leftView = [[UIImageView alloc]init];
leftView.image = [UIImage imageNamed:@"searchbar_textfield_search_icon"];
searchBar.leftView =leftView;
searchBar.leftViewMode = UITextFieldViewModeAlways;
leftView.width = 30;
leftView.height = 30;
leftView.contentMode = UIViewContentModeCenter;
searchBar.clearButtonMode = UITextFieldViewModeWhileEditing;
return searchBar;
}
- 第二点,是有关于自定义的那干view.由于经常使用到内部的控件.也是进行封装的,其实就是一个UIImageView 跟 UIButton. 对于点击到UIImageView之外的地方就直接从窗口上移除.这里就提供了好几种接口给大家展示.大家可以看源码就知道.
#import
@class WKPopMenu;
@protocol WKPopMenuDelegate
@optional
- (void)popMenuDidChangeImageRocation: (WKPopMenu *)popMenu;
@end
@interface WKPopMenu : UIView
@property (nonatomic,weak)id delegate;
- (instancetype)initWith: (UIView *)contentView;
+ (instancetype)popMenuWith: (UIView *)contentView;
- (void)showInrect: (CGRect)rect;
- (void)dismiss;
@end
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.frame = [UIScreen mainScreen].bounds;
UIButton *clearBtn = [[UIButton alloc]init];
// [clearBtn setBackgroundColor:[UIColor redColor]];
[clearBtn addTarget:self action:@selector(clickClearBtn) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:clearBtn];
self.clearBtn = clearBtn;
UIImageView *content = [[UIImageView alloc]init];
// content.backgroundColor = [UIColor yellowColor];
content.image = [UIImage resizableImage:@"popover_background"];
content.userInteractionEnabled = YES;
[self addSubview:content];
self.content = content;
}
return self;
}
- (void)clickClearBtn {
[self dismiss];
}
- (void)layoutSubviews {
[super layoutSubviews];
self.clearBtn.frame = self.bounds;
}
- (instancetype)initWith: (UIView *)contentView {
if (self = [super init]) {
self.contentView = contentView;
}
return self;
}
+ (instancetype)popMenuWith: (UIView *)contentView{
return [[WKPopMenu alloc]initWith:contentView];
}
- (void)showInrect: (CGRect)rect{
UIWindow *window = (UIWindow *)[UIApplication sharedApplication].keyWindow;
[window addSubview:self];
self.content.frame = rect;
[self.content addSubview:self.contentView];
CGFloat topMargin = 10;
CGFloat leftMargin = 5;
CGFloat rightMargin = 5;
CGFloat bottonMargin = 5;
self.contentView.x = leftMargin;
self.contentView.y = topMargin;
self.contentView.width = self.content.width - leftMargin - rightMargin;
self.contentView.height = self.content.height - topMargin - bottonMargin;
}
- (void)dismiss {
if ([self.delegate respondsToSelector:@selector(popMenuDidChangeImageRocation:)]) {
[self.delegate popMenuDidChangeImageRocation:self];
}
[self removeFromSuperview];
}
- 最后一点就是关于在自定义的tabBar上添加一个按钮,楼主使用的是替换到系统自带的tabBar 然后进行布局
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
//创建一个按钮
UIButton *publishBtn = [[UIButton alloc]init];
[publishBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
[publishBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateSelected];
[publishBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
[publishBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateSelected];
[publishBtn addTarget:self action:@selector(clickPublish) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:publishBtn];
self.publishBtn = publishBtn;
}
return self;
}
- (void)clickPublish {
NSLog(@"%s",__func__);
//点击按钮让tabbarController成为代码弹出控制器
// if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPublish:)]) {
//
// [self.tabBarDelegate tabBarDidClickPublish:self];
// }
UIWindow *window = [UIApplication sharedApplication].keyWindow;
WKPublishViewController *publishVc = [[WKPublishViewController alloc]init];
WKNavigationController *nav = [[WKNavigationController alloc]initWithRootViewController:publishVc];
[window.rootViewController presentViewController:nav animated:YES completion:nil];
}
- (void)layoutSubviews {
[super layoutSubviews];
//设置加号按钮frame
self.publishBtn.size = self.publishBtn.currentBackgroundImage.size;
self.publishBtn.center = CGPointMake(self.width * 0.5, self.height * 0.5);
NSInteger index = 0;
for (UIView *tabBarItem in self.subviews) {
//如果子控件不是UITabBarButton 让循环继续下去
if (![tabBarItem isKindOfClass:NSClassFromString(@"UITabBarButton")]) continue;
CGFloat tabBarY = 0;
CGFloat tabBarW = self.width / 5;
CGFloat tabBarH = self.height;
CGFloat tabBarX;
if (index >= 2) {
tabBarX = (index + 1) * tabBarW;
}else {
tabBarX = index * tabBarW;
}
tabBarItem.frame = CGRectMake(tabBarX, tabBarY, tabBarW, tabBarH);
index ++ ;
}
}
其他知识点补充:
四个容易混淆的属性:
1. textAligment : 文字的水平方向的对齐方式
1> 取值
NSTextAlignmentLeft = 0, // 左对齐
NSTextAlignmentCenter = 1, // 居中对齐
NSTextAlignmentRight = 2, // 右对齐
2> 哪些控件有这个属性 : 一般能够显示文字的控件都有这个属性
* UITextField
* UILabel
* UITextView
2. contentVerticalAlignment : 内容的垂直方向的对齐方式
1> 取值
UIControlContentVerticalAlignmentCenter = 0, // 居中对齐
UIControlContentVerticalAlignmentTop = 1, // 顶部对齐
UIControlContentVerticalAlignmentBottom = 2, // 底部对齐
2> 哪些控件有这个属性 : 继承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...
3. contentHorizontalAlignment : 内容的水平方向的对齐方式
1> 取值
UIControlContentHorizontalAlignmentCenter = 0, // 居中对齐
UIControlContentHorizontalAlignmentLeft = 1, // 左对齐
UIControlContentHorizontalAlignmentRight = 2, // 右对齐
2> 哪些控件有这个属性 : 继承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...
4. contentMode : 内容模式(控制内容的对齐方式), 一般对UIImageView很有用
1> 取值
/**
规律:
1.Scale : 图片会拉伸
2.Aspect : 图片会保持原来的宽高比
*/
// 前3个情况, 图片都会拉伸
// (默认)拉伸图片至填充整个UIImageView(图片的显示尺寸会跟UIImageView的尺寸一样)
UIViewContentModeScaleToFill,
// 按照图片原来的宽高比进行伸缩, 伸缩至适应整个UIImageView(图片的内容不能超出UIImageView的尺寸范围)
UIViewContentModeScaleAspectFit,
// 按照图片原来的宽高比进行伸缩, 伸缩至 图片的宽度和UIImageView的宽度一样 或者 图片的高度和UIImageView的高度一样
UIViewContentModeScaleAspectFill,
// 后面的所有情况, 都会按照图片的原来尺寸显示, 不会进行拉伸
UIViewContentModeRedraw, // 当控件的尺寸改变了, 就会重绘一次(重新调用setNeedsDisplay, 调用drawRect:)
UIViewContentModeCenter,
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
2> 哪些控件有这个属性 : 所有UI控件都有
5. 如果有多个属性的作用冲突了, 只有1个属性有效(就近原则)
一、UINavigationItem
1> 获得方式
self.navigationItem // self是指控制器
2> 作用
可以用来设置当前控制器顶部导航栏的内容
// 设置导航栏中间的内容
self.navigationItem.title
self.navigationItem.titleView
二、UIBarButtonItem
1> 用在什么地方
// 设置导航栏左上角的内容
self.navigationItem.leftBarButtonItem
// 设置导航栏右上角的内容
self.navigationItem.rightBarButtonItem
2> 作用
相当于一个按钮
三、UITabBarItem
1> 获得方式
self.tabBarItem // self是指控制器
2> 作用
可以用来设置当前控制器对应的选项卡标签的内容
// 标签的标题
self.tabBarItem.title
// 标签的图标
self.tabBarItem.image
// 标签的选中图标
self.tabBarItem.selectdImage
四、UINavigationBar
1. 导航控制器顶部的栏(UI控件)
2. UINavigationBar上面显示什么内容, 取决于当前控制器的navigationItem属性
3. UINavigationBar是view, navigationItem是model
4. 由navigationItem给UINavigationBar提供显示的数据
五、UITabBar
1. UITabBarController底部的选项卡条
六、UITabBarButton
1. UITabBar底部的每一个标签
2. 每一个UITabBarButton里面显示什么内容,取决于当前控制器的tabBarItem属性
3. UITabBarButton是view, tabBarItem是model
4. 由tabBarItem给UITabBarButton提供显示的数据
由于今天的内容也很简单大家有疑问的可以查看源码,地址:https://github.com/aryehToDog/WKWeibo
还有不同的问题,可以在下方提问.每天的代码我都会选取重要的地方进行讲解.谢谢大家