自定义放大 TabBar

作者: 见哥哥长高了 | 来源:发表于2018-09-13 17:36 被阅读9次

    下面是效果图:


    效果图

    要实现上面的效果方法有好多种,今天我们用原生的UITabBar来做。
    注:这里有一个很小的知识点需要注意一下就是UITabBarItem 是UIBarItem 的子类,直接继承自其。理解这个有助于更好的理解具体实现。
    其实实现起来的大致步骤为:
    一、item突出显示(偏移)
    二、item手势响应处理

    item突出显示(偏移)

    第一步很简单。创建一个UITabBarController并添加子控制器。

    .h
    @interface TabbarVC : UITabBarController
    
    @end
    
    .m
    -(void)addControllers{
        OneVC *one = [[OneVC alloc]init];
        UINavigationController *navOne = [[UINavigationController alloc]initWithRootViewController:one];
        navOne.tabBarItem = [self getTabBarItemWithTitle:@"第一个" image:[UIImage imageNamed:@"动态"] selectImage:[UIImage imageNamed:@"动态hober"] tag:1];
        
        TwoVC *two = [[TwoVC alloc]init];
        UINavigationController *navTwo = [[UINavigationController alloc]initWithRootViewController:two];
        navTwo.tabBarItem = [self getTabBarItemWithTitle:@"第二个" image:[UIImage imageNamed:@"我的"] selectImage:[UIImage imageNamed:@"我的hover"] tag:2];
        
        ThreeVC *three = [[ThreeVC alloc]init];
        UINavigationController *navThree = [[UINavigationController alloc]initWithRootViewController:three];
        navThree.tabBarItem = [self getTabBarItemWithTitle:@"第三个" image:[UIImage imageNamed:@"展示"] selectImage:[UIImage imageNamed:@"展示hover"] tag:3];
    
        
        FourVC *four = [[FourVC alloc]init];
        UINavigationController *navFour = [[UINavigationController alloc]initWithRootViewController:four];
        navFour.tabBarItem = [self getTabBarItemWithTitle:@"第四个" image:[UIImage imageNamed:@"训练"] selectImage:[UIImage imageNamed:@"训练hover"] tag:4];
        
        FiveVC *five = [[FiveVC alloc]init];
        UINavigationController *navFive = [[UINavigationController alloc]initWithRootViewController:five];
        navFive.tabBarItem = [self getTabBarItemWithTitle:@"第四个" image:[UIImage imageNamed:@"收藏灰"] selectImage:[UIImage imageNamed:@"收藏"] tag:5];
        self.viewControllers = @[navOne,navTwo,navThree,navFour,navFive];
    }
    
    -(UITabBarItem *)getTabBarItemWithTitle:(NSString *)title image:(UIImage *)image selectImage:(UIImage *)selectImage tag:(NSInteger)tag{
        UITabBarItem *item = [[UITabBarItem alloc]initWithTitle:title image:image tag:tag];
        item.selectedImage = selectImage;
        return item;
    }
    

    紧接着我们实现UITabBarController 的viewWillLayoutSubviews方法,获取到自己的tabBar上的指定UITabBarItem ,然后拿到UITabBarItem上的imageView视图,设置偏移量,并添加点击事件,做出响应事件的处理。

    -(void)viewWillLayoutSubviews{
        [super viewWillLayoutSubviews];
        
        UITabBarItem *tabbarItem = self.tabBar.items[2];
        tabbarItem.imageInsets = UIEdgeInsetsMake(-25, 0, 0, 0);
        
        UIImageView *imageView = [tabbarItem lgj_imageView];
        if (imageView && !imageView.userInteractionEnabled) {
            imageView.userInteractionEnabled = YES;
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(mittileTap)];
            [imageView addGestureRecognizer:tap];
        }
    }
    
    -(void)mittileTap{
        self.selectedIndex = 2;
    }
    
    item手势响应处理

    接下来创建UIBarItem、UITabBarItem和UITabBar的分类
    UIBarItem+LGJBarItem.h

    #import <UIKit/UIKit.h>
    
    @interface UIBarItem (LGJBarItem)
    
    @property(nonatomic,nullable,weak,readonly)UIView  *lgj_view;
    
    @end
    
    
    #import "UIBarItem+LGJBarItem.h"
    
    @implementation UIBarItem (LGJBarItem)
    
    -(UIView *)lgj_view{
        return [self valueForKey:@"view"];
    }
    
    @end
    
    

    UITabBarItem+LGJBarItem.h

    #import <UIKit/UIKit.h>
    
    @interface UITabBarItem (LGJTabBarItem)
    
    @property(nonatomic, copy) void (^lgj_doubleTapBlock)(UITabBarItem *tabBarItem, NSInteger index);
    
    - (UIImageView *)lgj_imageView;
    
    + (UIImageView *)lgj_imageViewInTabBarButton:(UIView *)tabBarButton;
    
    
    @end
    
    
    #import "UITabBarItem+LGJTabBarItem.h"
    #import "UIBarItem+LGJBarItem.h"
    #import <objc/runtime.h>
    @implementation UITabBarItem (LGJTabBarItem)
    
    
    - (UIImageView *)lgj_imageView {
        return [self.class lgj_imageViewInTabBarButton:self.lgj_view];
    }
    
    + (UIImageView *)lgj_imageViewInTabBarButton:(UIView *)tabBarButton {
        if (!tabBarButton ) {
            return nil;
        }
        for (UIView *subView in tabBarButton.subviews) {
            if ([NSStringFromClass([subView class]) isEqualToString:@"UITabBarSwappableImageView"]) {
                return (UIImageView *)subView;
            }
            NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
            CFShow(CFBridgingRetain(infoDictionary));
            NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"];
            float version = [app_Version floatValue];
            
            if (version < 10) {
                // iOS10以前,选中的item的高亮是用UITabBarSelectionIndicatorView实现的,所以要屏蔽掉
                if ([subView isKindOfClass:[UIImageView class]] && ![NSStringFromClass([subView class]) isEqualToString:@"UITabBarSelectionIndicatorView"]) {
                    return (UIImageView *)subView;
                }
    
            }
        }
        return nil;
    }
    
    
    static char kAssociatedObjectKey_doubleTapBlock;
    
    - (void)setLgj_doubleTapBlock:(void (^)(UITabBarItem *, NSInteger))gs_doubleTapBlock {
        objc_setAssociatedObject(self, &kAssociatedObjectKey_doubleTapBlock, gs_doubleTapBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);
    }
    
    - (void (^)(UITabBarItem *, NSInteger))lgj_doubleTapBlock {
        return (void (^)(UITabBarItem *, NSInteger))objc_getAssociatedObject(self, &kAssociatedObjectKey_doubleTapBlock);
    }
    
    
    @end
    

    UITabBar+LGJBarItem.h

    #import <UIKit/UIKit.h>
    
    @interface UITabBar (LGJTabBar)
    
    @end
    
    
    #import "UITabBar+LGJTabBar.h"
    #import "UITabBarItem+LGJTabBarItem.h"
    @implementation UITabBar (LGJTabBar)
    
    - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
        if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) {
            return nil;
            
        }
        if (self.items.count < 2) {
            return [super hitTest:point withEvent:event];
            
        }
        UITabBarItem *item = self.items[2];
        UIImageView *itemImageView = [item lgj_imageView];
        if (!itemImageView) {
            return [super hitTest:point withEvent:event];
            
        }
        UIView *view = [super hitTest:point withEvent:event];
        if (view == nil){
            //转换坐标
            CGPoint tempPoint = [itemImageView convertPoint:point fromView:self];
            //判断点击的点是否在按钮区域内
            if (CGRectContainsPoint(itemImageView.bounds, tempPoint)){ //返回按钮
                return itemImageView;
                
            }
            //****************** 或者使用这个方法 ****************
            //判断如果这个新的点是在发布按钮身上,那么处理点击事件最合适的view就是发布按钮
            if ([itemImageView pointInside:point withEvent:event]) {
                return itemImageView;
                
            }else{
                //如果点不在发布按钮身上,直接让系统处理就可以了
                return [super hitTest:point withEvent:event];
            }
        }
        return view;
    }
    
    @end
    

    以上工作完成,一个突出的TabBar就出现了,,,,

    相关文章

      网友评论

        本文标题:自定义放大 TabBar

        本文链接:https://www.haomeiwen.com/subject/nsqggftx.html