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

首页显示微博列表,是微博的核心部分,这一章节,我们主要是显示出微博的列表。

导入第三方类库

pod ‘SDWebImage‘, ‘~> 3.7.3‘
pod ‘MJRefresh‘, ‘~> 2.4.12‘
pod ‘MJExtension‘, ‘~> 2.5.14‘

需求分析

由于Cell的高度是不一样的,因而采用自定义cell的方式来实现。具体实现思路,请参数之前的文章:

iOS UI基础-9.2 UITableView 简单微博列表

代码实现

1、根据新浪微博的API文档,需要定义两个模型(User/Status),由于我们还需要计算控制的位置,另外定义一个StatusFrame模型。

User.h

//
//  User.h
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import <Foundation/Foundation.h>

typedef enum {
    UserVerifiedTypeNone = -1, // 没有任何认证
    UserVerifiedPersonal = 0,  // 个人认证
    UserVerifiedOrgEnterprice = 2, // 企业官方:CSDN、EOE、搜狐新闻客户端
    UserVerifiedOrgMedia = 3, // 媒体官方:程序员杂志、苹果汇
    UserVerifiedOrgWebsite = 5, // 网站官方:猫扑
    UserVerifiedDaren = 220 // 微博达人
} UserVerifiedType;

@interface User : NSObject

/**    string    字符串型的用户UID*/
@property (nonatomic, copy) NSString *idstr;

/**    string    友好显示名称*/
@property (nonatomic, copy) NSString *name;

/**    string    用户头像地址,50×50像素*/
@property (nonatomic, copy) NSString *profile_image_url;

/** 会员类型 > 2代表是会员 */
@property (nonatomic, assign) int mbtype;

/** 会员等级 */
@property (nonatomic, assign) int mbrank;

@property (nonatomic, assign, getter = isVip) BOOL vip;

/** 认证类型 */
@property (nonatomic, assign) UserVerifiedType verified_type;

@end

User.m

//
//  User.m
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import "User.h"

@implementation User

- (void)setMbtype:(int)mbtype
{
    _mbtype = mbtype;

    self.vip = mbtype > 2;
}

@end

Status.h

//
//  Status.h
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import <Foundation/Foundation.h>
@class User;

@interface Status : NSObject

/**    string    字符串型的微博ID*/
@property (nonatomic, copy) NSString *idstr;

/**    string    微博信息内容*/
@property (nonatomic, copy) NSString *text;

/**    object    微博作者的用户信息字段 详细*/
@property (nonatomic, strong) User *user;

/**    string    微博创建时间*/
@property (nonatomic, copy) NSString *created_at;

/**    string    微博来源*/
@property (nonatomic, copy) NSString *source;

/** 微博配图地址。多图时返回多图链接。无配图返回“[]” */
@property (nonatomic, strong) NSArray *pic_urls;

@end

Status.m

#import "Status.h"

@implementation Status

// source == <a href="http://app.weibo.com/t/feed/2llosp" rel="nofollow">OPPO_N1mini</a>
- (void)setSource:(NSString *)source
{
    if (source.length != 0) {
        NSRange range;
        range.location = [source rangeOfString:@">"].location + 1;
        range.length = [source rangeOfString:@"</"].location - range.location;
        _source = [NSString stringWithFormat:@"来自%@", [source substringWithRange:range]];
    } else{
        _source = @"来自微博";
    }
}

@end

StatusFrame.h

//
//  StatusFrame.h
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import <Foundation/Foundation.h>
@class Status;

// cell的边框宽度
#define StatusCellBorderW 10
// 昵称字体
#define StatusCellNameFont [UIFont systemFontOfSize:15]
// 时间字体
#define StatusCellTimeFont [UIFont systemFontOfSize:12]
// 来源字体
#define StatusCellSourceFont StatusCellTimeFont
// 正文字体
#define StatusCellContentFont [UIFont systemFontOfSize:14]

// 被转发微博的正文字体
#define StatusCellRetweetContentFont [UIFont systemFontOfSize:13]

// cell之间的间距
#define StatusCellMargin 15

@interface StatusFrame : NSObject

