项目搭建

1.新建一个微博的项目,去掉屏幕旋转

2.设置屏幕方向-->只有竖向

3.使用代码构建UI,不使用storyboard

4.配置图标AppIcon和LaunchImage

将微博资料的相关素材拉到AppIcon和LaunchImage中,并将除了AppIcon和LaunchImage其它图片也全部拉到images.xcassets中。

项目布局

1、项目分层。为了让在Finder中显示跟Xcode中显示都是分层效果,首先在Finder中建文件目录,再拉到xcode中。

2.添加导航及控制器

思路:

(1)创建一个集成UITabBarController的类作为window的rootViewController

(2)由于中间有一个特殊的+加按钮,需要重写(KVC)导航控制器类来重新布局

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{ //1.创建窗口
self.window=[[UIWindow alloc] init];
self.window.frame=[UIScreen mainScreen].bounds; //2.设置根控制器
self.window.rootViewController=[[UYTabBarViewController alloc] init]; //显示窗口
[self.window makeKeyAndVisible];
return YES;
}

Weibo-Prefix.pch :为了下面方便测试,我们在全局宏命令中定义随机色及RGB颜色

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

UYTabBarViewController:

#import "UYTabBarViewController.h"
#import "UYHomeViewController.h"
#import "UYMessageCenterViewController.h"
#import "UYProfileViewController.h"
#import "UYDiscoverViewController.h"
#import "UYTabBar.h" @interface UYTabBarViewController () @end @implementation UYTabBarViewController - (void)viewDidLoad
{
[super viewDidLoad]; // 1.初始化子控制器
UYHomeViewController *home = [[UYHomeViewController alloc] init];
[self addChildVc:home title:@"首页" image:@"tabbar_home" selectedImage:@"tabbar_home_selected"]; UYMessageCenterViewController *messageCenter = [[UYMessageCenterViewController alloc] init];
[self addChildVc:messageCenter title:@"消息" image:@"tabbar_message_center" selectedImage:@"tabbar_message_center_selected"]; UYDiscoverViewController *discover = [[UYDiscoverViewController alloc] init];
[self addChildVc:discover title:@"发现" image:@"tabbar_discover" selectedImage:@"tabbar_discover_selected"]; UYProfileViewController *profile = [[UYProfileViewController alloc] init];
[self addChildVc:profile title:@"我" image:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"]; // 2.更换系统自带的tabbar,由于tabbar是realonly,因此使用KVC来重写。如果没有特殊的导航布局,去掉这下面这部分代码即可。
// UYTabBar *tabBar = [[UYTabBar alloc] init];
// tabBar.delegate = self;
// [self setValue:tabBar forKeyPath:@"tabBar"];
} /**
* 添加一个子控制器
*
* @param childVc 子控制器
* @param title 标题
* @param image 图片
* @param selectedImage 选中的图片
*/
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 设置子控制器的文字
childVc.title = title; // 同时设置tabbar和navigationBar的文字 // 设置子控制器的图片
childVc.tabBarItem.image = [UIImage imageNamed:image];
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; // 设置文字的样式
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = HWColor(, , );
NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
selectTextAttrs[NSForegroundColorAttributeName] = [UIColor orangeColor];
[childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
[childVc.tabBarItem setTitleTextAttributes:selectTextAttrs forState:UIControlStateSelected]; // 先给外面传进来的小控制器 包装 一个导航控制器
//HWNavigationController *nav = [[HWNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:childVc];
} @end

运行后,效果如下:

从上面的效果可以看到,我们还需要设置顶部导航控制器:

思路:

  1. 每个tab的controller上包装了一个UINavigationController.
  2. 进入非NavigationController的rootViewController的时候,隐藏底部的TabBar
  3. 重写pushViewController方法,当push的时候隐藏TabBar #mark:此方法可以作用与所有的非rootViewController,非常好用

1.创建一个集成UIBarButtonItem的分类,用来创建使用UIButton作为按钮图标的item

#import "UIBarButtonItem+Extension.h"

@implementation UIBarButtonItem (Extension)

+ (instancetype) itemWithImage:(NSString *) imageName hightlightedImage:(NSString *) highlightedImageName target:(id)target selector:(SEL)selector {
UIBarButtonItem *item = [[self alloc] init]; // 创建按钮
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *image = [UIImage imageNamed:imageName];
[button setImage:image forState:UIControlStateNormal];
[button setImage:[UIImage imageNamed:highlightedImageName] forState:UIControlStateHighlighted]; // 一定要设置frame,才能显示
button.frame = CGRectMake(, , image.size.width, image.size.height); // 设置事件
[button addTarget:target action:selector forControlEvents:UIControlEventTouchUpInside]; item.customView = button;
return item;
} @end
2.UINavigationController:
#import "UYNavigationController.h"

@interface UYNavigationController ()

@end

@implementation UYNavigationController

+ (void)initialize
{
// 设置整个项目所有item的主题样式
UIBarButtonItem *item = [UIBarButtonItem appearance]; // 设置普通状态
// key:NS****AttributeName
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = [UIColor orangeColor];
textAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:];
[item setTitleTextAttributes:textAttrs forState:UIControlStateNormal]; // 设置不可用状态
NSMutableDictionary *disableTextAttrs = [NSMutableDictionary dictionary];
disableTextAttrs[NSForegroundColorAttributeName] = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.7];
disableTextAttrs[NSFontAttributeName] = [UIFont systemFontOfSize:];
[item setTitleTextAttributes:disableTextAttrs forState:UIControlStateDisabled];
} - (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
} /**
* 重写这个方法目的:能够拦截所有push进来的控制器
*
* @param viewController 即将push进来的控制器
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > ) { // 这时push进来的控制器viewController,不是第一个子控制器(不是根控制器)
/* 自动显示和隐藏tabbar */
viewController.hidesBottomBarWhenPushed = YES;
    //左边    
    self.navigationItem.leftBarButtonItem = [HVWBarButtonItem itemWithImage:@"navigationbar_friendsearch" hightlightedImage:@"navigationbar_friendsearch_highlighted" target:self selector:@selector(searchFriend)];
    // 右边按钮
    self.navigationItem.rightBarButtonItem = [HVWBarButtonItem itemWithImage:@"navigationbar_pop" hightlightedImage:@"navigationbar_pop_highlighted" target:self selector:@selector(pop)];
}
[super pushViewController:viewController animated:animated]; } 

