作者 sundays http://www.cnblogs.com/sundaysgarden/

OC中UITabbar的适配[iphoneX和Ipad适配]

自定可以UITabar

自定义UITabar头文件

#import <UIKit/UIKit.h>

@interface MCTabBar : UITabBar

@property (nonatomic, strong) UIButton *centerBtn; //中间按钮

@end

自定义UITabar m文件

#import "GBArcView.h"

//#import ""

#define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width

#define GBVIEWSCALL 1.2

#define CENTERBUTTONSCALL 1.1

@interface MCTabBar ()

@property (nonatomic,strong) GBArcView *gbview; //半圆View

@property(assign,nonatomic)int index;//UITabBar子view的索引

@end

@implementation MCTabBar

//重新初始化方法,从stroyboard 中加载,会调用

-(instancetype)initWithCoder:(NSCoder *)aDecoder{

if (self = [super initWithCoder:aDecoder]) {

self.backgroundColor=[UIColor whiteColor];

self.clipsToBounds=NO;//不裁剪子控件

self.selectedItem=0;//初始化索引

//设置tabBaritem 的文字颜色

//        [[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:RGB_COLOR(74, 74, 74), UITextAttributeTextColor, nil] forState:UIControlStateNormal];

//

//        [[UITabBarItem appearance] setTitleTextAttributes:                                                         [NSDictionary dictionaryWithObjectsAndKeys:RGB_COLOR(0, 147, 197),UITextAttributeTextColor, nil]forState:UIControlStateSelected];

}

return self;

}

- (instancetype)initWithFrame:(CGRect)frame{

if (self = [super initWithFrame:frame]){

[self initView];

}

return self;

}

- (void)initView{

[self addSubview:_centerBtn];

[self insertSubview:_gbview belowSubview:_centerBtn];

}

//处理超出区域点击无效的问题

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{

if (self.hidden){

return [super hitTest:point withEvent:event];

}else {

//转换坐标

CGPoint tempPoint = [self.centerBtn convertPoint:point fromView:self];

//判断点击的点是否在按钮区域内

if (CGRectContainsPoint(self.centerBtn.bounds, tempPoint)){

_centerBtn.selected = YES;

//返回按钮

return _centerBtn;

}else {

_centerBtn.selected = NO;

//            __weak __typeof(&*self)weakSelf =self;

return [super hitTest:point withEvent:event];

}

}

}

//绘制横线

- (void)drawRect:(CGRect)rect {

//中间的按钮宽度是UItabBar的高度,其他按钮的宽度就是,(self.width-self.height)/4.0

CGFloat buttonW = (self.width-self.height)/4.0;

CGContextRef context = UIGraphicsGetCurrentContext();

CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:200/255.0 green:200/255.0 blue:200/255.0 alpha:0.8].CGColor);

CGContextSetLineWidth(context, SINGLE_LINE_WIDTH + 2.0f);

//    CGContextSetLineWidth(context, 5);

CGContextBeginPath(context);

CGFloat lineMargin =0;

//1PX线,像素偏移

CGFloat pixelAdjustOffset = 0;

if (((int)(1 * [UIScreen mainScreen].scale) + 1) % 2 == 0) {

pixelAdjustOffset = SINGLE_LINE_ADJUST_OFFSET;

}

CGFloat yPos = lineMargin - pixelAdjustOffset;

//第一段线

CGContextMoveToPoint(context, 0, yPos);

CGContextAddLineToPoint(context, buttonW*2+SINGLE_LINE_WIDTH*2, yPos);

CGContextStrokePath(context);

//第二段线

CGContextMoveToPoint(context, buttonW*2+self.frame.size.height-SINGLE_LINE_WIDTH*2, yPos);

CGContextAddLineToPoint(context, self.bounds.size.width, yPos);

CGContextSetStrokeColorWithColor(context, [UIColor colorWithRed:200/255.0 green:200/255.0 blue:200/255.0 alpha:0.8].CGColor);

CGContextStrokePath(context);

}

//自定义按钮的懒加载

-(UIButton *)centerBtn{

if(!_centerBtn){

_centerBtn = [UIButton buttonWithType:UIButtonTypeCustom];

//  设定button大小为适应图片

UIImage *normalImage = [UIImage imageNamed:@"3_gray"];

_centerBtn.frame = CGRectMake(0, 0, normalImage.size.width, normalImage.size.height);

[_centerBtn setImage:normalImage forState:UIControlStateNormal];

UIImage *selectImage  = [UIImage imageNamed:@"3_hover"];

[_centerBtn setImage:selectImage forState:UIControlStateSelected];

//去除选择时高亮

_centerBtn.adjustsImageWhenHighlighted = NO;

//根据图片调整button的位置(图片中心在tabbar的中间最上部,这个时候由于按钮是有一部分超出tabbar的,所以点击无效,要进行处理)

_centerBtn.frame = CGRectMake(([UIScreen mainScreen].bounds.size.width - normalImage.size.width)/2.0, - normalImage.size.height/2.0 + 8, normalImage.size.width, normalImage.size.height);

_centerBtn.transform = CGAffineTransformMakeScale(CENTERBUTTONSCALL, CENTERBUTTONSCALL);

}

return _centerBtn;

}

