Sian 发表于 2014-4-12 23:30:13

ios实战开发之仿新浪微博(第二讲:主框架搭建)

1、效果演示

http://player.youku.com/player.php/sid/XNjk4MDE0NTI4/v.swf

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
//
//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
//
//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 = ;
    if (self) {
      // 设置Dock的背景图片,美化样式
      self.backgroundColor = ];
    }
    return self;
}

#pragma mark Dock上添加按钮
- (void)addItemWithIcon:(NSString *)iconName selectedIcon:(NSString *)selecteded title:(NSString *)title
{
    SADockItem *item = [ init];
    ;
   
    ;                                        // 设置按钮文字
    forState:UIControlStateNormal];                // 设置按钮不同状态下的图片
    forState:UIControlStateSelected];
    ;// 按钮事件响应
    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;
      item.tag = i;
      item.frame = CGRectMake(width * i, 0, width, height);
    }
   
    if (_item == nil) {
      ];                                                      // 默认状态点击第一个按钮
    }
}

#pragma mark 被选状态切换
// 点击当前按钮,则当前按钮置于被选择状态,其他按钮置于未被选择状态
- (void)itemEvent:(SADockItem *)item
{
    // 0、通知代理
    if () {
      ;
    }
   
    // 1、取消之前按钮的select状态
    _item.selected = NO;
   
    // 2、设置当前按钮select状态
    item.selected = YES;
   
    // 3、重新赋值给成员变量
    _item = item;
}


@end

SADockItem.h
//
//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
//
//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 = ;
    if (self) {
      
      // 1、图片居中
      self.imageView.contentMode = UIViewContentModeCenter;
      
      // 2、文字居中
      self.titleLabel.textAlignment = NSTextAlignmentCenter;
      
      // 3、文字大小
      self.titleLabel.font = ;
      
      // 4、设置selected状态背景
       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
//
//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
//
//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
{
    ;
   
    ;   // 添加Dock到控制器
}

#pragma mark 添加Dock控件到当前控制器
// 将Dock添加到当前控制器的View上面,即调整Dock尺寸位置让其显示到屏幕最底部
- (void)addDock
{
    _dock = [ init];
    _dock.frame = CGRectMake(0, self.view.frame.size.height - kDockHeight, self.view.frame.size.width, kDockHeight);
    ;
   
    // 设置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;
    ;
   
    // 2、展示当前的View并设置尺寸位置
    UIViewController *newViewControl = self.childViewControllers;
    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);
    ;
}

@end

SAMainController.h
//
//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
//
//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
{
    ;
   
    // 添加其他View
    ;
   
    // 添加Dock控件元素
    ;

}

#pragma mark 添加子控件到首页控制器
- (void)addSubView
{
    // 添加"首页"视图
    SAHomeController *homeControl = [ init];
    homeControl.view.backgroundColor = ;
    SANavigationController *homeNav = [ initWithRootViewController:homeControl];
    ;
   
    // 添加"消息"视图
    SAMessageController *messageControl = [ init];
    messageControl.view.backgroundColor = ;
    SANavigationController *messageNav = [ initWithRootViewController:messageControl];
    ;
   
    // 添加"我"视图
    SAProfileController *profileControl = [ init];
    profileControl.view.backgroundColor = ;
    SANavigationController *profileNav = [ initWithRootViewController:profileControl];
    ;
   
    // 添加"广场"视图
    SADiscoverController *discoverControl = [ init];
    discoverControl.view.backgroundColor = ;
    SANavigationController *discoverNav = [ initWithRootViewController:discoverControl];
    ;
   
    // 添加"更多"视图
    SAMoreController *moreControl = [ init];
    SANavigationController *moreNav = [ initWithRootViewController:moreControl];
    ;
}

#pragma mark 添加Dock控件到首页控制器
- (void)addDockItems
{
    ;
    ;
    ;
    ;
    ;
}
@end

SAHomeController.h
//
//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
//
//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 = ;
    if (self) {
      // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    ;
    self.title = @"首页";

    // 用自定的分类方法给导航条添加左边按钮
    self.navigationItem.leftBarButtonItem = ;
   
    // 用自定的分类方法给导航条添加右边按钮
    self.navigationItem.rightBarButtonItem = ;
}

#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
//
//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
//
//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
{
    ;
    UINavigationBar *bar = ;
   
    // 修改导航条背景
    forBarMetrics:UIBarMetricsDefault];
   
    // 修改导航条文字样式
    [bar setTitleTextAttributes:@{
                                  UITextAttributeTextColor : ,
                                  UITextAttributeTextShadowOffset :
                                  }];
    // 修改状态栏样式
    .statusBarStyle = UIStatusBarStyleBlackOpaque;
}

@end

4、源代码下载
**** Hidden Message *****

相关主题链接
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实战开发之仿新浪微博(小龙虾发布版)

lonaldoowen01 发表于 2014-10-21 20:55:09

luoluo
luo lulu

futue10 发表于 2014-10-23 07:53:13

谢谢楼主的分享

panzilong 发表于 2014-10-23 20:33:16

继续支持,感谢楼主!

zhwyaoyao 发表于 2014-11-4 13:17:02

:handshake:handshake:handshake

Schicksal 发表于 2014-11-11 18:53:41

谢谢楼主       楼主好人

lazhdy 发表于 2014-11-13 16:48:09

xue xi yi xia ...

ztt0422jiayou 发表于 2014-11-13 22:12:36

谢谢分享,学习学习

yipangzi 发表于 2014-11-19 13:10:05

继续前进,看完还是又收货的哈

warmlight 发表于 2014-11-20 17:32:21

学习怎么进行封装来降低耦合度
页: [1] 2 3 4 5 6 7
查看完整版本: ios实战开发之仿新浪微博(第二讲:主框架搭建)