- (void)back { 
#warning 这里要用self,不是self.navigationController
// 因为self本来就是一个导航控制器,self.navigationController这里是nil的
[self popViewControllerAnimated:YES];
} - (void)more {
[self popToRootViewControllerAnimated:YES];
} @end

效果如下:

自定义TabBar,把特殊+按钮添加上来

需要反注释掉UYTabBarViewController部分代码:

    // 2.更换系统自带的tabbar,由于tabbar是realonly,因此使用KVC来重写。如果没有特殊的导航布局,去掉这下面这部分代码即可。
UYTabBar *tabBar = [[UYTabBar alloc] init];
tabBar.delegate = self;
[self setValue:tabBar forKeyPath:@"tabBar"];

UYTabBar 中,在layoutSubviews重新对四个底部TabBar进行位置调整,并给+号按钮增加点击事件:

UYTabBar.h

#import <UIKit/UIKit.h>
@class UYTabBar; #warning 因为UYTabBar继承自UITabBar,所以称为UYTabBar的代理,也必须实现UITabBar的代理协议
@protocol UYTabBarDelegate <UITabBarDelegate>
@optional
- (void)tabBarDidClickPlusButton:(UYTabBar *)tabBar;
@end @interface UYTabBar : UITabBar
@property (nonatomic, weak) id<UYTabBarDelegate> delegate;
@end

UYTabBar.m

#import "UYTabBar.h"