/** 存在微博模型 */
@property (nonatomic, strong) Status *status;

/** 原创微博整体 */
@property (nonatomic, assign, readonly) CGRect originalViewF;
/** 头像 */
@property (nonatomic, assign, readonly) CGRect iconViewF;
/** 会员图标 */
@property (nonatomic, assign, readonly) CGRect vipViewF;
/** 配图 */
@property (nonatomic, assign, readonly) CGRect photosViewF;
/** 昵称 */
@property (nonatomic, assign, readonly) CGRect nameLabelF;
/** 时间 */
@property (nonatomic, assign, readonly) CGRect timeLabelF;
/** 来源 */
@property (nonatomic, assign, readonly) CGRect sourceLabelF;
/** 正文 */
@property (nonatomic, assign, readonly) CGRect contentLabelF;

/** cell的高度 */
@property (nonatomic, assign, readonly) CGFloat cellHeight;

@end

StatusFrame.m

//
//  StatusFrame.m
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import "StatusFrame.h"
#import "Status.h"
#import "User.h"
#import "NSString+Size.h"

@implementation StatusFrame

/**
 *  设置每一条微博的Frame 及cell的高度
 *
 *  @param status 微博模型
 */
-(void)setStatus:(Status *)status
{
    _status = status;

    User *user=status.user;

    // cell的宽度
    CGFloat cellW = [UIScreen mainScreen].bounds.size.width;

    /* 原创微博 */

    /** 头像 */
    CGFloat iconWH = 35;
    CGFloat iconX = StatusCellBorderW;
    CGFloat iconY = StatusCellBorderW;
    _iconViewF = CGRectMake(iconX, iconY, iconWH, iconWH);

    /** 昵称 */
    CGFloat nameX = CGRectGetMaxX(self.iconViewF) + StatusCellBorderW;
    CGFloat nameY = iconY;
    CGSize nameSize = [user.name sizeWithFont:StatusCellNameFont];
    _nameLabelF = (CGRect){{nameX, nameY}, nameSize};

    /** 会员图标 */
    if (user.isVip) {
        CGFloat vipX = CGRectGetMaxX(self.nameLabelF) + StatusCellBorderW;
        CGFloat vipY = nameY;
        CGFloat vipH = nameSize.height;
        CGFloat vipW = 14;
        _vipViewF = CGRectMake(vipX, vipY, vipW, vipH);
    }

    /** 时间 */
    CGFloat timeX = nameX;
    CGFloat timeY = CGRectGetMaxY(self.nameLabelF) + StatusCellBorderW;
    CGSize timeSize = [status.created_at sizeWithFont:StatusCellTimeFont];
    _timeLabelF = (CGRect){{timeX, timeY}, timeSize};

    /** 来源 */
    CGFloat sourceX = CGRectGetMaxX(self.timeLabelF) + StatusCellBorderW;
    CGFloat sourceY = timeY;
    CGSize sourceSize = [status.source sizeWithFont:StatusCellSourceFont];
    _sourceLabelF = (CGRect){{sourceX, sourceY}, sourceSize};

    /** 正文 */
    CGFloat contentX = iconX;
    CGFloat contentY = MAX(CGRectGetMaxY(self.iconViewF), CGRectGetMaxY(self.timeLabelF)) + StatusCellBorderW;
    CGFloat maxW = cellW - 2 * contentX;
    CGSize contentSize = [status.text sizeWithFont:StatusCellContentFont maxW:maxW];
    _contentLabelF = (CGRect){{contentX, contentY}, contentSize};

    /* cell的高度 */
    _cellHeight = CGRectGetMaxY(self.contentLabelF)+StatusCellBorderW;
}

@end

2、接下来,我们需要自定义cell,在cell里添加所有的控件及设置控件的尺寸。

StatusCell.h

//
//  StatusCell.h
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import <UIKit/UIKit.h>
@class StatusFrame;

@interface StatusCell : UITableViewCell
@property (nonatomic, strong) StatusFrame *statusFrame;

+ (instancetype)cellWithTableView:(UITableView *)tableView;
@end

