年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 20142|回复: 69

[新浪微博] ios实战开发之仿新浪微博(第三讲:更多界面搭建)

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

    [LV.9]以坛为家II

    发表于 2014-4-14 21:28:57 | 显示全部楼层 |阅读模式
    1、效果展示
    1.1、iOS6.0版本
    iOS6-1.png iOS6-2.png

    1.2、iOS7.0版本
    iOS7-1.png iOS7-2.png

    2、设计说明
    2.1 创建数据模型
    2.1.1 Plist文件结构
    QQ20140414-1@2x.png

    2.1.2 创建数据模型,取出Plist文件中的每一个字典做为一个基本模型数据
    2.2 创建表格基本样式
    2.2.1 修改表格背景样式
    2.2.2 修改表格Cell样式,主要是背景图片,不同行号的Cell背景图片不尽相同
    2.2.3 抽象出Cell类,重构代码,保证代码的重用性

    2.3 调整特殊表格样式
    2.3.1 不同行号的Cell有不同样式的需求
    2.3.2 将Cell附加样式进行分类
    2.3.3 抽象成枚举类型,直接调用实现
    2.3.4 代码重构,性能优化

    3、关键代码
    SATableData.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SATableData.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-14.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //  数据模型
    
    #import <Foundation/Foundation.h>
    
    @interface SATableData : NSObject
    
    @property (nonatomic, copy) NSString        *icon;
    @property (nonatomic, copy) NSString        *name;
    @property (nonatomic, assign) NSInteger     row;
    
    - (id)initWithDict:(NSDictionary *)dict;
    + (id)tableDateWithDict:(NSDictionary *)dict;
    
    @end
    

    SATableData.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SATableData.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-14.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import "SATableData.h"
    
    @implementation SATableData
    
    - (id)initWithDict:(NSDictionary *)dict
    {
        if (self = [super init]) {
            
            self.icon = dict[@"icon"];
            self.name = dict[@"name"];
            self.row = [dict[@"row"] integerValue];
        }
        return self;
    }
    
    + (id)tableDateWithDict:(NSDictionary *)dict
    {
        return [[self alloc] initWithDict:dict];
    }
    
    @end
    

    SATableViewCell.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SATableViewCell.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-14.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    typedef enum {
        kCellTypeNone,
        kCellTypeArrow,
        kCellTypeLabel,
        kCellTypeSwitch,
        kCellRedButton
    } CellType;
    
    @interface SATableViewCell : UITableViewCell
    
    @property (nonatomic, readonly) UILabel     *accessoryLabel;
    @property (nonatomic, assign) CellType      cellType;
    @property (nonatomic, strong) UISwitch      *accessorySwitch;
    
    - (void)setGroupCellStyleWithTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
    
    @end
    

    SATableViewCell.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SATableViewCell.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-14.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import "SATableViewCell.h"
    #import "UIImage+SA.h"
    @interface SATableViewCell ()
    {
        UIImageView *_normalImage;
        UIImageView *_selectedImage;
        UIImageView *_cellImageView;
    }
    @end
    @implementation SATableViewCell
    
    #pragma mark - 修改ios7中Cell的尺寸位置
    - (void) layoutSubviews {
        [super layoutSubviews];
        // iOS7默认Cell宽度为320充满整个屏幕,而iOS6Cell宽度为300,为保持一致,重写该方法统一风格
        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
            CGRect fram = self.frame;
            fram.size.width = 300;                                  // Cell宽度设置成300
            fram.origin.x = 10;                                     // x右移10象素使Cell居中
            self.frame = fram;
        }
    }
    
    #pragma mark - 自定义Cell样式
    #pragma mark 设置Cell基本样式
    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
            _normalImage = [[UIImageView alloc] init];
            _selectedImage = [[UIImageView alloc] init];
            self.backgroundView = _normalImage;                     // 设置Cell普通状态下背景
            self.selectedBackgroundView = _selectedImage;           // 设置Cell选择状态下背景
            self.textLabel.backgroundColor = [UIColor clearColor];  // Label设置透明色
            self.backgroundColor = [UIColor clearColor];            // Cell设置透明色
        }
        return self;
    }
    
    #pragma mark 设置Cell背景图片
    - (void)setGroupCellStyleWithTableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSInteger rows = [tableView numberOfRowsInSection:indexPath.section];
        self.textLabel.textAlignment = NSTextAlignmentLeft;         // 文字居左
        self.textLabel.textColor = [UIColor blackColor];            // 文本颜色为黑色
        self.textLabel.font = [UIFont systemFontOfSize:15];         // 字体大小固定
        
        // 设置Cell背景样式,美化视觉效果,由于圆角的设计使得处于不同位置的Cell背景图片不尽相同
        if (rows == 1) {                           // 只有一行情况
            _normalImage.image = [UIImage resizeImage:@"common_card_background.png"];
            _selectedImage.image = [UIImage resizeImage:@"common_card_background_highlighted.png"];
        } else if (indexPath.row == 0) {           // 首行
            _normalImage.image = [UIImage resizeImage:@"common_card_top_background.png"];
            _selectedImage.image = [UIImage resizeImage:@"common_card_top_background_highlighted.png"];
        } else if (indexPath.row == rows - 1) {    // 末行
            _normalImage.image = [UIImage resizeImage:@"common_card_bottom_background.png"];
            _selectedImage.image = [UIImage resizeImage:@"common_card_bottom_background_highlighted.png"];
        } else {                                   // 中间行
            _normalImage.image = [UIImage resizeImage:@"common_card_middle_background.png"];
            _selectedImage.image = [UIImage resizeImage:@"common_card_middle_background_highlighted.png"];
        }
    }
    
    #pragma mark - 自定义Cell附属样式
    -(void)setCellType:(CellType)cellType
    {
        
        switch (cellType) {
                
                // 无附属样式
            case kCellTypeNone:
                self.accessoryView = nil;
                break;
                
                // Cell右侧添加箭头图标样式
            case kCellTypeArrow:
                if (_cellImageView == nil){
                    _cellImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"common_icon_arrow.png"]];
                }
                self.accessoryView = _cellImageView;
                break;
                
                // Cell右侧添加标签样式
            case kCellTypeLabel:
                if (_accessoryLabel == nil){
                    _accessoryLabel = [[UILabel alloc] init];
                    _accessoryLabel.text = @"展开";
                    _accessoryLabel.bounds = CGRectMake(0, 0, 70, 44);
                    _accessoryLabel.backgroundColor = [UIColor clearColor];
                    _accessoryLabel.textColor = [UIColor grayColor];
                    _accessoryLabel.textAlignment = NSTextAlignmentCenter;
                    _accessoryLabel.font = [UIFont systemFontOfSize:12];
                }
                self.accessoryView = _accessoryLabel;
                break;
                
                // Cell右侧添加开关样式
            case kCellTypeSwitch:
                if (_accessorySwitch == nil) {
                    _accessorySwitch = [[UISwitch alloc] init];
                }
                self.accessoryView = _accessorySwitch;
                break;
                
                // 整个Cell为红色按钮样式
            case kCellRedButton:
            {
                self.textLabel.textAlignment = NSTextAlignmentCenter;
                self.textLabel.textColor = [UIColor whiteColor];
                _normalImage.image = [UIImage resizeImage:@"common_button_big_red.png"];
                _selectedImage.image = [UIImage resizeImage:@"common_button_big_red_highlighted.png"];
                self.accessoryView = nil;
            }
                break;
            default:
                self.accessoryView = nil;
                break;
        };
        
    }
    @end
    

    SAMoreController.h
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAMoreController.h
    //  SianWeibo
    //
    //  Created by yusian on 14-4-12.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface SAMoreController : UITableViewController
    
    @end
    

    SAMoreController.m
    [Objective-C] 纯文本查看 复制代码
    //
    //  SAMoreController.m
    //  SianWeibo
    //
    //  Created by yusian on 14-4-12.
    //  Copyright (c) 2014年 小龙虾论坛. All rights reserved.
    //
    
    #import "SAMoreController.h"
    #import "UIImage+SA.h"
    #import "SATableData.h"
    #import "SATableViewCell.h"
    #import "UIBarButtonItem+SA.h"
    
    @interface SAMoreController ()
    {
        NSMutableArray *_dataSource;
    }
    
    @end
    
    @implementation SAMoreController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        // 设置控制器标题
        self.title = @"更多";
        
        // 添加导航右侧按钮
        self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:UIBarButtonItemStyleBordered target:nil action:nil];
        
        // 加载数据模型
        [self loadData];
        
        // 创建表格样式
        [self buildTable];
    
    }
    
    #pragma mark - 加载数据模型
    - (void)loadData
    {
        _dataSource = [NSMutableArray array];
        NSURL *url = [[NSBundle mainBundle] URLForResource:@"More" withExtension:@"plist"];
        NSArray *plistData = [NSArray arrayWithContentsOfURL:url];                      // 加载Plist文件到临时数组
        for (int i = 0; i < plistData.count; i++) {                                     // 两个循环嵌套加载数据到模型
            NSMutableArray *array = [NSMutableArray array];                             // --1._dataSource  数组
            [_dataSource addObject:array];                                              // +---2.array      数组(Section)
            for (int j = 0; j < [plistData[i] count]; j ++) {                           // +-----3.data     数据模型(Row)
                SATableData *data = [SATableData tableDateWithDict:plistData[i][j]];    // 将每行数据创建数据模型并以行为单位存储到数组
                [array addObject:data];                                                 // 加载到单位组中
            }
        }
    }
    
    #pragma mark - 创建表格
    - (void)buildTable
    {
        // 清除表格底图,加载表格底色
        self.tableView.backgroundView = nil;
        self.tableView.backgroundColor = [UIColor colorWithRed:239/255.0 green:239/255.0 blue:244/255.0 alpha:1];
        
        // 设置表格底隔高度,清除表格栅隔线
        self.tableView.sectionFooterHeight = 0;
        self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
        
    }
    
    #pragma mark - Table view data source
    #pragma mark 表格组数
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
       return _dataSource.count;
    }
    
    #pragma mark 每组表格行数
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [_dataSource[section] count];
    }
    
    #pragma mark 每行表格内容
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSInteger sections = [tableView numberOfSections];
        
        // 基本Cell创建
        static NSString *Identifier = @"Cell";
        SATableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Identifier];
        if (cell == nil) {
            cell = [[SATableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Identifier];
        }
        
        // Cell内容设置
        [cell setGroupCellStyleWithTableView:tableView cellForRowAtIndexPath:indexPath];
        cell.textLabel.text = [_dataSource[indexPath.section][indexPath.row] name];
        
        // Cell样式处理
        if (indexPath.section == 2) {                       // 第三组表格右侧需要显示文字
            cell.cellType = kCellTypeLabel;
            cell.accessoryLabel.text = indexPath.row?@"经典模式" : @"有图模式";
        } else if (indexPath.section == sections - 1) {     // 最后一组表格设置成"退出登录"按钮样式
            cell.cellType = kCellRedButton;
        } else {                                            // 其他Cell右侧带小箭头图标
            cell.cellType = kCellTypeArrow;
        }
        
        return cell;
    }
    
    #pragma mark - TableView代理方法
    // 表格点击事件
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
    }
    
    @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-6-6 22:57:10 | 显示全部楼层
    必须好好好,不然不让下载啊

    该用户从未签到

    发表于 2014-6-17 16:05:46 | 显示全部楼层
    学习了,非常好的教程。

    该用户从未签到

    发表于 2014-7-1 10:45:59 | 显示全部楼层
    支持!!!!!!!!!!
    回复

    使用道具 举报

    该用户从未签到

    发表于 2014-9-9 14:27:50 | 显示全部楼层
    使用 storyboard 不是更快捷方便吗
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

     楼主| 发表于 2014-9-10 23:00:16 来自手机 | 显示全部楼层
    namefcl 发表于 2014-9-9 14:27
    使用 storyboard 不是更快捷方便吗

    开发简单但不好维护,扩展性差

    该用户从未签到

    发表于 2014-9-19 14:15:13 | 显示全部楼层
    good!good!good!good!
  • TA的每日心情
    害羞
    2014-10-23 07:44
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-23 07:57:05 | 显示全部楼层
    对学习IOS开发很有好处

    该用户从未签到

    发表于 2014-10-24 11:17:18 | 显示全部楼层
    继续感谢楼主!!!!!!
  • TA的每日心情
    倒霉
    2014-11-11 21:18
  • 签到天数: 18 天

    [LV.4]偶尔看看III

    发表于 2014-10-29 00:53:16 | 显示全部楼层
    来回顾回顾内容,谢谢了
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

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

    GMT+8, 2024-4-16 13:59 , Processed in 0.058233 second(s), 26 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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