对于定义UITabBar来说我们就是要创建一个和tabBar尺寸相同的View,当点击View部分时候View通知我们的UITabBarController点击的index,然后由controller调整选择的控制器.
自定义tabbar.h的文件
#import <UIKit/UIKit.h>
@interface YZMTabItem :UIView
@property(nonatomic,copy)NSString *title;
@property(nonatomic,copy)NSString *normalImage;
@property(nonatomic,copy)NSString *selectedImage;
-(BOOL)isSelected;
-(void)setSelected:(BOOL)selected;
@end
//数据源方法
@class YZMTabBar;
@protocol YZMTabBarDataSource <NSObject>
//有多少选项
@required
-(NSInteger)numOfItemInTabbar;
-(YZMTabItem *)tabbar:(YZMTabBar *)tabbar itemAtIndex:(NSInteger)index;
@end
//代理方法
@protocol YZNTabBarDelegate <NSObject>
-(void)tabbar:(YZMTabBar *)tabbar didSelectedItemAtIndex:(NSInteger)index;
@end
@interface YZMTabBar : UIView
@property(nonatomic,weak)id<YZMTabBarDataSource> dateSource;
@property(nonatomic,weak)id<YZNTabBarDelegate> delegate;
//外部改变当前选中的值
-(void)selectItemAtIndex:(NSInteger)index;
@end
tabbar.m
#import "YZMTabBar.h"
#define imageW 25
#define imageH 25
#define titleW 50
#define titleH 20
#define diffItemTag 100
@interface YZMTabItem ()
{
BOOL _selected;
}
//@property(nonatomic,assign,getter=isSelected)BOOL selected;
@property(nonatomic,strong)UIImageView *imageView;
@property(nonatomic,strong)UILabel *titleLabel;
@end
@implementation YZMTabItem
//初始化方法
-(instancetype)initWithFrame:(CGRect)frame
{
if (self=[super initWithFrame:frame]) {
CGFloat viewW=frame.size.width;
CGFloat viewH=frame.size.height;
[self setBackgroundColor:[UIColor clearColor]];
_imageView=[[UIImageView alloc] initWithFrame:CGRectMake((viewW-imageW)*0.5, (viewH-imageH-titleH)*0.5, imageW, imageH)];
[self addSubview:_imageView];
_titleLabel=[[UILabel alloc] initWithFrame:CGRectMake((viewW-titleW)*0.5, CGRectGetMaxY(_imageView.frame), titleW, titleH)];
_titleLabel.font=[UIFont systemFontOfSize:14.0f];
_titleLabel.textAlignment=NSTextAlignmentCenter;
// [_titleLabel setBackgroundColor:[UIColor redColor]];
[self addSubview:_titleLabel];
}
return self;
}
-(void)setSelected:(BOOL)selected
{
_selected=selected;
if (_selected) {
_imageView.image=[UIImage imageNamed:self.selectedImage];
_titleLabel.textColor=[UIColor colorWithRed:245/255.0 green:102/255.0 blue:147/255.0 alpha:1];
[self showAnimation];
}else{
_imageView.image=[UIImage imageNamed:self.normalImage];
_titleLabel.textColor=[UIColor grayColor];
}
}
-(void)showAnimation
{
CAKeyframeAnimation *animation=[CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
animation.values=@[[NSNumber numberWithFloat:1.0],[NSNumber numberWithFloat:0.5],[NSNumber numberWithFloat:1.2],[NSNumber numberWithFloat:1.0]];
animation.duration=1;
[self.layer addAnimation:animation forKey:animation.keyPath];
}
-(BOOL)isSelected
{
return _selected;
}
-(void)setNormalImage:(NSString *)normalImage
{
_normalImage=normalImage;
//按钮的初始化状态为未选中
[self setSelected:NO];
}
-(void)setTitle:(NSString *)title
{
_title=title;
self.titleLabel.text=title;
}
@end
struct{
unsigned int numOfItemInTabbarMethod :1;
unsigned int itemAtIndexMethod :1;
}dataSourceFlag;
@interface YZMTabBar ()
{
NSInteger selectedItemTag;//当前选中的itemtag
}
@end
@implementation YZMTabBar
-(void)setDateSource:(id<YZMTabBarDataSource>)dateSource
{
_dateSource=dateSource;
selectedItemTag=-1;
[self setBackgroundColor:[UIColor colorWithRed:42/255.0 green:176/255.0 blue:252/255.0 alpha:1]];
//方法是否有定义
dataSourceFlag.numOfItemInTabbarMethod=[_dateSource respondsToSelector:@selector(numOfItemInTabbar)];
dataSourceFlag.itemAtIndexMethod=[_dateSource respondsToSelector:@selector(tabbar:itemAtIndex:)];
// NSAssert(!dataSourceFlag.numOfItemInTabbarMethod, @"数据源方法未定义");
NSInteger numberOfItems=[_dateSource numOfItemInTabbar];
for(int i=0;i<numberOfItems;i++){
UIView *itemView=[_dateSource tabbar:self itemAtIndex:i];
itemView.tag=i+diffItemTag;
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(TapOnItemView:)];
[itemView addGestureRecognizer:tap];
[self addSubview:itemView];
}
}
-(void)TapOnItemView:(UIGestureRecognizer *)gesture
{
YZMTabItem *view=(YZMTabItem *)gesture.view;
if (view.tag==selectedItemTag) {
return;
}
if (selectedItemTag!=-1) {
YZMTabItem *selectedView=(YZMTabItem *)[self viewWithTag:selectedItemTag];
[selectedView setSelected:NO];
}
selectedItemTag=view.tag;
[view setSelected:YES];
if ([_delegate respondsToSelector:@selector(tabbar:didSelectedItemAtIndex:)]) {
[_delegate tabbar:self didSelectedItemAtIndex:selectedItemTag-diffItemTag];
}
}
-(void)selectItemAtIndex:(NSInteger)index
{
if (selectedItemTag==index+diffItemTag) {
return;
}
if (selectedItemTag!=-1) {
YZMTabItem *selectedView=(YZMTabItem *)[self viewWithTag:selectedItemTag];
[selectedView setSelected:NO];
}
selectedItemTag=index+diffItemTag;
YZMTabItem *view=(YZMTabItem *)[self viewWithTag:selectedItemTag];
[view setSelected:YES];
if ([_delegate respondsToSelector:@selector(tabbar:didSelectedItemAtIndex:)]) {
[_delegate tabbar:self didSelectedItemAtIndex:selectedItemTag-diffItemTag];
}
}<pre name="code" class="objc"> UINavigationBar *navigationBar=[UINavigationBar appearance];
UIImage *resizeImage=[self imageByApplyingAlpha:0.99 image:[UIImage imageNamed:@"navogatinBar_bk.jpg"]];
[navigationBar setBackgroundImage:resizeImage forBarMetrics:UIBarMetricsDefault];
在tabBarController中使用
- (void)viewDidLoad {
[super viewDidLoad];
//添加控制器
[self addControllers];
_itemSettingArray=@[@[@"首页",@"C01.png",@"C02.png"],
@[@"订单",@"C03.png",@"C04.png"],
@[@"我",@"C05.png",@"C06.png" ],
@[@"更多",@"C07.png",@"C08.png"]
];
YZMTabBar *tabbar=[[YZMTabBar alloc] initWithFrame:CGRectMake(0, 0, SCREENWIDTH, 100)];
tabbar.dateSource=self;
tabbar.delegate=self;
[self.tabBar addSubview:tabbar];
[tabbar selectItemAtIndex:0];
}
//删除除自定义外的所有子视图
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
for(UIView *view in self.tabBar.subviews)
{
if (![view isKindOfClass:[YZMTabBar class]]) {
[view removeFromSuperview];
};
}
}
-(void)addControllers
{
HomeViewController *homeVC=[[HomeViewController alloc] init];
[self AddSubController:homeVC withTitle:@"首页"];
OrderViewController *orderVC=[[OrderViewController alloc] init];
[self AddSubController:orderVC withTitle:@"订单"];
MeViewController *meVC=[[MeViewController alloc] initWithNibName:@"MeViewController" bundle:nil];
[self AddSubController:meVC withTitle:@"我"];
MoreViewController *moreVC=[[MoreViewController alloc] initWithNibName:@"MoreViewController" bundle:nil];
[self AddSubController:moreVC withTitle:@"更多"];
//默认选择
// [self setSelectedIndex:0];
}
#pragma mark dateSource
-(NSInteger)numOfItemInTabbar
{
NSLog(@"%lu",_itemSettingArray.count);
return _itemSettingArray.count;
}
-(YZMTabItem *)tabbar:(YZMTabBar *)tabbar itemAtIndex:(NSInteger)index
{
CGFloat itemW=SCREENWIDTH/_itemSettingArray.count;
CGFloat itemH=49;
YZMTabItem *item=[[YZMTabItem alloc] initWithFrame:CGRectMake(index*itemW, 0, itemW, itemH)];
item.title=_itemSettingArray[index][0];
item.normalImage=_itemSettingArray[index][1];
item.selectedImage=_itemSettingArray[index][2];
return item;
}
#pragma mark delegate
-(void)tabbar:(YZMTabBar *)tabbar didSelectedItemAtIndex:(NSInteger)index
{
NSLog(@"%lu",index);
[self setSelectedIndex:index];
}
-(void)AddSubController:(UIViewController *)controller withTitle:(NSString *)name
{
//
controller.title=name;
YZMNavigationController *navigation=[[YZMNavigationController alloc] initWithRootViewController:controller];
[self addChildViewController:navigation];
}
这样去设计也借鉴一些写的比较好的代码.
我们封装了barItem:他有图片和文字组成,他的模型参考的UIButton,(初始化,设置素材,可选切换,自定义动画)
TabBar的设计模型参考了tableView:有数据源,代理方法,并为添加到自身的tabbarItem设置管理方法.
UINavigationBar :
1.设置他的setBackgroundImage:forBarMetrics:会出现一种情况,我们的控制器的视图会向下偏移.解决的办法我们可以调整image的Alpha为0.99
这个现象就不会出现了
UINavigationBar *navigationBar=[UINavigationBar appearance];
UIImage *resizeImage=[self imageByApplyingAlpha:0.99 image:[UIImage imageNamed:@"navogatinBar_bk.jpg"]];
[navigationBar setBackgroundImage:resizeImage forBarMetrics:UIBarMetricsDefault];
//设置图片透明度
+ (UIImage *)imageByApplyingAlpha:(CGFloat)alpha image:(UIImage*)image
{
UIGraphicsBeginImageContextWithOptions(image.size, NO, 0.0f);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, image.size.width, image.size.height);
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);
CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
CGContextSetAlpha(ctx, alpha);
CGContextDrawImage(ctx, area, image.CGImage);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
2.设置Navigation导航条的透明度,
不可行的方法,就是直接设置Navigation的alpha,因为导航条还会有其他的图层.
可行的就是弄一张1*1的透明的图设置成setBackgroundImage:forBarMetrics:的image(这样会使得整个导航条变得透明化)
然后在添加一个view到navigationBar的下方,通过调整这个view的透明度就可以实现我们的背景的透明化.
CGSize size=self.navigationBar.bounds.size;
UIView *alphaView=[[UIView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height+20)];
[alphaView setBackgroundColor:[UIColor whiteColor]];
alphaView.alpha=0.8;
UIView *flagView=[[UIView alloc] initWithFrame:CGRectMake(0, alphaView.height-1, alphaView.width, 1)];
[flagView setBackgroundColor:[UIColor colorWithRed:220/255.0 green:220/255.0 blue:220/255.0 alpha:1]];
[alphaView addSubview:flagView];
[self.view insertSubview:alphaView belowSubview:self.navigationBar];
[self.navigationBar setBackgroundImage:[UIImage imageNamed:@"bigShadow.png"] forBarMetrics:UIBarMetricsCompact];
self.navigationBar.layer.masksToBounds = YES;
定制UINavigationBar 的apperenc(主题)
我们通过设置这个属性可以改变接下来用UINavigationBar创建的所有实例的样式,但是对于之前的没有效果,而且一种navigationbar只会有一种样式.作为新建实例的一个参照.