iOS 简单的App基础框架

自己写了一套简单的App常用的框架样式,就是比较传统的NavigationController+TabBarController结合的这种

效果图:
PageBlurTestGif.gif
大体介绍:

主要是两个容器来盛放子控制器,两个容器分别是UINavigationController 和 UITabBarController,在这两个控制器中,自行设置其子控制器.通过git图上可以看见我们自行简单对他们的更改,主要是两个比较好玩的地方,一个是比较常规的自定义UITabBarItem另一个是设置NavigationBar透明,并且随着TableView滑动改变透明度.这篇主要就是记录一下自定义TabBarItem和设置NavigationBar透明的实现

言归正传:
关于UITabBarController

首先自定义一个继承自UITabBar的类@interface LGJTabBar : UITabBar在.m文件中

- (instancetype)initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    return  self;
}
//布局子控件
- (void)layoutSubviews {
    
    [super layoutSubviews];
    [self setUpAllTabBarButtonsFrame];
}

在复写layoutSubviews这个方法时,设置tabbartabbarButtonFrame将这个过程封装为两个函数:

1:设置每个tabbarButton的frame

/**
 *  设置每个tabbarButton的frame
 *
 *  @param tabBarButton 需要设置的tabbarButton
 *  @param index        tabbarButton的index
 */
- (void)setUpTabBarButtonFrame:(UIView *)tabBarButton atIndex:(int)index {
    CGFloat buttonW = self.width / (self.items.count);
    CGFloat buttonH = self.height;
    
    tabBarButton.width = buttonW;
    tabBarButton.height = buttonH;
    tabBarButton.x = buttonW * index;
    tabBarButton.y = 0;
}

2:设置所有的tabbarButtonFrame, 在函数中 设置index值为0,在tabbar上遍历其子视图,如果找不到UITabBarButton就跳过,在for循环中调用setUpTabBarButtonFrame:(UIView *)tabBarButton atIndex:(int)index方法,将view(也就是tabBarButton)和所在的索引值index传到这个函数中,设置每个tabBarButton的frame;

/**
 *  设置所有的tabbarButtonFrame
 */
- (void)setUpAllTabBarButtonsFrame {
    
    int index = 0;
    
    for (UIView *tabBarButton in self.subviews) {
        if (![tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            continue;
        }
        [self setUpTabBarButtonFrame:tabBarButton atIndex:index];
        index++;
    }
}

然后自定义一个继承自UITabBarController的类@interface LGJTabBarController : UITabBarController在这个控制器中,我们需要做的是创建自定义的tabbar和将子控制器加进来;

1:创建自定义的tabbar

/**
 *  创建自定义tabbar
 */
- (void)addCustomTabBar {
    
    //创建自定义tabbar
    LGJTabBar *customTabBar = [[LGJTabBar alloc] init];
    
    UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 49)];
    backView.backgroundColor = [UIColor whiteColor];
    [customTabBar insertSubview:backView atIndex:0];
    customTabBar.opaque = YES;
    
    //更换系统自带的tabbar
    [self setValue:customTabBar forKeyPath:@"tabBar"];
}

在这个函数中,将backView插入到customTabBar的最底层,作为背景图;然后

//更换系统自带的tabbar
    [self setValue:customTabBar forKeyPath:@"tabBar"];

2:将子控制器加入tabbarController中

- (void)addOneChildViewController:(UIViewController *)childViewController title:(NSString *)title imageName:(NSString *)imageName selectedImageName:(NSString *)selectedImageName {
    
    childViewController.title = title;
    childViewController.tabBarItem.image = [UIImage imageNamed:imageName];
    
    //设置tabbarItem的普通文字颜色
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:100/255.0 green:100/255.0 blue:100/255.0 alpha:1];
    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:10];
    [childViewController.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
    
    //设置tabbarItem的选中文字颜色
    NSMutableDictionary *selectedTextAttrs = [NSMutableDictionary dictionary];
    selectedTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:244/255.0 green:165/255.0 blue:27/255.0 alpha:1];
    [childViewController.tabBarItem setTitleTextAttributes:selectedTextAttrs forState:UIControlStateSelected];
    
    //设置选中的图标
    UIImage *selectedImage = [UIImage imageNamed:selectedImageName];
    //声明这张图用原图(不渲染)
    selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    
    childViewController.tabBarItem.selectedImage = selectedImage;
    
    //添加为tabbar控制器的子控制器
    LGJNavigationController *nav = [[LGJNavigationController alloc] initWithRootViewController:childViewController];
    [self addChildViewController:nav];
}
关于UINavigationController

自定义继承自UINavigationController的类

@interface LGJNavigationController : UINavigationController

在.m文件中:

//只初始化一次
+ (void)initialize {
    
    //设置项目中的item的主题样式
    UIBarButtonItem *item = [UIBarButtonItem appearance];
    
    //Normal
    NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
    textAttrs[NSForegroundColorAttributeName] = [UIColor orangeColor];
    textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:13];
    [item setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
    
    //不可以用状态
    NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionary];
    disableTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:123/255.0 green: 123/255.0 blue:123/255.0 alpha:1];
    disableTextAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:13];
    [item setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
    
}
/**
 *  重写这个方法目的:能够拦截所有push进来的控制器
 *
 *  @param viewController 即将push进来的控制器
 *  @param animated
 */
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
    
    if (self.viewControllers.count > 0) {
        //此时push进来的ViewController是第二个自控制器
        //自动隐藏tabbar
        viewController.hidesBottomBarWhenPushed = YES;
        
        //定义leftBarButtonItem
        viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"nav_back" highImage:@"nil"];
        
    }
    
    /**
     *  调用父类pushViewController, self.viewControllers数组添加对象viewController
     */
    [super pushViewController:viewController animated:animated];
    
}

- (void)back {
    
    /**
     *  这里要用self, 不能用self.navigationViewController 因为self本身就是导航控制器对象, self.navigationViewController是nil
     */
    [self popViewControllerAnimated:YES];
}
在MainViewController中

针对navigationBar透明度随着滑动改变的设置方法

//MARK:-ScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    if (self.tableView.contentOffset.y < 0.1) {
        NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
        textAttrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
        [self.navigationItem.leftBarButtonItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
        
        [self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:@"toumingbeijing"] forBarPosition:UIBarPositionAny barMetrics:UIBarMetricsDefault];
        
    } else {
        
        CGFloat alpha = self.tableView.contentOffset.y / 200.0f > 1.0f?1:self.tableView.contentOffset.y/200.0f;
        [self.navigationController.navigationBar setBackgroundImage:[self getImageWithAlpha:alpha] forBarMetrics:UIBarMetricsDefault];
        
        self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(next) image:@"scan_code_c" highImage:nil];
        
    }
    
}

这个方法是用来根据tableView滑动的contentOffSet.y来设置透明度,需要的参数是根据contentOffSet.y计算出来的alpha值[self getImageWithAlpha:alpha]在这个函数中注释已经写好了_

- (UIImage *)getImageWithAlpha:(CGFloat)alpha {
    
    UIColor *color = [UIColor colorWithRed:251/255.0 green:249/255.0 blue:248/255.0 alpha:alpha];
    //设置需要截取的color"画板"的size大小
    CGSize colorSize = CGSizeMake(1, 1);
    
    //UIGraphicsBeginImageContext()指定获取上下文的"画板"size大小
    UIGraphicsBeginImageContext(colorSize);
    //开始截取
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    
    //用颜色填充当前"画板"
    CGContextSetFillColorWithColor(context, color.CGColor);
    //每个截取到上下文"画板"中填充的frame
    CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
    //得到当前上下文获取到的图片
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    NSLog(@"imgHeight:%f, imgWidth:%f", img.size.height, img.size.width);
    return img;
}

可能大家对于里面两个用到size的地方比较蒙, 这样解释下,在代码注释中说的"画板"就是这个获取到最终的imgCGSize colorSize = CGSizeMake(1, 1);CGContextFillRect(context, CGRectMake(0, 0, 1, 1));这句代码的意思是在这个"画板"上填充进去的颜色.为了更直观 我改变了这两句代码:

//设置需要截取的color"画板"的size大小
    CGSize colorSize = CGSizeMake(50, 50);
//每个截取到上下文模板中填充的frame
    CGContextFillRect(context, CGRectMake(0, 0, 20, 20));

得到的是这样的:


FEFABEE2-F0CF-4723-956B-2F5B0F1AE92E.png

其中红色框就是colorSize,绿框就是代表CGContextFillRect的frame.

总结:

整个简单的小框架大概就这些内容,欢迎大家和我交流,一同进步
demo地址:https://github.com/irembeu/SimpleAppBasicDemo.git

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,952评论 4 60
  • 已到立秋 三亚的天气还似乎未见转凉 初晨锻炼时 看到彩虹便随手一拍
    窥眼阅读 156评论 0 0
  • -01- “XXX在你436天前的朋友圈点了个赞”当我边吃饭边看到这条提醒,默默地,左手放下手机,右手放下筷子,瞬...
    小马不怕过河阅读 2,077评论 2 5
  • 看到“家”这个字时,你的脑海里会浮现怎样的画面? 是结束加班拖着疲惫身躯,推开门奔着床扑倒就再也不想起来的公寓 是...
    doreen_wy阅读 181评论 0 1
  • 头晕,因为感冒的缘故。烦躁,因为大姨妈的缘故。阅兵直播看不了,看重播被打断好几次,最后弃之,睡个午觉被铃声惊起,因...
    丢肚儿阅读 222评论 0 1