StatusCell.m

//
//  StatusCell.m
//  Weibo
//
//  Created by jiangys on 15/10/24.
//  Copyright © 2015年 Jiangys. All rights reserved.
//

#import "StatusCell.h"
#import "Status.h"
#import "StatusFrame.h"
#import "User.h"
#import "UIImageView+WebCache.h"

@interface StatusCell()

/* 原创微博 */
/** 原创微博整体 */
@property (nonatomic, weak) UIView *originalView;
/** 头像 */
@property (nonatomic, weak) UIImageView *iconView;
/** 会员图标 */
@property (nonatomic, weak) UIImageView *vipView;
/** 配图 */
@property (nonatomic, weak) UIImageView *photosView;
/** 昵称 */
@property (nonatomic, weak) UILabel *nameLabel;
/** 时间 */
@property (nonatomic, weak) UILabel *timeLabel;
/** 来源 */
@property (nonatomic, weak) UILabel *sourceLabel;
/** 正文 */
@property (nonatomic, weak) UILabel *contentLabel;

@end

@implementation StatusCell

/**
 *  重写initWithStyle:reuseIdentifier:方法
 *  添加所有需要显示的子控件(不需要设置子控件的数据和frame,子控件要添加到contentView中)
 *  进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)
 */
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self==[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        /** 原创微博整体 */
        UIView *originalView = [[UIView alloc] init];
        originalView.backgroundColor = [UIColor whiteColor];
        [self.contentView addSubview:originalView];
        self.originalView = originalView;

        /** 头像 */
        UIImageView *iconView = [[UIImageView alloc] init];
        [originalView addSubview:iconView];
        self.iconView = iconView;

        /** 会员图标 */
        UIImageView *vipView = [[UIImageView alloc] init];
        vipView.contentMode = UIViewContentModeCenter;
        [originalView addSubview:vipView];
        self.vipView = vipView;

        /** 配图 */
        UIImageView *photosView = [[UIImageView alloc] init];
        [originalView addSubview:photosView];
        self.photosView = photosView;

        /** 昵称 */
        UILabel *nameLabel = [[UILabel alloc] init];
        nameLabel.font = StatusCellNameFont;
        [originalView addSubview:nameLabel];
        self.nameLabel = nameLabel;

        /** 时间 */
        UILabel *timeLabel = [[UILabel alloc] init];
        timeLabel.font = StatusCellTimeFont;
        timeLabel.textColor = [UIColor orangeColor];
        [originalView addSubview:timeLabel];
        self.timeLabel = timeLabel;

        /** 来源 */
        UILabel *sourceLabel = [[UILabel alloc] init];
        sourceLabel.font = StatusCellSourceFont;
        [originalView addSubview:sourceLabel];
        self.sourceLabel = sourceLabel;

        /** 正文 */
        UILabel *contentLabel = [[UILabel alloc] init];
        contentLabel.font = StatusCellContentFont;
        contentLabel.numberOfLines = 0;
        [originalView addSubview:contentLabel];
        self.contentLabel = contentLabel;
    }
    return self;
}

- (void)setStatusFrame:(StatusFrame *)statusFrame
{
    _statusFrame = statusFrame;
    Status *status = self.statusFrame.status;
    User *user = status.user;

    /** 原创微博整体 */
    self.originalView.frame = statusFrame.originalViewF;

    /** 头像 */
    self.iconView.frame = statusFrame.iconViewF;
    [self.iconView sd_setImageWithURL:[NSURL URLWithString:user.profile_image_url] placeholderImage:[UIImage imageNamed:@"avatar_default_small"]];

    /** 会员图标 */
    if (user.isVip) {
        self.vipView.hidden = NO;

        self.vipView.frame = statusFrame.vipViewF;
        NSString *vipName = [NSString stringWithFormat:@"common_icon_membership_level%d", user.mbrank];
        self.vipView.image = [UIImage imageNamed:vipName];

        self.nameLabel.textColor = [UIColor orangeColor];
    } else {
        self.nameLabel.textColor = [UIColor blackColor];
        self.vipView.hidden = YES;
    }

    /** 配图 */
    self.photosView.frame = statusFrame.photosViewF;
    self.photosView.backgroundColor = [UIColor redColor];

    /** 昵称 */
    self.nameLabel.text = user.name;
    self.nameLabel.frame = statusFrame.nameLabelF;

    /** 时间 */
    self.timeLabel.text = status.created_at;
    self.timeLabel.frame = statusFrame.timeLabelF;

    /** 来源 */
    self.sourceLabel.text = status.source;
    self.sourceLabel.frame = statusFrame.sourceLabelF;

    /** 正文 */
    self.contentLabel.text = status.text;
    self.contentLabel.frame = statusFrame.contentLabelF;

}

