zoukankan      html  css  js  c++  java
  • 新浪微博自定制TabBar

    转载请标明出处:http://blog.csdn.net/android_ls/article/details/45896395

    声明:仿新浪微博项目,所用所有图片资源都来源于官方新浪微博IOS客户端,编写本应用的目的在于学习交流,如涉及侵权请告知,我会及时换掉用到的相关图片。


    自定义UITabBar替换系统默认的,目的是为了在UITabBar中间位置添加一个“+号按钮”,下面我们来聊聊具体的实现。

    1、自定义WBTabBar,让其继承自UITabBar,代码如下:

    //
    //  WBTabBar.h
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/21.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface WBTabBar : UITabBar
    
    @end
    

    2、tabBar是UITabBarController的只读成员变量(属性),是不让修改的,在UITabBarController.h文件中的声明如下:

    @property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0);
    针对于这种情况,我们可以使用KVC的方式,更换系统自带的UITabBar,实现代码如下:

        WBTabBar *tabBar = [[WBTabBar alloc] init];
        [self setValue:tabBar forKeyPath:@"tabBar"];

    3、添加一个UIButton到WBTabBar中,实现代码如下:

    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            // 添加一个按钮到tabbar中
            UIButton *plusBtn = [[UIButton alloc] init];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateNormal];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted];
            plusBtn.size = plusBtn.currentBackgroundImage.size;
            [plusBtn addTarget:self action:@selector(plusClick) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:plusBtn];
            self.plusBtn = plusBtn;
        }
        return self;
    }

    4、设置加号按钮的位置,调整WBTabBar中各个UITabBarButton的位置和宽度,具体实现代码如下:
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        // 1.设置加号按钮的位置
        self.plusBtn.centerX = self.width * 0.5;
        self.plusBtn.centerY = self.height * 0.5;
        
        // 2.设置其它UITabBarButton的位置和尺寸
        CGFloat tabbarButtonW = self.width / 5;
        CGFloat tabbarButtonIndex = 0;
        for (UIView *child in self.subviews) {
            Class class = NSClassFromString(@"UITabBarButton");
            if ([child isKindOfClass:class]) {
                // 设置宽度
                child.width = tabbarButtonW;
                // 设置x
                child.x = tabbarButtonIndex * tabbarButtonW;
                
                // 增加索引
                tabbarButtonIndex++;
                if (tabbarButtonIndex == 2) {
                    tabbarButtonIndex++;
                }
            }
        }
    }
    

    5、定义WBTabBarDelegate协议,声明WBTabBar的代理,代码如下:
    //
    //  WBTabBar.h
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/21.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    #pragma mark 因为在UITabBar中已经声明过一个UITabBarDelegate协议,
    #pragma mark 我们若想新增一个对外的代理函数,可以让我们自定义的协议继承自UITabBarDelegate,添加一个扩展函数。
    
    @class WBTabBar;
    
    @protocol WBTabBarDelegate <UITabBarDelegate>
    
    @optional
    - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar;
    
    @end
    
    @interface WBTabBar : UITabBar
    
    @property (nonatomic, weak) id<WBTabBarDelegate> tabBarDelegate;
    
    @end
    

    6、在加号按钮的点击事件处理器中,通知代理
    #pragma mark 加号按钮点击事件处理器
    - (void)plusClick
    {
        // 通知代理
        if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
            [self.tabBarDelegate tabBarDidClickPlusButton:self];
        }
    }

    7、在WBTabBarController中设置WBTabBar的代理,具体实现如下:

     // 2、使用KVC的方式,更换系统自带的UITabBar
        WBTabBar *tabBar = [[WBTabBar alloc] init];
        tabBar.tabBarDelegate = self;
        [self setValue:tabBar forKeyPath:@"tabBar"];

    #pragma mark - HWTabBarDelegate代理方法
    - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar
    {
        ComposeViewController *composeViewController= [[ComposeViewController alloc] init];
        UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:composeViewController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }

    8、有图有真相,已实现的效果图如下:



    点击加号按钮,弹出写作界面,效果图如下:


    WBTabBarController.m文件完整源码如下:

    //
    //  WBTabBarController.m
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/17.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import "WBTabBarController.h"
    #import "HomeViewController.h"
    #import "MessageViewController.h"
    #import "DiscoverViewController.h"
    #import "ProfileViewController.h"
    #import "WBNavigationController.h"
    #import "WBTabBar.h"
    #import "ComposeViewController.h"
    
    @interface WBTabBarController ()<WBTabBarDelegate>
    {
        HomeViewController * _homeViewController;
        MessageViewController * _messageViewController;
        DiscoverViewController * _discoverViewController;
        ProfileViewController * _profileViewController;
    }
    @end
    
    @implementation WBTabBarController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 初始化子控制器,并将其添加到UITabBarController中
        _homeViewController = [[HomeViewController alloc]init];
        [self addChildController:_homeViewController title:@"首页" image:@"tabbar_home"];
        
        _messageViewController = [[MessageViewController alloc]init];
        [self addChildController:_messageViewController title:@"消息" image:@"tabbar_message_center"];
        
        _discoverViewController = [[DiscoverViewController alloc]init];
        [self addChildController:_discoverViewController title:@"发现" image:@"tabbar_discover"];
        
        _profileViewController = [[ProfileViewController alloc]init];
        [self addChildController:_profileViewController title:@"我" image:@"tabbar_profile"];
        
        // @property(nonatomic,readonly) UITabBar *tabBar NS_AVAILABLE_IOS(3_0);
        // tabBar是UITabBarController的只读成员变量(属性),是不让修改的
        
        // 2、使用KVC的方式,更换系统自带的UITabBar
        WBTabBar *tabBar = [[WBTabBar alloc] init];
        tabBar.tabBarDelegate = self;
        [self setValue:tabBar forKeyPath:@"tabBar"];
        
    }
    
    #pragma mark - HWTabBarDelegate代理方法
    - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar
    {
        ComposeViewController *composeViewController= [[ComposeViewController alloc] init];
        UINavigationController * navigationController = [[UINavigationController alloc]initWithRootViewController:composeViewController];
        [self presentViewController:navigationController animated:YES completion:nil];
    }
    
    /**
     * 添加子控制器到UITabBarController中
     */
    - (void)addChildController:(UIViewController *)childViewController title:(NSString *)title image:(NSString *)image
    {
        // 设置子控制器,tabbar和navigationBar上的title
        childViewController.title = title;
        
        // 设置tabBarItem上默认的指示图片和选中时的图片
        childViewController.tabBarItem.image = [UIImage imageNamed:image];
        childViewController.tabBarItem.selectedImage = [[UIImage imageNamed:[NSString stringWithFormat:@"%@%@", image, @"_selected"]]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
        
        // 设置tabBarItem上文字的样式(这里是设置文字在不同状态下的颜色值)
        [childViewController.tabBarItem setTitleTextAttributes:
         @{NSForegroundColorAttributeName:kColor(117, 117, 117)} forState:UIControlStateNormal];
        [childViewController.tabBarItem setTitleTextAttributes:
         @{NSForegroundColorAttributeName:kColor(253, 109, 10)} forState:UIControlStateSelected];
        
        // 使用系统默认的UINavigationController
    //    [self addChildViewController:[[UINavigationController alloc] initWithRootViewController:childViewController]];
        
        // 使用我们自定义的导航栏(WBNavigationController继承自UINavigationController)
        WBNavigationController * navigationController = [[WBNavigationController alloc]initWithRootViewController:childViewController];
        [self addChildViewController:navigationController];
    }
    
    @end
    

    WBTabBar.h文件完整源码如下:

    //
    //  WBTabBar.h
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/21.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    #pragma mark 因为在UITabBar中已经声明过一个UITabBarDelegate协议,
    #pragma mark 我们若想新增一个对外的代理函数,可以让我们自定义的协议继承自UITabBarDelegate,添加一个扩展函数。
    
    @class WBTabBar;
    
    @protocol WBTabBarDelegate <UITabBarDelegate>
    
    @optional
    - (void)tabBarDidClickPlusButton:(WBTabBar *)tabBar;
    
    @end
    
    @interface WBTabBar : UITabBar
    
    @property (nonatomic, weak) id<WBTabBarDelegate> tabBarDelegate;
    
    @end
    

    WBTabBar.m文件完整源码如下:

    //
    //  WBTabBar.m
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/21.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import "WBTabBar.h"
    
    @interface WBTabBar()
    @property (nonatomic, weak) UIButton *plusBtn;
    @end
    
    @implementation WBTabBar
    
    - (id)initWithFrame:(CGRect)frame
    {
        self = [super initWithFrame:frame];
        if (self) {
            // 添加一个按钮到tabbar中
            UIButton *plusBtn = [[UIButton alloc] init];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
            [plusBtn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_background_icon_add"] forState:UIControlStateNormal];
            [plusBtn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted];
            plusBtn.size = plusBtn.currentBackgroundImage.size;
            [plusBtn addTarget:self action:@selector(plusClick) forControlEvents:UIControlEventTouchUpInside];
            [self addSubview:plusBtn];
            self.plusBtn = plusBtn;
        }
        return self;
    }
    
    #pragma mark 加号按钮点击事件处理器
    - (void)plusClick
    {
        // 通知代理
        if ([self.tabBarDelegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
            [self.tabBarDelegate tabBarDidClickPlusButton:self];
        }
    }
    
    - (void)layoutSubviews
    {
        [super layoutSubviews];
        
        // 1.设置加号按钮的位置
        self.plusBtn.centerX = self.width * 0.5;
        self.plusBtn.centerY = self.height * 0.5;
        
        // 2.设置其它UITabBarButton的位置和尺寸
        CGFloat tabbarButtonW = self.width / 5;
        CGFloat tabbarButtonIndex = 0;
        for (UIView *child in self.subviews) {
            Class class = NSClassFromString(@"UITabBarButton");
            if ([child isKindOfClass:class]) {
                // 设置宽度
                child.width = tabbarButtonW;
                // 设置x
                child.x = tabbarButtonIndex * tabbarButtonW;
                
                // 增加索引
                tabbarButtonIndex++;
                if (tabbarButtonIndex == 2) {
                    tabbarButtonIndex++;
                }
            }
        }
    }
    
    @end
    

    ComposeViewController继承自UIViewController,主要实现在m文件,其完整代码如下:

    //
    //  ComposeViewController.m
    //  SinaWeibo
    //
    //  Created by android_ls on 15/5/21.
    //  Copyright (c) 2015年 android_ls. All rights reserved.
    //
    
    #import "ComposeViewController.h"
    #import "UIBarButtonItem+Category.h"
    
    @interface ComposeViewController ()
    
    @end
    
    @implementation ComposeViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.title = @"写作界面";
        self.view.backgroundColor = [UIColor whiteColor];
        
        self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self
                                action:@selector(back)
                                image:@"navigationbar_back_withtext"
                                highImage:@"navigationbar_back_withtext_highlighted"
                                title:@"返回"];
    
    }
    
    - (void)back
    {
        [self.navigationController dismissViewControllerAnimated:YES completion:^{}];
    }
    
    @end
  • 相关阅读:
    换一个角度看问题:火柴棒等式
    队列之blah集合
    专题——极值定理及应用
    专题——计数原理
    Antiprime数-数论
    Openjudge-NOI题库-旅行-数论
    砝码设计-数论
    有理数分解-数论
    洛谷-神奇的幻方-NOIP2015提高组复赛
    NOIP2014-提高组初赛C语言解析(选择填空题)
  • 原文地址:https://www.cnblogs.com/yuqingzhude/p/4836523.html
Copyright © 2011-2022 走看看