@interface UYTabBar()
@property(nonatomic,weak) UIButton *plusBtn;
@end @implementation UYTabBar - (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_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;
} /**
* 加号按钮点击
*/
- (void)plusClick
{
// 通知代理
if ([self.delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
[self.delegate tabBarDidClickPlusButton:self];
}
} - (void)layoutSubviews
{
#warning [super layoutSubviews] 一定要调用
[super layoutSubviews]; // 1.设置加号按钮的位置
self.plusBtn.centerX = self.width * 0.5;
self.plusBtn.centerY = self.height * 0.5; // 2.设置其他tabbarButton的位置和尺寸
CGFloat tabbarButtonW = self.width / ;
CGFloat tabbarButtonIndex = ;
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 == ) {
tabbarButtonIndex++;
}
}
}
} @end

效果如下:

添加导航栏按钮

需要给各个Tab还有其下的页面添加左右导航栏按钮
由于该方法经常被使用到,自定义一个分类UIBarButtonItem
UIBarButtonItem.h
@interface UIBarButtonItem (Extension)
+ (UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage;
@end

UIBarButtonItem.m

@implementation UIBarButtonItem (Extension)
/**
* 创建一个item
*
* @param target 点击item后调用哪个对象的方法
* @param action 点击item后调用target的哪个方法
* @param image 图片
* @param highImage 高亮的图片
*
* @return 创建完的item
*/
+ (UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage
{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
// 设置图片
[btn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
// 设置尺寸
btn.size = btn.currentBackgroundImage.size;
return [[UIBarButtonItem alloc] initWithCustomView:btn];
}
@end

在HWNavigationController.m方法pushViewController下,增加

/**
* 重写这个方法目的:能够拦截所有push进来的控制器
*
* @param viewController 即将push进来的控制器
*/
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.viewControllers.count > ) { // 这时push进来的控制器viewController,不是第一个子控制器(不是根控制器)
/* 自动显示和隐藏tabbar */
viewController.hidesBottomBarWhenPushed = YES; /* 设置导航栏上面的内容 */
// 设置左边的返回按钮
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"navigationbar_back" highImage:@"navigationbar_back_highlighted"]; // 设置右边的更多按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(more) image:@"navigationbar_more" highImage:@"navigationbar_more_highlighted"];
} [super pushViewController:viewController animated:animated];
}

新建一个测试页UYTest1ViewController

首页UYHomeViewController.m

- (void)viewDidLoad
{
[super viewDidLoad]; /* 设置导航栏上面的内容 */
self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(friendSearch) image:@"navigationbar_friendsearch" highImage:@"navigationbar_friendsearch_highlighted"]; self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(pop) image:@"navigationbar_pop" highImage:@"navigationbar_pop_highlighted"];
} - (void)friendSearch
{
NSLog(@"friendSearch");
} - (void)pop
{
//NSLog(@"pop");
UYTest1ViewController *test1 = [[UYTest1ViewController alloc] init];
test1.title = @"测试1控制器";
[self.navigationController pushViewController:test1 animated:YES]; }

效果:

添加自定义日志输出

日志输出,如果直接使用NSLog,在发布程序后,会比较耗性能。因此,我们只在调试的时候,才需要日志输出。

在pch文件里添加debug模式下的log函数

// 测试用log
#ifdef DEBUG
#define UYLog(...) NSLog(__VA_ARGS__)
#else
#define UYLog(...)
#endif

使用宏定义的log函数,只有在debug模式下才会转化成为NSLog,release的时候会转为空

 /** 寻找朋友按钮事件 */
- (void) searchFriend {
UYLog(@"searchFriend");
}

这里可以修改运行模式:

发布的程序,是Archive模式,是Release。

源代码下载:点击下载