+ (instancetype)cellWithTableView:(UITableView *)tableView
{
    static NSString *ID = @"status";
    StatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[StatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    return cell;
}

@end

3、最后,就是有首页里显示出cell。首页里,显示用到的MJRefresh刷新控件

//
//  HomeViewController.m
//  Weibo
//
//  Created by jiangys on 15/10/5.
//  Copyright (c) 2015年 Jiangys. All rights reserved.
//

#import "HomeViewController.h"
#import "Test1ViewController.h"
#import "DropdownMenu.h"
#import "TitleMenuViewController.h"
#import "TitleButton.h"
#import "Status.h"
#import "StatusFrame.h"
#import "MJRefresh.h"
#import "MJExtension.h"
#import "AccountTool.h"
#import "Account.h"
#import "HttpTool.h"
#import "StatusCell.h"
#import "User.h"

@interface HomeViewController ()<DropdownMenuDelegate>

/** 微博列表 (里面放的都是HWStatusFrame模型,一个StatusFrame对象就代表一条微博)*/
@property (nonatomic, strong) NSMutableArray *statusFrames;

@end

@implementation HomeViewController

- (NSMutableArray *)statusFrames
{
    if (!_statusFrames) {
        self.statusFrames = [NSMutableArray array];
    }
    return _statusFrames;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    // 设置导航栏内容
    [self setupNav];

    // 获得用户信息(昵称)
    [self setupUserInfo];

    // 集成下拉刷新控件
    [self setupDownRefresh];

    // 集成上拉刷新控制
    [self setupUpRefresh];
}

/**
 *  集成下拉刷新控件
 */
- (void)setupDownRefresh
{
    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
    self.tableView.header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(loadNewStatus)];

    // 马上进入刷新状态
    [self.tableView.header beginRefreshing];
}

- (void)setupUpRefresh
{
    // 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法)
    self.tableView.footer = [MJRefreshAutoNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(loadMoreStatus)];
}

- (void)loadNewStatus
{
    // 1.拼接请求参数
    Account *account = [AccountTool getAccount];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"access_token"] = account.access_token;

    // 取出最前面的微博(最新的微博,ID最大的微博)
    StatusFrame *firstStatusF = [self.statusFrames firstObject];
    if (firstStatusF) {
        // 若指定此参数,则返回ID比since_id大的微博(即比since_id时间晚的微博),默认为0
        params[@"since_id"] = firstStatusF.status.idstr;
    }

    // 2.发送请求
    [HttpTool get:@"https://api.weibo.com/2/statuses/friends_timeline.json" params:params success:^(id json) {
        // YSLog(@"--json--%@",json);

        // 将 "微博字典"数组 转为 "微博模型"数组
        NSArray *newStatuses = [Status objectArrayWithKeyValuesArray:json[@"statuses"]];

        // 将 HWStatus数组 转为 HWStatusFrame数组
        NSArray *newFrames = [self stausFramesWithStatuses:newStatuses];

        // 将最新的微博数据,添加到总数组的最前面
        NSRange range = NSMakeRange(0, newFrames.count);
        NSIndexSet *set = [NSIndexSet indexSetWithIndexesInRange:range];
        [self.statusFrames insertObjects:newFrames atIndexes:set];

        // 刷新表格
        [self.tableView reloadData];

        // 结束刷新
        [self.tableView.header endRefreshing];

        // 显示最新微博的数量
        [self showNewStatusCount:newStatuses.count];

    } failure:^(NSError *error) {
        YSLog(@"请求失败-%@", error);

        // 结束刷新刷新
        [self.tableView.header endRefreshing];
    }];
}

