优雅快速的搭建一个IOS项目,让你的项目结构不再混乱!(纯代码)

git地址:https://github.com/guhaibo312/HBFrame.git

首先:新建项目,删除没用的文件(Main.storyboard,ViewController),并配置启动项(Main Interface):

既然修改了启动项不使用storyboard,当然就要设置window和window的根控制器。这里我们使用继承了UITabBarController的MainTabBarController作为根控制器

AppDelegate中


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.rootViewController = [[MainTabBarController alloc] init];
    [self.window makeKeyAndVisible];
    return YES;
}


下面我们来看一些自定义的MainTabBarController

(分为2部分)

  • 添加子控制器

这里我们抽出添加子控制器的方法。(将子控制器包装在 继承自UINavigationController 的 MainNavigationController中)


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    UIViewController *homeController = [[UIViewController alloc] init];
    [self addChildController:homeController title:@"首页" iconNormal:@"icon_tab_a2_normal" iconSelected:@"icon_tab_a2_selected"];
    
    UIViewController *circleVc = [[UIViewController alloc] init];
    [self addChildController:circleVc title:@"圈子" iconNormal:@"icon_tab_a1_normal" iconSelected:@"icon_tab_a1_selected"];
    
    UIViewController *nearbyVc = [[UIViewController alloc] init];
    [self addChildController:nearbyVc title:@"附近" iconNormal:@"icon_tab_a3_normal" iconSelected:@"icon_tab_a3_selected"];
    
    UIViewController *mineVc = [[UIViewController alloc] init];
    [self addChildController:mineVc title:@"我的" iconNormal:@"icon_tab_w4_normal" iconSelected:@"icon_tab_w4_selected"];
}

- (void) addChildController : (UIViewController *) viewController title : (NSString *) title iconNormal : (NSString *) iconNormal iconSelected : (NSString *) iconSelected
{
    viewController.view.backgroundColor = HBRandomColor; //添加背景色(随机色)
    viewController.title = title;
    viewController.tabBarItem.image = [UIImage imageNamed:iconNormal];
    UIImage *selectedImage = [UIImage imageNamed:iconSelected];
    // 声明:这张图片按照原始的样子显示出来,不要渲染成其他的颜色(比如说默认的蓝色)
    selectedImage = [selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    viewController.tabBarItem.selectedImage = selectedImage;
    [self addChildViewController:[[MainNavigationController alloc] initWithRootViewController:viewController]];
}

@end


这里我给控制器添加了一个随机的背景色,说到这里就说一下PCH文件的添加。

首先:新建一个PCH文件,然后添加上宏

#define HBRGB(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0]
#define HBRandomColor HBRGB(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)) //随机色

#define RGBCOLOR_HEX(hexColor) [UIColor colorWithRed: (((hexColor >> 16) & 0xFF))/255.0f         \
green: (((hexColor >> 8) & 0xFF))/255.0f          \
blue: ((hexColor & 0xFF))/255.0f                 \
alpha: 1]
#define GRAYTEXTCOLOR RGBCOLOR_HEX(0x7b7b7b)
#define ButtonNormalColor RGBCOLOR_HEX(0x67d2ca)

//屏幕高
#define SCREENHEIGHT [UIScreen mainScreen].bounds.size.height
//屏幕宽
#define SCREENWIDTH [UIScreen mainScreen].bounds.size.width

然后配置一下PCH文件:点击项目名->Build Settings->搜索"prefix header"->双击prefix header右侧 出现输入框,在项目中找到PCH文件 直接拖入 即可生成路径->commend + B 编译 就可以用了。

tmp7550ef43.png
  • 替换系统的tabbar 在中间添加一个圆形的button
    方案:自定义MainTabBarView 继承UITabBar,重写layoutSubviews方法将原来的按钮向左向右移动留出中间的空间区域 用于添加按钮。 之后只用KVC直接替换系统tabBar
.h文件

#import <UIKit/UIKit.h>
@class MainTabBarView;

@protocol MainTabBarViewDelegate <NSObject>

- (void) mainTabBarViewDidClick : (MainTabBarView *)hBTabBarView;


@end

@interface MainTabBarView : UITabBar

@property(nonatomic,weak) id<MainTabBarViewDelegate> tabbarDelegate;

@end
.m文件

@interface MainTabBarView()

@property (nonatomic,strong) UIButton *addButton;

@end

@implementation MainTabBarView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.addButton = [[UIButton alloc] init];
        [self.addButton setImage:[UIImage imageNamed:@"icon_add_tag"] forState:UIControlStateNormal];
        [self.addButton addTarget:self action:@selector(addClick) forControlEvents:UIControlEventTouchUpInside];
        [self addSubview:self.addButton];
        
    }
    return self;
}

