1、效果演示
2、设计说明
2.1 整体设计请先参照:ios实战开发之仿新浪微博(第一讲:新特性展示)
2.2 该部分主要在设计微博主界面下方的Dock及Dock中五个按钮之间视图的切换,如图所示
2.3 主体部分在于Dock,传承封装的思想及代码重用性,尽量降低模块之间的偶合度,为Dock专门设计了控制器(SADockContorller)与视图(SADock与SADockItem);
2.4 由于Dock有自己的控制器,并将功能及视图控制基本全部封装,Main控制器只需要继承Dock控制器再添加业务需求上去即可;
2.5 五个功能区域Home、Message、Profile、Discover、More均有相对应的控制器,所以Main控制器将这五个控制器分别设置为其子控制器,在Dock的事件响应中相互切换;
2.6 各功能区域相互独立,独立管理独立实现相关功能;
2.7 有些细节单独抽取出来处理,如:导航条的样式单独一个导航条子类来自定义导航条(主要为美化显示效果),导航条上控制样式单独一个分类来重写(风格统一美化效果);
3、关键代码
SADock.h
[Objective-C] 纯文本查看 复制代码 //
// SADock.h
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock基本样式设置
#import <UIKit/UIKit.h>
#import "SADockItem.h"
@class SADock;
#pragma mark - SADock协议
@protocol SADockDelegate <NSObject>
@optional
- (void)dock:(SADock *)dock itemSelectFrom:(NSInteger)sourceIndex to:(NSInteger)toIndex;
@end
#pragma mark - SADock类声明
@interface SADock : UIView
// Dock中的按钮抽取出来做为成员变量方便事件响应与方法传递
@property (nonatomic, strong)SADockItem *item;
// 定义一个代理属性,将Dock中的按钮事件供外界调用
@property (nonatomic, weak) id<SADockDelegate> delegate;
// Dock上添加按键的一个方法
- (void)addItemWithIcon:(NSString *)iconName selectedIcon:(NSString *)selecteded title:(NSString *)title;
@end
SADock.m
[Objective-C] 纯文本查看 复制代码 //
// SADock.m
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock基本样式设置
#import "SADock.h"
#import "SADockItem.h"
#define kBackgroundImageName @"tabbar_background.png"
@implementation SADock
#pragma mark Dock初始始化状态
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 设置Dock的背景图片,美化样式
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:kBackgroundImageName]];
}
return self;
}
#pragma mark Dock上添加按钮
- (void)addItemWithIcon:(NSString *)iconName selectedIcon:(NSString *)selecteded title:(NSString *)title
{
SADockItem *item = [[SADockItem alloc] init];
[self addSubview:item];
[item setTitle:title forState:UIControlStateNormal]; // 设置按钮文字
[item setImage:[UIImage imageNamed:iconName] forState:UIControlStateNormal]; // 设置按钮不同状态下的图片
[item setImage:[UIImage imageNamed:selecteded] forState:UIControlStateSelected];
[item addTarget:self action:@selector(itemEvent:) forControlEvents:UIControlEventTouchDown];// 按钮事件响应
NSUInteger count = self.subviews.count;
CGFloat width = self.frame.size.width / count;
CGFloat height = self.frame.size.height;
for (int i = 0; i < count; i++) { // 根据按钮个数动态设置按钮尺寸位置
SADockItem *item = self.subviews[i];
item.tag = i;
item.frame = CGRectMake(width * i, 0, width, height);
}
if (_item == nil) {
[self itemEvent:self.subviews[0]]; // 默认状态点击第一个按钮
}
}
#pragma mark 被选状态切换
// 点击当前按钮,则当前按钮置于被选择状态,其他按钮置于未被选择状态
- (void)itemEvent:(SADockItem *)item
{
// 0、通知代理
if ([_delegate respondsToSelector:@selector(dock:itemSelectFrom:to:)]) {
[_delegate dock:self itemSelectFrom:(NSInteger)_item.tag to:(NSInteger)item.tag];
}
// 1、取消之前按钮的select状态
_item.selected = NO;
// 2、设置当前按钮select状态
item.selected = YES;
// 3、重新赋值给成员变量
_item = item;
}
@end
SADockItem.h
[Objective-C] 纯文本查看 复制代码 //
// SADockItem.h
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock按钮样式设置
#import <UIKit/UIKit.h>
@interface SADockItem : UIButton
@end
SADockItem.m
[Objective-C] 纯文本查看 复制代码 //
// SADockItem.m
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock按钮样式设置
#import "SADockItem.h"
#define kPercentage 0.6
#define kBgImageName @"tabbar_slider.png"
@implementation SADockItem
#pragma mark 按钮初始化状态
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 1、图片居中
self.imageView.contentMode = UIViewContentModeCenter;
// 2、文字居中
self.titleLabel.textAlignment = NSTextAlignmentCenter;
// 3、文字大小
self.titleLabel.font = [UIFont systemFontOfSize:12];
// 4、设置selected状态背景
[self setBackgroundImage:[UIImage imageNamed:kBgImageName] forState:UIControlStateSelected];
}
return self;
}
#pragma mark - 重写按钮方法自定义样式
#pragma mark 按钮高亮事件
- (void)setHighlighted:(BOOL)highlighted {} // 重写高亮事件为空,即跳过高亮事件过程,即点击按钮不会有高亮效果
#pragma mark 按钮图片尺寸位置
- (CGRect)imageRectForContentRect:(CGRect)contentRect // 按钮中图片占比上方60%,位置居中
{
CGFloat imageWith = contentRect.size.width;
CGFloat imageHeight = contentRect.size.height * kPercentage;
return CGRectMake(0, 0, imageWith, imageHeight);
}
#pragma mark 按钮文字尺寸位置
- (CGRect)titleRectForContentRect:(CGRect)contentRect // 按钮文字占比下方40%,位置居中上移2个像素
{
CGFloat titleY = contentRect.size.height * kPercentage - 2;
CGFloat width = contentRect.size.width;
CGFloat height = contentRect.size.height * (1 - kPercentage);
return CGRectMake(0, titleY, width, height);
}
@end
SADockController.h
[Objective-C] 纯文本查看 复制代码 //
// SADockController.h
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock控制器
#import <UIKit/UIKit.h>
#import "SADock.h"
@interface SADockController : UIViewController
@property (nonatomic, strong) SADock *dock;
@end
SADockController.m
[Objective-C] 纯文本查看 复制代码 //
// SADockController.m
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// Dock控制器
#import "SADockController.h"
#define kDockHeight 44
@interface SADockController () <SADockDelegate>
@end
@implementation SADockController
- (void)viewDidLoad
{
[super viewDidLoad];
[self addDock]; // 添加Dock到控制器
}
#pragma mark 添加Dock控件到当前控制器
// 将Dock添加到当前控制器的View上面,即调整Dock尺寸位置让其显示到屏幕最底部
- (void)addDock
{
_dock = [[SADock alloc] init];
_dock.frame = CGRectMake(0, self.view.frame.size.height - kDockHeight, self.view.frame.size.width, kDockHeight);
[self.view addSubview:_dock];
// 设置Dock的代理为当前控制器
_dock.delegate = self;
}
#pragma mark 首页控制器上View的切换
// Dock的代理方法,当Dock上按钮被点击时,切换相应的View到当前控制器上显示
-(void)dock:(SADock *)dock itemSelectFrom:(NSInteger)sourceIndex to:(NSInteger)toIndex
{
if (toIndex < 0 || toIndex >= self.childViewControllers.count) return;
// 1、移除之前的View
UIViewController *oldViewControl = self.childViewControllers[sourceIndex];
[oldViewControl.view removeFromSuperview];
// 2、展示当前的View并设置尺寸位置
UIViewController *newViewControl = self.childViewControllers[toIndex];
CGFloat width = self.view.frame.size.width;
CGFloat height = self.view.frame.size.height - dock.frame.size.height;
newViewControl.view.frame = CGRectMake(0, 0, width, height);
[self.view addSubview:newViewControl.view];
}
@end
SAMainController.h
[Objective-C] 纯文本查看 复制代码 //
// SAMainController.h
// SianWeibo
//
// Created by yusian on 14-4-11.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 主程序界面
#import <UIKit/UIKit.h>
#import "SADockController.h"
@interface SAMainController : SADockController
@end
SAMainController.m
[Objective-C] 纯文本查看 复制代码 //
// SAMainController.m
// SianWeibo
//
// Created by yusian on 14-4-11.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 主程序界面
#import "SAMainController.h"
#import "SAHomeController.h"
#import "SAMessageController.h"
#import "SAProfileController.h"
#import "SADiscoverController.h"
#import "SAMoreController.h"
#import "SANavigationController.h"
@interface SAMainController () <SADockDelegate>
@end
@implementation SAMainController
- (void)viewDidLoad
{
[super viewDidLoad];
// 添加其他View
[self addSubView];
// 添加Dock控件元素
[self addDockItems];
}
#pragma mark 添加子控件到首页控制器
- (void)addSubView
{
// 添加"首页"视图
SAHomeController *homeControl = [[SAHomeController alloc] init];
homeControl.view.backgroundColor = [UIColor grayColor];
SANavigationController *homeNav = [[SANavigationController alloc] initWithRootViewController:homeControl];
[self addChildViewController:homeNav];
// 添加"消息"视图
SAMessageController *messageControl = [[SAMessageController alloc] init];
messageControl.view.backgroundColor = [UIColor greenColor];
SANavigationController *messageNav = [[SANavigationController alloc] initWithRootViewController:messageControl];
[self addChildViewController:messageNav];
// 添加"我"视图
SAProfileController *profileControl = [[SAProfileController alloc] init];
profileControl.view.backgroundColor = [UIColor yellowColor];
SANavigationController *profileNav = [[SANavigationController alloc] initWithRootViewController:profileControl];
[self addChildViewController:profileNav];
// 添加"广场"视图
SADiscoverController *discoverControl = [[SADiscoverController alloc] init];
discoverControl.view.backgroundColor = [UIColor blueColor];
SANavigationController *discoverNav = [[SANavigationController alloc] initWithRootViewController:discoverControl];
[self addChildViewController:discoverNav];
// 添加"更多"视图
SAMoreController *moreControl = [[SAMoreController alloc] init];
SANavigationController *moreNav = [[SANavigationController alloc] initWithRootViewController:moreControl];
[self addChildViewController:moreNav];
}
#pragma mark 添加Dock控件到首页控制器
- (void)addDockItems
{
[self.dock addItemWithIcon:@"tabbar_home.png" selectedIcon:@"tabbar_home_selected.png" title:@"首页"];
[self.dock addItemWithIcon:@"tabbar_message_center.png" selectedIcon:@"tabbar_message_center_selected.png" title:@"消息"];
[self.dock addItemWithIcon:@"tabbar_profile.png" selectedIcon:@"tabbar_profile_selected.png" title:@"我"];
[self.dock addItemWithIcon:@"tabbar_discover.png" selectedIcon:@"tabbar_discover_selected.png" title:@"广场"];
[self.dock addItemWithIcon:@"tabbar_more.png" selectedIcon:@"tabbar_more_selected.png" title:@"更多"];
}
@end
SAHomeController.h
[Objective-C] 纯文本查看 复制代码 //
// SAHomeController.h
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 首页控制器
#import <UIKit/UIKit.h>
@interface SAHomeController : UITableViewController
@end
SAHomeController.m
[Objective-C] 纯文本查看 复制代码 //
// SAHomeController.m
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 首页控制器
#import "SAHomeController.h"
#import "NSString+SA.h"
#import "UIBarButtonItem+SA.h"
@interface SAHomeController ()
@end
@implementation SAHomeController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"首页";
// 用自定的分类方法给导航条添加左边按钮
self.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithImageName:@"navigationbar_compose.png" highLightedImageName:@"navigationbar_compose_highlighted.png" addTarget:self action:@selector(leftButtonClick) forControlEvents:UIControlEventTouchUpInside];
// 用自定的分类方法给导航条添加右边按钮
self.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithImageName:@"navigationbar_pop.png" highLightedImageName:@"navigationbar_pop_highlighted.png" addTarget:self action:@selector(rightButtonClick) forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark 首页导航左按钮事件
- (void)leftButtonClick
{
MyLog(@"首页左按钮");
}
#pragma mark 首页导航右按钮事件
- (void)rightButtonClick
{
MyLog(@"首页右按钮");
}
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 0;
}
@end
SANavigationController.h
[Objective-C] 纯文本查看 复制代码 //
// SANavigationController.h
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 新建一个子类自定义导航条
#import <UIKit/UIKit.h>
@interface SANavigationController : UINavigationController
@end
SANavigationController.m
[Objective-C] 纯文本查看 复制代码 //
// SANavigationController.m
// SianWeibo
//
// Created by yusian on 14-4-12.
// Copyright (c) 2014年 小龙虾论坛. All rights reserved.
// 新建一个子类自定义导航条
#import "SANavigationController.h"
@interface SANavigationController ()
@end
@implementation SANavigationController
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationBar *bar = [UINavigationBar appearance];
// 修改导航条背景
[bar setBackgroundImage:[UIImage imageNamed:@"navigationbar_background.png"] forBarMetrics:UIBarMetricsDefault];
// 修改导航条文字样式
[bar setTitleTextAttributes:@{
UITextAttributeTextColor : [UIColor grayColor],
UITextAttributeTextShadowOffset : [NSValue valueWithUIOffset:UIOffsetZero]
}];
// 修改状态栏样式
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
}
@end
4、源代码下载
相关主题链接
1、ios实战开发之仿新浪微博(第一讲:新特性展示)
2、ios实战开发之仿新浪微博(第二讲:主框架搭建)
3、ios实战开发之仿新浪微博(第三讲:更多界面搭建)
4、ios实战开发之仿新浪微博(第四讲:OAuth认证)
5、ios实战开发之仿新浪微博(第五讲:微博数据加载)
6、ios实战开发之仿新浪微博(第六讲:微博数据展示一)
7、ios实战开发之仿新浪微博(第七讲:微博数据展示二)
8、ios实战开发之仿新浪微博(第八讲:微博数据展示三)
9、ios实战开发之仿新浪微博(第九讲:微博功能完善一)
10、ios实战开发之仿新浪微博(第十讲:微博功能完善二)
11、ios实战开发之仿新浪微博(第十一讲:微博功能完善三)
12、ios实战开发之仿新浪微博(小龙虾发布版)
|