/**
 *  加载更多微博数据
 */
- (void)loadMoreStatus
{
    // 1.拼接请求参数
    Account *account = [AccountTool getAccount];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"access_token"] = account.access_token;

    // 取出最后面的微博(最新的微博,ID最大的微博)
    StatusFrame *lastStatusF = [self.statusFrames lastObject];
    if (lastStatusF) {
        // 若指定此参数,则返回ID小于或等于max_id的微博,默认为0。
        // id这种数据一般都是比较大的,一般转成整数的话,最好是long long类型
        long long maxId = lastStatusF.status.idstr.longLongValue - 1;
        params[@"max_id"] = @(maxId);
    }

    // 2.发送请求
    [HttpTool get:@"https://api.weibo.com/2/statuses/friends_timeline.json" params:params success:^(id json) {
        // 将 "微博字典"数组 转为 "微博模型"数组
        NSArray *newStatuses = [Status objectArrayWithKeyValuesArray:json[@"statuses"]];

        // 如果没有更多数据,隐藏
        if (newStatuses.count==0) {
            self.tableView.footer.hidden = YES;
        }

        // 将 Status数组 转为 StatusFrame数组
        NSArray *newFrames = [self stausFramesWithStatuses:newStatuses];

        // 将更多的微博数据,添加到总数组的最后面
        [self.statusFrames addObjectsFromArray:newFrames];

        // 刷新表格
        [self.tableView reloadData];

        // 结束footer刷新
        [self.tableView.footer endRefreshing];

    } failure:^(NSError *error) {
        YSLog(@"请求失败-%@", error);

        // 结束刷新
         [self.tableView.footer endRefreshing];
    }];
}

/**
 *  显示最新微博的数量
 *
 *  @param count 最新微博的数量
 */
- (void)showNewStatusCount:(NSUInteger)count
{
    // 1.创建label
    UILabel *label = [[UILabel alloc] init];
    label.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"timeline_new_status_background"]];
    label.width = [UIScreen mainScreen].bounds.size.width;
    label.height = 35;

    // 2.设置其他属性
    if (count == 0) {
        label.text = @"没有新的微博数据,稍后再试";
    } else {
        label.text = [NSString stringWithFormat:@"共有%zd条新的微博数据", count];
    }
    label.textColor = [UIColor whiteColor];
    label.textAlignment = NSTextAlignmentCenter;
    label.font = [UIFont systemFontOfSize:16];

    // 3.添加
    label.y = 64 - label.height;
    // 将label添加到导航控制器的view中,并且是盖在导航栏下边
    [self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];

    // 4.动画
    // 先利用1s的时间,让label往下移动一段距离
    CGFloat duration = 1.0; // 动画的时间
    [UIView animateWithDuration:duration animations:^{
        label.transform = CGAffineTransformMakeTranslation(0, label.height);
    } completion:^(BOOL finished) {
        // 延迟1s后,再利用1s的时间,让label往上移动一段距离(回到一开始的状态)
        CGFloat delay = 1.0; // 延迟1s
        // UIViewAnimationOptionCurveLinear:匀速
        [UIView animateWithDuration:duration delay:delay options:UIViewAnimationOptionCurveLinear animations:^{
            label.transform = CGAffineTransformIdentity;
        } completion:^(BOOL finished) {
            [label removeFromSuperview];
        }];
    }];

    // 如果某个动画执行完毕后,又要回到动画执行前的状态,建议使用transform来做动画
}

/**
 *  将Status模型转为StatusFrame模型
 */
- (NSArray *)stausFramesWithStatuses:(NSArray *)statuses
{
    NSMutableArray *frames = [NSMutableArray array];
    for (Status *status in statuses) {
        StatusFrame *f = [[StatusFrame alloc] init];
        f.status = status;
        [frames addObject:f];
    }
    return frames;
}

/**
 *  设置导航栏内容
 */
