标签:
一、今天的任务
1)自定义标签栏控制器
2)自定义导航栏控制器
3)在新特性界面播放音频
1、第一个任务:自定义标签栏控制器
原因:默认的TabbarViewController不能满足项目的需求。
1)自定义TabBarButton
button的内部构造是由一个label和imageView组成,所以自定义TabBarButton就是自定义label和ImageView的位置。
代码如下:
#pragma mark - 覆盖父类的2个方法 #pragma mark - 设置按钮标题的frame - (CGRect)titleRectForContentRect:(CGRect)contentRect { CGFloat titleY = contentRect.size.height * FZHTabBarImageRatio; CGFloat titleH = contentRect.size.height - titleY; CGFloat titleW = contentRect.size.width; return CGRectMake(0, titleY, titleW, titleH); } - (CGRect)imageRectForContentRect:(CGRect)contentRect { CGFloat imageH = contentRect.size.height * FZHTabBarImageRatio; CGFloat imageW = contentRect.size.width; return CGRectMake(0, 2, imageW, imageH); }
因为使我们自定义的button所以他并没有系统的点击方法,所以我们要给button添加观察者来监听他的点击事件来做切换视图的操作。
代码如下:
- (void)setItem:(UITabBarItem *)item { _item = item; //1.利用kvo监听item属性的改变 [item addObserver:self forKeyPath:@"title" options:0 context:nil]; [item addObserver:self forKeyPath:@"image" options:0 context:nil]; [item addObserver:self forKeyPath:@"selectedImage" options:0 context:nil]; //2.属性赋值 [self observeValueForKeyPath:nil ofObject:nil change:nil context:nil]; }
KVO监听必须在监听器释放的时候,移除监听操作, 通知也得在释放的时候移除监听
代码如下:
-(void)dealloc { [self.item removeObserver:self forKeyPath:@"title"]; [self.item removeObserver:self forKeyPath:@"image"]; [self.item removeObserver:self forKeyPath:@"selectedImage"]; }
监听方法如下:
/** * 监听item的属性值改变 * * @param keyPath 哪个属性改变了 * @param object 哪个对象的属性改变了 */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context { //1.设置文字 [self setTitle:self.item.title forState:UIControlStateSelected]; [self setTitle:self.item.title forState:UIControlStateNormal]; //2.设置图片 [self setImage:self.item.image forState:UIControlStateNormal]; [self setImage:self.item.selectedImage forState:UIControlStateSelected]; }
至此完成自定义TabBarButton。
2)自定义tabbar
因为tabbar是添加在controller上面的,我们的点击事件也是发生在controller上面,那我们如何知道点击了那个按钮呢?我们可以通过代理模式来完成这一功能,让控制器做tabbar的代理,当用户点击控制器的tabbar上面的按钮时,它会通过代理的方式来告诉tabbar点击了那个按钮,这样我们就可以做相应的操作了。
.h文件代码如下:
1 #import <UIKit/UIKit.h> 2 #import "FZHTabbarButton.h" 3 @class FZHTabbar; 4 @protocol FZHTabbarDelegate <NSObject> 5 6 @optional 7 - (void)tabBar:(FZHTabbar *)tabBar didSelectedButtonFrom:(int)from to:(int)to; 8 - (void)tabBardidPlusButton:(FZHTabbar *)tabBar; 9 10 @end 11 @interface FZHTabbar : UIView 12 @property (nonatomic,strong)NSMutableArray * tabbarButtons; 13 @property (weak,nonatomic)FZHTabbarButton * selectedButton; 14 - (void)addTabbarButtonWithItem:(UITabBarItem *)item; 15 @property (nonatomic,weak)id<FZHTabbarDelegate>delegate; 16 @end
.m文件代码如下:
1 #import "FZHTabbar.h" 2 #import "FZHTabbarButton.h" 3 @implementation FZHTabbar 4 5 - (NSMutableArray *)tabbarButtons 6 { 7 if (_tabbarButtons == nil) { 8 _tabbarButtons = [NSMutableArray array]; 9 } 10 return _tabbarButtons; 11 12 } 13 - (id)initWithFrame:(CGRect)frame 14 { 15 self = [super initWithFrame:frame]; 16 if (self) { 17 18 } 19 return self; 20 } 21 - (void)addTabbarButtonWithItem:(UITabBarItem *)item 22 { 23 //1.创建按钮 24 FZHTabbarButton * button=[[FZHTabbarButton alloc]init]; 25 [self.tabbarButtons addObject:button]; 26 //2.设置数据 27 button.item=item; 28 29 //3.添加按钮 30 [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchDown]; 31 [self addSubview:button]; 32 //4.默认选中 33 if (self.tabbarButtons.count==1) { 34 35 [self buttonClick:button]; 36 } 37 } 38 -(void)buttonClick:(FZHTabbarButton *)button 39 { 40 //1.通知代理 41 if ([self.delegate respondsToSelector:@selector(tabBar:didSelectedButtonFrom:to:)]) { 42 [self.delegate tabBar:self didSelectedButtonFrom:(int)self.selectedButton.tag to:(int)button.tag]; 43 } 44 //2.控制器选中按钮 45 self.selectedButton.selected=NO; 46 button.selected=YES; 47 self.selectedButton=button; 48 } 49 - (void)layoutSubviews 50 { 51 [super layoutSubviews]; 52 53 //1. 3个按钮 54 CGFloat buttonW=self.frame.size.width/self.subviews.count; 55 CGFloat buttonH=self.frame.size.height; 56 CGFloat buttonY = 0; 57 58 for (int index=0; index<self.tabbarButtons.count; index++) { 59 60 //1.取出按钮 61 FZHTabbarButton * button=self.tabbarButtons[index]; 62 //2.设置按钮的frame 63 CGFloat buttonX=index * buttonW; 64 65 button.frame=CGRectMake(buttonX, buttonY, buttonW, buttonH); 66 //3.绑定tag 67 button.tag=index; 68 } 69 70 }
至此,自定义tabbar部分完成,做到这自定义TabBarViewController也已完成,只剩下在控制器中的初始化操作。
代码如下:
1 /** 2 * 初始化tabbar 3 */ 4 - (void)setupTabbar 5 { 6 FZHTabbar * customTabBar = [[FZHTabbar alloc] init]; 7 customTabBar.frame = self.tabBar.bounds; 8 customTabBar.delegate = self; 9 [self.tabBar addSubview:customTabBar]; 10 self.customTabBar = customTabBar; 11 } 12 /** 13 * 监听tabbar按钮的改变 14 * @param from 原来选中的位置 15 * @param to 最新选中的位置 16 */ 17 - (void)tabBar:(FZHTabbar *)tabBar didSelectedButtonFrom:(int)from to:(int)to 18 { 19 self.selectedIndex = to; 20 } 21 22 -(void)initSubVC 23 { 24 FZHHomeViewController * home=[[FZHHomeViewController alloc]init]; 25 [self setupChildVC:home Title:@"英雄" imageName:@"hero" selectedImageName:@"hero_selected"]; 26 27 FZHVideoViewController * video=[[FZHVideoViewController alloc]init]; 28 [self setupChildVC:video Title:@"视频" imageName:@"video" selectedImageName:@"video_selected"]; 29 30 FZHAboutMeViewController * aboutMe = [[FZHAboutMeViewController alloc]init]; 31 [self setupChildVC:aboutMe Title:@"个人" imageName:@"me" selectedImageName:@"me_selected"]; 32 33 } 34 //初始化所有子控制器 35 -(void)setupChildVC:(UIViewController *)childVC Title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName 36 { 37 //1.设置标题 38 childVC.title=title; 39 //2.设置图片 40 childVC.tabBarItem.image=[UIImage imageNamed:imageName]; 41 //3.设置选中图片 42 childVC.tabBarItem.selectedImage=[UIImage imageNamed:selectedImageName]; 43 //不在渲染图片 44 childVC.tabBarItem.selectedImage=[[UIImage imageNamed:selectedImageName]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 45 //4.添加导航控制器 46 FZHNaviViewController * Nav=[[FZHNaviViewController alloc]initWithRootViewController:childVC]; 47 [self addChildViewController:Nav]; 48 //5.添加tabbar内部的按钮 49 [self.customTabBar addTabbarButtonWithItem:childVC.tabBarItem]; 50 }
注意点:一定要先删除系统自带的tabbar代码如下:
-(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; //删除系统自动生成的UITabBarButton for (UIView * child in self.tabBar.subviews) { if ([child isKindOfClass:[UIControl class]]) { [child removeFromSuperview]; } } }
2、自定义导航栏控制器
代码如下:
1 + (void)initialize 2 { 3 //1.设置导航栏主题 4 [self setupNavBarTheme]; 5 6 //2.设置导航栏按钮的主题 7 [self setupBarButtonItemTheme]; 8 } 9 /** 10 * 设置导航栏按钮主题 11 */ 12 +(void)setupBarButtonItemTheme 13 { 14 UIBarButtonItem * item=[UIBarButtonItem appearance]; 15 //设置文字属性 16 NSMutableDictionary * textAttrs=[NSMutableDictionary dictionary]; 17 18 //字体颜色 19 textAttrs[NSForegroundColorAttributeName] = [UIColor blackColor]; 20 //阴影大小 21 // textAttrs[NSShadowAttributeName] = [NSValue valueWithUIOffset:UIOffsetZero]; 22 textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:17]; 23 //不能点击的状态 24 NSMutableDictionary * DisableTextAttrs=[NSMutableDictionary dictionary]; 25 DisableTextAttrs[NSForegroundColorAttributeName] = [UIColor blackColor]; 26 [item setTitleTextAttributes:DisableTextAttrs forState:UIControlStateDisabled]; 27 //普通和高亮的状态 28 [item setTitleTextAttributes:textAttrs forState:UIControlStateNormal]; 29 [item setTitleTextAttributes:DisableTextAttrs forState:UIControlStateHighlighted]; 30 31 } 32 /** 33 * 设置导航栏主题 34 */ 35 +(void)setupNavBarTheme 36 { 37 //取出appearance对象 38 UINavigationBar * navBar=[UINavigationBar appearance]; 39 navBar.tintColor = [UIColor blackColor]; 40 // 设置标题属性 41 NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary]; 42 //字体颜色 43 textAttrs[NSForegroundColorAttributeName] = [UIColor blackColor]; 44 //阴影大小 45 #warning 设置阴影 46 //textAttrs[NSShadowAttributeName] = [NSValue valueWithUIOffset:UIOffsetZero]; 47 textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:19]; 48 [navBar setTitleTextAttributes:textAttrs]; 49 50 } 51 -(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated 52 { 53 if (self.viewControllers.count>0) { 54 viewController.hidesBottomBarWhenPushed = YES; 55 } 56 [super pushViewController:viewController animated:animated]; 57 }
至此完成了自定义导航栏和标签栏。
3、播放音频
1)导入AVFoundation/AVFoundation框架
2)编写代码如下:
NSURL * mp3Url = [[NSBundle mainBundle] URLForResource:@"Dota2.mp3" withExtension:nil]; AVAudioPlayer * player = [[AVAudioPlayer alloc]initWithContentsOfURL:mp3Url error:nil]; [player prepareToPlay]; player.delegate = self; self.player = player; [self.player play];
到这,以上的三个部分全部实现。
代码下载地址:https://github.com/fengzhihao123/FZHDota2
标签:
原文地址:http://www.cnblogs.com/fengzhihao/p/5344526.html