今天的內(nèi)容也是關(guān)于首頁(yè)架構(gòu)的實(shí)現(xiàn),大概分為三塊.
- 第一點(diǎn)是關(guān)于自定義的searchBar 由于大家項(xiàng)目中經(jīng)常有些控件是系統(tǒng)控件不能實(shí)現(xiàn)的,或者是經(jīng)常使用的,但是不是在一個(gè)頁(yè)面.所以我會(huì)使用自定義控件的方法進(jìn)行封裝.
- 第二點(diǎn)是關(guān)于自定義的menu蒙版的效果,也是對(duì)于不同的view回頭內(nèi)容的封裝,大家可以進(jìn)行思考.
- 最后一點(diǎn)的就是關(guān)于TabBar條上添加一個(gè)加號(hào)按鈕,這個(gè)時(shí)候也是采取的自定義TabBar的方法,強(qiáng)行在中間添加一個(gè)按鈕.
今天的內(nèi)容都是有關(guān)于控件的自定義跟封裝,看起來(lái)很簡(jiǎn)單,但是相比知識(shí)點(diǎn)是少了一點(diǎn),但是對(duì)于思想上的提升也是很有幫助,對(duì)于大家的代碼邏輯以及以后代碼的嚴(yán)謹(jǐn)也很有基礎(chǔ).
GIF