////自定义半圆View的懒加载

-(UIView *)gbview{

if(!_gbview){

CGFloat buttonW = self.centerBtn.width;

GBArcView *gbview = [[GBArcView alloc]initWithFrame:CGRectMake(0,0,buttonW *GBVIEWSCALL,buttonW*GBVIEWSCALL)];

gbview.backgroundColor=[UIColor whiteColor];

gbview.layer.masksToBounds=YES;

gbview.layer.cornerRadius=buttonW*GBVIEWSCALL*0.5f;

gbview.center = _centerBtn.center;

gbview.transform = CGAffineTransformMakeScale(GBVIEWSCALL, GBVIEWSCALL);

_gbview = gbview;

}

return _gbview;

}

-(void)setHidden:(BOOL)hidden{

[super setHidden:hidden];

//手动设置UITabBar 隐藏时,我们要将自定义的按钮和背景隐藏

[self.gbview setHidden:hidden];

[self.centerBtn setHidden:hidden];

}

//******核心部分******

//当配置  hidesBottomBarWhenPushed 的viewController ,隐藏UITabBar时,会改变其frame,就是将UITabBar 的Y值设为屏幕最大的y值,就不可见。我们重写这个方法,判断当frame的y小于屏幕的高度 ,那么UITabBar就是被隐藏了,这时候我们将自定的控件隐藏。相反的,我们就显示我们的自定义控件。

-(void)setFrame:(CGRect)frame{

//    if (self.superview &&CGRectGetMaxY(self.superview.bounds) !=CGRectGetMaxY(frame)) {

//        frame.origin.y =CGRectGetHeight(self.superview.bounds) -CGRectGetHeight(frame);

//    }

[super setFrame:frame];

if(frame.origin.y>=[UIScreen mainScreen].bounds.size.height){

[self.gbview setHidden:YES];

[self.centerBtn setHidden:YES];

}else{

[self.gbview setHidden:NO];

[self.centerBtn setHidden:NO];

}

}

//适配ipad

//重写traitCollection方法,使UITabbar保持图为垂直排列,防止在ipad11出现水平排列

- (UITraitCollection *)traitCollection {

if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) {

return [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassCompact];

}

return [super traitCollection];

}

@end

在UITabBarController.m文件中设置适配iPhoneX

//利用KVC 将自己的tabbar赋给系统tabBar

ViewDidLoad方法添加如下代码

  //利用kvc将自定义的文件copy给系统

[self setValue:_mcTabbar forKeyPath:@"tabBar"];

  给系统的[自定义]的UITabBar添加一个View设置UITabBar的高度

[self setupTabBar];

- (void)setupTabBar{

//删除现有的tabBar

CGRect rect = self.tabBar.frame;

[self.tabBar removeFromSuperview];  //移除TabBarController自带的下部的条

//    [self.tabBarController.tabBar removeFromSuperview];

rect.size.height = 49;

rect.origin.y = [UIScreen mainScreen].bounds.size.height - 49;

UIView *myView = [[UIView alloc] init];

myView.frame = rect;

myView.backgroundColor = [UIColor whiteColor];

[self.view addSubview:myView];

}

自定义UItabBar中引用的文件

GBArcView.h

#define SINGLE_LINE_WIDTH           (1 / [UIScreen mainScreen].scale)

#define SINGLE_LINE_ADJUST_OFFSET   ((1 / [UIScreen mainScreen].scale) / 2)

@interface GBArcView : UIView

@end

GBArch.m

#import <QuartzCore/QuartzCore.h>

#import "Math.h"

#import <CoreGraphics/CoreGraphics.h>

@implementation GBArcView

- (void)drawRect:(CGRect)rect {

CGContextRef context = UIGraphicsGetCurrentContext();

UIColor *color1 = [UIColor colorWithRed:200/255.0 green:200/255.0 blue:200/255.0 alpha:0.8];

CGContextSetStrokeColorWithColor(context, color1.CGColor);

CGContextSetLineWidth(context, SINGLE_LINE_WIDTH + 0.5f);

CGContextBeginPath(context);

//    CGFloat lineMargin =self.frame.size.width*0.5f;

//1px线,偏移像素点

CGFloat pixelAdjustOffset = 0;

if (((int)(1 * [UIScreen mainScreen].scale) + 1) % 2 == 0) {

pixelAdjustOffset = SINGLE_LINE_ADJUST_OFFSET;

}

CGFloat yPos = self.frame.size.width*0.5f - pixelAdjustOffset;

CGFloat xPos = self.frame.size.width*0.5f - pixelAdjustOffset - 4.0f;

CGContextAddArc(context, xPos, yPos, self.frame.size.width*0.5 - 1.f , M_PI*1.08, M_PI*1.95, 0);

CGContextDrawPath(context, kCGPathStroke);

//    CGContextStrokePath(context);

}

@end

适配IPhoneX

定义UITabar的分类实现适配