- (void)setupNav
{
    self.navigationItem.leftBarButtonItem=[UIBarButtonItem itemWithImage:@"navigationbar_friendsearch" highImage:@"navigationbar_friendsearch_highlighted" target:self action:@selector(friendSearch)];

    self.navigationItem.rightBarButtonItem=[UIBarButtonItem itemWithImage:@"navigationbar_pop" highImage:@"navigationbar_pop_highlighted" target:self action:@selector(pop)];

    /* 中间的标题按钮 */
    TitleButton *titleButton = [[TitleButton alloc] init];

    NSString *name = [AccountTool getAccount].name;
    [titleButton setTitle:name?name:@"首页" forState:UIControlStateNormal];

    // 监听标题点击
    [titleButton addTarget:self action:@selector(titleClick:) forControlEvents:UIControlEventTouchUpInside];

    self.navigationItem.titleView = titleButton;
}

/**
 *  标题点击
 */
- (void)titleClick:(UIButton *)titleButton
{
    // 1.创建下拉菜单
    DropdownMenu *menu = [DropdownMenu menu];
    menu.delegate = self;

    // 2.设置内容
    TitleMenuViewController *vc = [[TitleMenuViewController alloc] init];
    vc.view.height = 150;
    vc.view.width = 150;

    menu.contentController = vc;

    // 3.显示
    [menu showFrom:titleButton];
}

/**
 *  获得用户信息(昵称)
 */
- (void)setupUserInfo
{
    // 1.拼接请求参数
    Account *account = [AccountTool getAccount];
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    params[@"access_token"] = account.access_token;
    params[@"uid"] = account.uid;

    // 2.发送请求
    [HttpTool get:@"https://api.weibo.com/2/users/show.json" params:params success:^(id json) {
        // 标题按钮
        UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
        // 设置名字
        User *user = [User objectWithKeyValues:json];
        [titleButton setTitle:user.name forState:UIControlStateNormal];

        // 存储昵称到沙盒中
        account.name = user.name;
        [AccountTool saveAccount:account];
    } failure:^(NSError *error) {
        YSLog(@"请求失败-%@", error);
    }];
}

-(void)friendSearch
{

}

-(void)pop
{
    Test1ViewController *test1=[[Test1ViewController alloc]init];
    test1.title = @"测试2控制器";
    [self.navigationController pushViewController:test1 animated:YES];
}

#pragma mark - HWDropdownMenuDelegate
/**
 *  下拉菜单被销毁了
 */
- (void)dropdownMenuDidDismiss:(DropdownMenu *)menu
{
    UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
    titleButton.selected = NO;// 让箭头向下
}

/**
 *  下拉菜单显示了
 */
- (void)dropdownMenuDidShow:(DropdownMenu *)menu
{
    UIButton *titleButton = (UIButton *)self.navigationItem.titleView;
    titleButton.selected = YES;// 让箭头向上
}

#pragma mark - Table view data source
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.statusFrames.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 获得cell
    StatusCell *cell = [StatusCell cellWithTableView:tableView];

    // 给cell传递模型数据
    cell.statusFrame = self.statusFrames[indexPath.row];

    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    StatusFrame *statusFrame=self.statusFrames[indexPath.row];
    return statusFrame.cellHeight;
}

@end

最终效果如下:

章节源代码下载:http://pan.baidu.com/s/1c00SK1q

新浪微博Github:https://github.com/jiangys/Weibo

时间: 2024-11-03 05:28:47

iOS 新浪微博-5.0 首页微博列表的相关文章

iOS 新浪微博-5.1 首页微博列表_时间/配图

在上一篇中,我们已经把首页微博显示出来了,但还有很多细节,需要我们去调整的.这一章中,我们将处理好时间,配图,工具框及转发微博等小细节的功能. 时间处理 第一步:定义一个时间的类别,用于判断是昨天.今天等. NSDate+Time.h #import <Foundation/Foundation.h> @interface NSDate (Time) /** * 判断某个时间是否为今年 */ - (BOOL)isThisYear; /** * 判断某个时间是否为昨天 */ - (BOOL)is