- (void)layoutSubviews
{
    [super layoutSubviews];
    
    CGFloat buttonW = SCREENWIDTH * 0.2;
    for (int i = 0; i < self.subviews.count; i ++) {
        UIView *view = self.subviews[i];
        if ([view isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
            view.width = buttonW;
            view.height = self.height;
            view.y = 0;
            if (i < 4) {
                view.x = (i - 2) * buttonW;
            }else
            {
                view.x = (i - 1) * buttonW;
            }
        }
    }
    
    self.addButton.width = buttonW;
    self.addButton.height = self.height;
    self.addButton.y = 0;
    self.addButton.x = 2 * buttonW;
}

- (void)addClick
{
    if ([self.tabbarDelegate respondsToSelector:@selector(mainTabBarViewDidClick:)]) {
        [self.tabbarDelegate mainTabBarViewDidClick:self];
    }
}

中间按钮点击事件传给控制器。

回到MainTabBarController

中 使用KVC替换tabbar 并且设置tabbar代理

    int i = 1; //0系统tabbar  1自定义tabbar
    if (i == 1) {
        MainTabBarView *tabBar = [[MainTabBarView alloc] init];
        tabBar.tabbarDelegate = self;
        [self setValue:tabBar forKeyPath:@"tabBar"]; //KVC直接修改系统tabbar
    }

下面进入UINavigationController 导航控制器

总共分为2个部分

  • 设置全局主题(将代码写在initialize方法中) 这里做统一设置。

//APP生命周期中 只会执行一次
+ (void)initialize
{
    //导航栏主题 title文字属性
    UINavigationBar *navBar = [UINavigationBar appearance];
    [navBar setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor orangeColor], NSFontAttributeName : [UIFont systemFontOfSize:16]}];
    
    //导航栏左右文字主题
    UIBarButtonItem *barButtonItem = [UIBarButtonItem appearance];
    [barButtonItem setTitleTextAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:12]} forState:UIControlStateNormal];
    
    //tabBar主题 title文字属性
    UITabBarItem *tabBarItem = [UITabBarItem appearance];
    [tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : GRAYTEXTCOLOR} forState:UIControlStateNormal];
    [tabBarItem setTitleTextAttributes:@{NSForegroundColorAttributeName : ButtonNormalColor} forState:UIControlStateSelected];

}
  • 拦截push请求(在push之前 设置隐藏tabbar 和 添加返回按钮等操作)
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (self.viewControllers.count > 0) {
        viewController.hidesBottomBarWhenPushed = YES; //隐藏tabbar
        
        //添加返回按钮
        viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem setNavigationBarBackGroundImgName:@"icon_back" target:self selector:@selector(back)];
    }
    
    [super pushViewController:viewController animated:animated];
}

- (void)back
{
    [self popViewControllerAnimated:YES];
}

这里用到了2个分类
1.UIBarButtonItem+Extension 添加UIBarButtonItem的分类

+ (instancetype)setNavigationBarBackGroundImgName:(NSString*)imageName target : (UIViewController *)target selector: (SEL)selector
{
    UIButton * rightButton= [UIButton buttonWithType:UIButtonTypeCustom];
    [rightButton setImage:[UIImage imageNamed:imageName] forState:UIControlStateNormal];
    rightButton.size = rightButton.imageView.image.size;
    [rightButton addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside];
    UIBarButtonItem *rightBarBtnItem = [[UIBarButtonItem alloc] initWithCustomView:rightButton];
    return rightBarBtnItem;
}

2.UIView+Extension 快速设置View的x,y, width, height,size等属性

好了,到这里先停一下,把项目的结构修改一下

tmp50d9253e.png

大致的修改了一下,具体的结构要根据业务需求区划分了。

简单的添加一些常用的功能

新建HomeController (在MainTabBarController 中简单的修改即可)

tmp5e390fd7.png
  • 跳转

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"跳转" style:UIBarButtonItemStylePlain target:self action:@selector(push)];

- (void)push
{
    HBText1Controller *text1Vc = [[HBText1Controller alloc] init];
    text1Vc.name = @"你好";
    text1Vc.title = @"标题";
    [self.navigationController pushViewController:text1Vc animated:YES];
}

  • 网络请求 AFN

将AFNetworking 拖至3rdParty文件夹下 在HomeController中添加

#import "AFNetworking.h"
    //AFN网络请求
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    
    NSMutableDictionary *param = [NSMutableDictionary dictionary];
    param[@"phonenum"] = @"13500000000";
    param[@"password"] = @"123456";
    
    [manager POST:@"http://123.57.42.13/WenShen/V3.0.0/User/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
        HBLog(@"%@",responseObject);//返回的JSON
        
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];

这里的HBLog是一个宏,需要在PCH文件中配置 只有在开发阶段才会打印log 正式上线是不会打印log的

#ifdef DEBUG // 处于开发阶段
#define HBLog(...) NSLog(__VA_ARGS__)
#else // 出去发布阶段
#define HBLog(...)
#endif

  • 既然接到返回值了,接下来就是解析json 使用MJExtension 同样的将MJExtension 拖至3rdParty文件夹下 OK来看看怎么用

1.首先要有一个model (model不是乱建的,根据返回的数据格式 和 你所需要用到的数据 创建的)

tmp6532f8f4.png

注意 只需要在.h文件中创建属性,.m文件什么都不用写!

tmp7bd2f224.png

OK 回到HomeController中 将MJExtension 拖至3rdParty文件夹下

#import "HBUser.h"
#import "MBProgressHUD+MJ.h"
#import "MJExtension.h"

回调的代码改为
[manager POST:@"http://123.57.42.13/WenShen/V3.0.0/User/login" parameters:param success:^(AFHTTPRequestOperation *operation, id responseObject) {
        HBLog(@"%@",responseObject);//返回的JSON
        
        HBUser *user = [HBUser objectWithKeyValues:responseObject[@"data"][@"userInfo"]];
        //提示信息
        [MBProgressHUD showSuccess:user.area];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        [MBProgressHUD showError:@"失败"];
    }];

HBUser *user = [HBUser objectWithKeyValues:responseObject[@"data"][@"userInfo"]]; 只需要一句代码 就将json解析转成了我们的model! 进入到MJExtension 里面看看我们会发现提供了 (plist,json,字典)转模型,(plist,json,字典)转模型数组。 还是挺强大的。

好了,今天就先到这里,一些你们常用的第三库或者第三方SDK 我就不写在这里了,根据业务需求自己加入就好。如果需要demo的,稍后我会上传,贴上项目地址。

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

推荐阅读更多精彩内容