OC和Swift中的UITabBar和UINaviGationBar的适配 [UITabbar在IPad中的适配]的更多相关文章

  1. iOS开发之OC与swift开发混编教程,代理的相互调用,block的实现。OC调用Swift中的代理, OC调用Swift中的Block 闭包

    本文章将从两个方向分别介绍 OC 与 swift 混编 1. 第一个方向从 swift工程 中引入 oc类 1. 1 如何在swift的类中使用oc类    1.2  如何在swift中实现oc的代理 ...

  2. oc工程中oc、swift混编代码打包成静态framework踩坑笔记

    参考资料: https://www.jianshu.com/p/734341f7c242 https://www.jianshu.com/p/55038871e7de   两天时间探索,期间不知道遇到 ...

  3. iOS代码规范(OC和Swift)

    下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...

  4. IOS --- OC与Swift混编

    swift 语言出来后,可能新的项目直接使用swift来开发,但可能在过程中会遇到一些情况,某些已用OC写好的类或封装好的模块,不想再在swift 中再写一次,哪就使用混编.这个在IOS8中是允许的. ...

  5. iOS OC和Swift进行互相调用

    有时候 ,我们会涉及到双向混合编程,特别是OC和swift的互相引用. swift调用oc的方法: 1.桥接文件,一般是swift工程,在创建一个oc文件时,系统自动添加(不用改名,直接默认即可) 2 ...

  6. 关于C、OC、C++、OC++、Swift的一些常识

    关于C.OC.C++.OC++.Swift的一些常识 OC是C语言的一个超集,是一门面向对象的语言,因为苹果的崛起而火,API主要是cocoa(OSX)和cocoatouch(iOS),GCC 和 C ...

  7. iOS - OC 与 Swift 互相操作

    前言 在 Swift 语言中,我们可以使用 Objective-C.C 语言编写代码,我们可以导入任意用 Objective-C 写的 Cocoa 平台框架.Objective-C 框架或 C 类库. ...

  8. Swift语言学习之OC和Swift混编

    本文转自http://www.helloswift.com.cn/swiftbase/2015/0112/3469.html iOS OC和Swift混编 1.创建一个swift或者oc的工程:我这里 ...

  9. 【转】IOS --- OC与Swift混编

    群里大神发的网址,感觉有用就先收录了,暂时没时间看SWIFT,感觉代码简洁,但是可阅读性不是太高,有些代码让系统去判断类型,同样的,我们看代码的时候也得自己去判断类型,或许看多就习惯了,有时间再说吧, ...

随机推荐

  1. 高德地图SDK使用经验

    下文说的是高德地图 Android SDK版本,详细版本如下: 2D地图:v2.3.1 定位:v1.3.0 导航:v1.1.1 发现的问题如下,其中一些疑是地图BUG,一些是需要你自己小心的地方: 1 ...

  2. WebStorm开发工具设置React Native智能提示

    最近在做React Native开发的时候,相信大家一般会使用WebStorm,Sublime,Atom等等开发工具.二之前搞前端的对WebStorm会很熟悉,WebStorm最新版是WebStorm ...

  3. 《java入门第一季》之面向对象(内部类到底在哪里?)

    /* 内部类概述: 把类定义在其他类的内部,这个类就被称为内部类. 举例:在类A中定义了一个类B,类B就是内部类. 内部的访问特点: A:内部类可以直接访问外部类的成员,包括私有. B:外部类要访问内 ...

  4. Java集合之Set

    Set也是继承自Collection,Set也是集合的一种,同时Set不允许重复的元素存在.Set的实现类都是基于Map来实现的,其中HashSet是通过HashMap来实现的,TreeSet是通过T ...

  5. AngularJS进阶(十九)在AngularJS应用中集成百度地图实现定位功能

    在AngularJS应用中集成百度地图实现定位功能 注:请点击此处进行充电! 前言 根据项目需求,需要实现手机定位功能,考虑到百度业务的强大能力,遂决定使用百度地图第三方服务. 添加第三方模块的步骤与 ...

  6. 【数值分析】误差的分析与减少及Matlab解线性方程的四种方法

    1.误差的来源 模型误差:数学模型与实际问题之间的误差 观测误差:测量数据与实际数据的误差 方法误差:数学模型的精确解与数值方法得到的数值解之间的误差:例如 舍入误差:对数据进行四舍五入后产生的误差 ...

  7. Linux常用命令(第二版) --网络通信命令

    网络通信命令 1.write /usr/bin/write 格式: write [用户名] #用于向用户发送信息,前提是这个用户已经登录到了这台服务器主机,不然的话,也没有办法给他留言,所以,writ ...

  8. Gradle 1.12用户指南翻译——第三十四章. JaCoCo 插件

    本文由CSDN博客万一博主翻译,其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Githu ...

  9. OpenCV——老照片效果

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  10. 如何在shell脚本中判断文件或者文件夹是否存在?

    1:查找文件夹 如果文件夹存在,则打印一句存在,否则打印不存在 这里的话可以自由加一些指令. if [ test -d 文件夹名称 ] ; then echo "文件夹存在!" e ...