IOS SWIFT UITableView 实现简单微博列表

// // Weibo.swift // UITableViewCellExample // // Created by XUYAN on 15/8/15. // Copyright (c) 2015年 com.world. All rights reserved. // import Foundation class Weibo { //属性 var id : UInt32 var img : String! var username : String! var mbtype : String

iOS 新浪微博-4.0 OAuth授权

申请开发者 想要拉到到新浪微博的数据,首先让自己成为开发者.申请成为开发者账号很简单,只要有新浪微博的账号即可. 申请地址:http://open.weibo.com/ 在开发的过程中,我们需要拿到几下几个值: AppKey :分配给每个第三方应用的 app key.用于鉴权身份,显示来源等功能. AppSecret :分配给每个第三方应用的 app 私钥. RedirectURI:应用回调页面,可在新浪微博开放平台->我的应用->应用信息->高级应用->授权设置->应用回调

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

#import "ViewController.h" #import "AFNetworking.h" @interface ViewController ()<UIWebViewDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1.使用webview UIWebView *webView = [[UIWebView all

新浪微博爬取笔记(3):wap端爬取用户微博列表 ,转发列表+数据清理

wap端登陆成功后,就可以安心开始爬取数据了.我这次需要的数据是: (1)用户的近期1000条微博,需要:微博id,转发量,发布时间 (2)某条微博的转发列表,需要:转发人,转发时间 (3)某个用户的关注数,粉丝数,微博数,最近100条微博的平均转发量 ========================================= 相比模拟登陆,爬数据的工作就简单很多.但需要注意几个坑,一边做一边总结如下: ##爬微博列表## (1)虽然目前wap端每页加载的微博数貌似是固定的,但其实是不固

iOS 应用2.0版怎么做(转)

移动互联网如火如荼,iOS 应用+ Android 应用+ 手机站似乎成了所有互联网公司的标配,你的网站要是还没有个iOS 应用,似乎都不好意思跟人打招呼.iOS 应用诞生毕竟才只有不到5年的时间,各个方面还都处在起步阶段.不管是出于团队缺乏经验,还是那个“唯快不破”的铁律,往往这些iOS 应用的第一个版本都比较简陋,尤其在技术架构上.这篇文章,我想跟大家探讨的就是这个问题,当你的iOS应用已经有一个版本在线的情况下,如何去构建一款可以支持高效迭代,快速响应的2.0版.首先,应用的架构要层次清晰

iOS 类似简单的第三方微博客户端,可进行登录微博浏览相关信息

Demo地址:https://github.com/ChenNan-FRAM/Fenvo (如果你觉得有用麻烦star一下感激不尽) Fenvo Objective-C, iOS 类似简单的第三方微博客户端,可进行登录微博浏览相关信息.在这个过程我是遇到很多的问题,但是大部分都顺利解决了,相信如果你的项目有类似的地方我的项目里面也能够给你提供一定的帮助,如果需要,可以给我留言或者在Github上联系我. UI简陋,暂未完善.有UI大师指点就最好了. 这个应用我是从开始学后为了实践自己的能力一直在

iOS简单易用的标签列表界面

iOS简单易用的标签列表界面 Demo效果: Demo演示: 1.使用cocoapods引入YZTagListView,或者直接拖入YZTagListView文件夹到项目中 2.导入YZTagListView.h头文件 1 #import "YZTagList.h" 3.创建YZTagListView控件 1 2 3   YZTagList *tagList = [[YZTagList alloc] init];   tagList.backgroundColor = [UIColor

新浪微博OAuth2.0的用法

最近学习Android开发,照着视频开发新浪微博,但是视频里的介绍的是OAuth1.0的授权方式,试了半天发现用不了. 原来现在一般没审核的用户只能使用OAuth2.0了,视频教学里的方法已经过时了.于是只好自己研究如何进行微博认证. OAuth2.0的授权过程 说白了,就是请求获取Grant Code→使用Grant Code申请Access Token→以后就使用这个Access Token获取微博的服务,这比OAuth1.0的授权方式简化了不少. 如果不使用别的第三方OAuth认证的库或者