第二天內(nèi)容.gif
代碼如下
- 第一點(diǎn)有關(guān)于自定義的searchBar的封裝,在此之前博主想說(shuō)對(duì)于這種經(jīng)常使用到的控件如果是想多次利用封裝好是用分類還是用繼承好呢.博主覺(jué)得如果是UI控件的話就使用繼承,一個(gè)是在創(chuàng)建的時(shí)候,不需要知道你內(nèi)部是怎么實(shí)現(xiàn),二是知道你使用的名字就跟想用的完全一樣.一看就知道這個(gè)控件是做什么的,不要點(diǎn)進(jìn)去看是什么控件.
+ (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;
}
- 第二點(diǎn),是有關(guān)于自定義的那干view.由于經(jīng)常使用到內(nèi)部的控件.也是進(jìn)行封裝的,其實(shí)就是一個(gè)UIImageView 跟 UIButton. 對(duì)于點(diǎn)擊到UIImageView之外的地方就直接從窗口上移除.這里就提供了好幾種接口給大家展示.大家可以看源碼就知道.
#import <UIKit/UIKit.h>
@class WKPopMenu;
@protocol WKPopMenuDelegate <NSObject>
@optional
- (void)popMenuDidChangeImageRocation: (WKPopMenu *)popMenu;
@end
@interface WKPopMenu : UIView
@property (nonatomic,weak)id<WKPopMenuDelegate> 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];
}
- 最后一點(diǎn)就是關(guān)于在自定義的tabBar上添加一個(gè)按鈕,樓主使用的是替換到系統(tǒng)自帶的tabBar 然后進(jìn)行布局
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
//創(chuàng)建一個(gè)按鈕
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__);
//點(diǎn)擊按鈕讓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];
//設(shè)置加號(hào)按鈕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 讓循環(huán)繼續(xù)下去
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 ++ ;
}
}
其他知識(shí)點(diǎn)補(bǔ)充:
四個(gè)容易混淆的屬性:
1. textAligment : 文字的水平方向的對(duì)齊方式
1> 取值
NSTextAlignmentLeft = 0, // 左對(duì)齊
NSTextAlignmentCenter = 1, // 居中對(duì)齊
NSTextAlignmentRight = 2, // 右對(duì)齊
2> 哪些控件有這個(gè)屬性 : 一般能夠顯示文字的控件都有這個(gè)屬性
* UITextField
* UILabel
* UITextView
2. contentVerticalAlignment : 內(nèi)容的垂直方向的對(duì)齊方式
1> 取值
UIControlContentVerticalAlignmentCenter = 0, // 居中對(duì)齊
UIControlContentVerticalAlignmentTop = 1, // 頂部對(duì)齊
UIControlContentVerticalAlignmentBottom = 2, // 底部對(duì)齊
2> 哪些控件有這個(gè)屬性 : 繼承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...
3. contentHorizontalAlignment : 內(nèi)容的水平方向的對(duì)齊方式
1> 取值
UIControlContentHorizontalAlignmentCenter = 0, // 居中對(duì)齊
UIControlContentHorizontalAlignmentLeft = 1, // 左對(duì)齊
UIControlContentHorizontalAlignmentRight = 2, // 右對(duì)齊
2> 哪些控件有這個(gè)屬性 : 繼承自UIControl的控件或者UIControl本身
* UIControl
* UIButton
* UITextField
* ...
4. contentMode : 內(nèi)容模式(控制內(nèi)容的對(duì)齊方式), 一般對(duì)UIImageView很有用
1> 取值
/**
規(guī)律:
1.Scale : 圖片會(huì)拉伸
2.Aspect : 圖片會(huì)保持原來(lái)的寬高比
*/
// 前3個(gè)情況, 圖片都會(huì)拉伸
// (默認(rèn))拉伸圖片至填充整個(gè)UIImageView(圖片的顯示尺寸會(huì)跟UIImageView的尺寸一樣)
UIViewContentModeScaleToFill,
// 按照?qǐng)D片原來(lái)的寬高比進(jìn)行伸縮, 伸縮至適應(yīng)整個(gè)UIImageView(圖片的內(nèi)容不能超出UIImageView的尺寸范圍)
UIViewContentModeScaleAspectFit,
// 按照?qǐng)D片原來(lái)的寬高比進(jìn)行伸縮, 伸縮至 圖片的寬度和UIImageView的寬度一樣 或者 圖片的高度和UIImageView的高度一樣
UIViewContentModeScaleAspectFill,
// 后面的所有情況, 都會(huì)按照?qǐng)D片的原來(lái)尺寸顯示, 不會(huì)進(jìn)行拉伸
UIViewContentModeRedraw, // 當(dāng)控件的尺寸改變了, 就會(huì)重繪一次(重新調(diào)用setNeedsDisplay, 調(diào)用drawRect:)
UIViewContentModeCenter,
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
2> 哪些控件有這個(gè)屬性 : 所有UI控件都有
5. 如果有多個(gè)屬性的作用沖突了, 只有1個(gè)屬性有效(就近原則)
一、UINavigationItem
1> 獲得方式
self.navigationItem // self是指控制器
2> 作用
可以用來(lái)設(shè)置當(dāng)前控制器頂部導(dǎo)航欄的內(nèi)容
// 設(shè)置導(dǎo)航欄中間的內(nèi)容
self.navigationItem.title
self.navigationItem.titleView
二、UIBarButtonItem
1> 用在什么地方
// 設(shè)置導(dǎo)航欄左上角的內(nèi)容
self.navigationItem.leftBarButtonItem
// 設(shè)置導(dǎo)航欄右上角的內(nèi)容
self.navigationItem.rightBarButtonItem
2> 作用
相當(dāng)于一個(gè)按鈕
三、UITabBarItem
1> 獲得方式
self.tabBarItem // self是指控制器
2> 作用
可以用來(lái)設(shè)置當(dāng)前控制器對(duì)應(yīng)的選項(xiàng)卡標(biāo)簽的內(nèi)容
// 標(biāo)簽的標(biāo)題
self.tabBarItem.title
// 標(biāo)簽的圖標(biāo)
self.tabBarItem.image
// 標(biāo)簽的選中圖標(biāo)
self.tabBarItem.selectdImage
四、UINavigationBar
1. 導(dǎo)航控制器頂部的欄(UI控件)
2. UINavigationBar上面顯示什么內(nèi)容, 取決于當(dāng)前控制器的navigationItem屬性
3. UINavigationBar是view, navigationItem是model
4. 由navigationItem給UINavigationBar提供顯示的數(shù)據(jù)
五、UITabBar
1. UITabBarController底部的選項(xiàng)卡條
六、UITabBarButton
1. UITabBar底部的每一個(gè)標(biāo)簽
2. 每一個(gè)UITabBarButton里面顯示什么內(nèi)容,取決于當(dāng)前控制器的tabBarItem屬性
3. UITabBarButton是view, tabBarItem是model
4. 由tabBarItem給UITabBarButton提供顯示的數(shù)據(jù)
由于今天的內(nèi)容也很簡(jiǎn)單大家有疑問(wèn)的可以查看源碼,地址:https://github.com/aryehToDog/WKWeibo
還有不同的問(wèn)題,可以在下方提問(wèn).每天的代碼我都會(huì)選取重要的地方進(jìn)行講解.謝謝大家