iOS 新浪微博-1.0框架搭建的更多相关文章

  1. iOS 新浪微博-1.1框架升级

    在iOS 新浪微博-1.0框架搭建 中,使用的是xcode5.1.1开发.现在把重整了一下框架 改为xcode7.0开发 使用cocoaPad管理第三方库 程序将托管到github上 在改为xcode ...

  2. Vue2.0框架搭建基础操作及目录说明

    一.概述 vue.js是一套构建用户界面的渐进式框架.vue采用自底向上增量开发的设计.vue的核心库只关心视图层,非常容易学习,非常容易与其它库和已有项目整合.vue完全有能力驱动采用单文件组件和v ...

  3. iOS 新浪微博-5.0 首页微博列表

    首页显示微博列表,是微博的核心部分,这一章节,我们主要是显示出微博的列表. 导入第三方类库 pod 'SDWebImage', '~> 3.7.3' pod 'MJRefresh', '~> ...

  4. iOS 新浪微博-4.0 OAuth授权

    申请开发者 想要拉到到新浪微博的数据,首先让自己成为开发者.申请成为开发者账号很简单,只要有新浪微博的账号即可. 申请地址:http://open.weibo.com/ 在开发的过程中,我们需要拿到几 ...

  5. iOS 网易彩票-2框架搭建-代码重构

    在上一篇中,我们基本已经把整个框架都搭建出来了,下面进行代码重构一下. 思路: 导航按钮,按下时,会变灰,那是系统自带了,通过自定义UIButton,实现按下按钮立即切换效果. MJTabBarCon ...

  6. iOS 新浪微博-3.0 新特性

    每个程序在第一次启动的时候,都会显示新特性.效果如下: 思路: 添加一个ViewController,里面放两个View,一个是UISrollView,另一个pageControl 往UISrollV ...

  7. iOS 新浪微博-2.0 搜索框/标题带箭头/下拉菜单

    不管是搜索框还是下拉菜单,我们都需要对背景的图片进行拉伸.定义一个Category分类对图片进行操作. UIImage+Effect.h #import <UIKit/UIKit.h> @ ...

  8. iOS 网易彩票-1框架搭建

    仿网易彩票,最终要做成的效果如下: 一.分层搭建 1.新建一个项目,Lottery.只支持7.1以上坚屏. 2.将素材全部图片全部拉到相应的文件夹里. 3.选中Lottery--右键Show in F ...

  9. iOS新浪微博OAuth2.0认证代码

    #import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...

随机推荐

  1. jQuery的回调管理机制(三)

    jQuery.when()方法是jQuery内部使用回调机制的范例. // 参数为多个方法,这些方法全部执行完成之后执行回调 when: function( subordinate /* , ..., ...

  2. Android 冷启动时间优化

    一 下载工具: 1.MaterialColdStart https://github.com/DreaminginCodeZH/MaterialColdStart 2.AndroidSVGScript ...

  3. Elasticsearch学习之深入搜索二 --- 搜索底层原理剖析

    1. 普通match如何转换为term+should { "match": { "title": "java elasticsearch"} ...

  4. mysqlslap 压测工具使用说明

    PS:今天一同事问我有木有比较靠谱的mysql压力测试工具可用.其实mysql自带就有一个叫mysqlslap的压力测试工具,还是模拟的不错的.下面举例说说.mysqlslap是从5.1.4版开始的一 ...

  5. springmvc如何访问到静态的文件,如jpg,js,css

    如何你的DispatcherServlet拦截"*.do"这样的有后缀的URL,就不存在访问不到静态资源的问题. 如果你的DispatcherServlet拦截"/&qu ...

  6. mysqladmin 命令详解

    mysqladmin是一个执行管理操作的客户端程序.它可以用来检查服务器的配置和当前状态.创建和删除数据库等. mysqladmin 工具的使用格式: mysqladmin [option] comm ...

  7. 浅谈SharePoint 2013 站点模板开发

    一直以来所接触的SharePoint开发,都是Designer配合Visual Studio,前者设计页面,后者开发功能,相互合作,完成SharePoint网站开发.直到SharePoint 2013 ...

  8. HDU 3480 - Division - [斜率DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3480 Time Limit: 10000/5000 MS (Java/Others) Memory L ...

  9. codeforces 782B - The Meeting Place Cannot Be Changed

    time limit per test 5 seconds memory limit per test 256 megabytes input standard input output standa ...

  10. hihocoder 1322 - 树结构判定 - [hiho一下161周][模板题/水题]

    题目链接:http://hihocoder.com/problemset/problem/1322 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个包含 N 个顶 ...