Dota2APP--第二天

一、今天的任务

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

原文地址:https://www.cnblogs.com/fengzhihao/p/5344526.html