年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 23987|回复: 63

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

  [复制链接]
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

    发表于 2014-4-12 23:30:13 | 显示全部楼层 |阅读模式
    1、效果演示



    2、设计说明
    2.1 整体设计请先参照:ios实战开发之仿新浪微博(第一讲:新特性展示)
    2.2 该部分主要在设计微博主界面下方的Dock及Dock中五个按钮之间视图的切换,如图所示
    iOS 模拟器屏幕快照“2014年4月12日 下午11.13.43”.png

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

    该用户从未签到

    发表于 2014-10-21 20:55:09 | 显示全部楼层
    luoluo
    luo lulu
  • TA的每日心情
    害羞
    2014-10-23 07:44
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-23 07:53:13 | 显示全部楼层
    谢谢楼主的分享

    该用户从未签到

    发表于 2014-10-23 20:33:16 | 显示全部楼层
    继续支持,感谢楼主!

    该用户从未签到

    发表于 2014-11-4 13:17:02 | 显示全部楼层
    :handshake:handshake:handshake
    回复

    使用道具 举报

    该用户从未签到

    发表于 2014-11-11 18:53:41 | 显示全部楼层
    谢谢楼主       楼主好人
  • TA的每日心情
    开心
    2014-11-13 16:47
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2014-11-13 16:48:09 | 显示全部楼层
    xue xi yi xia ...

    该用户从未签到

    发表于 2014-11-13 22:12:36 | 显示全部楼层
    谢谢分享,学习学习
  • TA的每日心情
    发光
    2014-11-26 14:19
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2014-11-19 13:10:05 | 显示全部楼层
    继续前进,看完还是又收货的哈
  • TA的每日心情

    2014-12-29 14:23
  • 签到天数: 6 天

    [LV.2]偶尔看看I

    发表于 2014-11-20 17:32:21 | 显示全部楼层
    学习怎么进行封装来降低耦合度
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-4-20 02:57 , Processed in 0.060395 second(s), 26 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表