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
//
// Created by jiangys on 15/10/24.
// Copyright © 2015年 Jiangys. All rights reserved.
// #import <Foundation/Foundation.h> typedef enum {
UserVerifiedTypeNone = -, // 没有任何认证
UserVerifiedPersonal = , // 个人认证
UserVerifiedOrgEnterprice = , // 企业官方:CSDN、EOE、搜狐新闻客户端
UserVerifiedOrgMedia = , // 媒体官方:程序员杂志、苹果汇
UserVerifiedOrgWebsite = , // 网站官方:猫扑
UserVerifiedDaren = // 微博达人
} 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
//
// 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 > ;
} @end
Status.h
//
// Status.h
//
// 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 != ) {
NSRange range;
range.location = [source rangeOfString:@">"].location + ;
range.length = [source rangeOfString:@"</"].location - range.location;
_source = [NSString stringWithFormat:@"来自%@", [source substringWithRange:range]];
} else{
_source = @"来自微博";
}
} @end
StatusFrame.h
//
// StatusFrame.h
//
// 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
//
// 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 = ;
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 = ;
_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 - * 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
//
// 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
//
// 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 = ;
[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
//
// 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(, 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 - ;
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==) {
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 = ; // 2.设置其他属性
if (count == ) {
label.text = @"没有新的微博数据,稍后再试";
} else {
label.text = [NSString stringWithFormat:@"共有%zd条新的微博数据", count];
}
label.textColor = [UIColor whiteColor];
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:]; // 3.添加
label.y = - 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(, 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 = ;
vc.view.width = ; 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
iOS 新浪微博-5.0 首页微博列表的更多相关文章
- iOS 新浪微博-5.1 首页微博列表_时间/配图
在上一篇中,我们已经把首页微博显示出来了,但还有很多细节,需要我们去调整的.这一章中,我们将处理好时间,配图,工具框及转发微博等小细节的功能. 时间处理 第一步:定义一个时间的类别,用于判断是昨天.今 ...
- iOS 新浪微博-5.2 首页微博列表_转发微博/工具栏
继续于上一篇,还是做首页的功能,这一篇把剩下的首页继续完善. 看看上面的图片,分析: 1.转发微博里面的内容,和原创微博是一样的,由文字+配图组成.这应该放在一个UIView里处理. 2.工具栏也当成 ...
- iOS 新浪微博-5.3 首页微博列表_集成图片浏览器
实际上,我们可以使用李明杰在教程里集成的MJPhotoBrowser,地址: http://code4app.com/ios/快速集成图片浏览器/525e06116803fa7b0a000001 使用 ...
- IOS SWIFT UITableView 实现简单微博列表
// // Weibo.swift // UITableViewCellExample // // Created by XUYAN on 15/8/15. // Copyright (c) 2015 ...
- iOS 新浪微博-4.0 OAuth授权
申请开发者 想要拉到到新浪微博的数据,首先让自己成为开发者.申请成为开发者账号很简单,只要有新浪微博的账号即可. 申请地址:http://open.weibo.com/ 在开发的过程中,我们需要拿到几 ...
- iOS 新浪微博-3.0 新特性
每个程序在第一次启动的时候,都会显示新特性.效果如下: 思路: 添加一个ViewController,里面放两个View,一个是UISrollView,另一个pageControl 往UISrollV ...
- iOS 新浪微博-2.0 搜索框/标题带箭头/下拉菜单
不管是搜索框还是下拉菜单,我们都需要对背景的图片进行拉伸.定义一个Category分类对图片进行操作. UIImage+Effect.h #import <UIKit/UIKit.h> @ ...
- iOS新浪微博OAuth2.0认证代码
#import "ViewController.h" #import "AFNetworking.h" @interface ViewController () ...
- 【Android 我的博客APP】1.抓取博客首页文章列表内容——网页数据抓取
打算做个自己在博客园的博客APP,首先要能访问首页获取数据获取首页的文章列表,第一步抓取博客首页文章列表内容的功能已实现,在小米2S上的效果图如下: 思路是:通过编写的工具类访问网页,获取页面源代码, ...
随机推荐
- BZOJ 1002 - 轮状病毒 - [基尔霍夫矩阵(待补)+高精度]
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1002 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生 ...
- CH 1401 - 兔子与兔子 - [字符串hash]
题目链接:传送门 描述 很久很久以前,森林里住着一群兔子.有一天,兔子们想要研究自己的 DNA 序列.我们首先选取一个好长好长的 DNA 序列(小兔子是外星生物,DNA 序列可能包含 26 个小写英文 ...
- LCA&最小生成树
LCA 经常被用来使用.比如询问树两点之间的距离. 比如树上差分 都是经常被使用的类型.有的时候倍增求LCA的同时还可以优化算法. 这道题呢 求一个严格的最小生成树,当然如果不严格的话如果有重边那么就 ...
- LeetCode 953 Verifying an Alien Dictionary 解题报告
题目要求 In an alien language, surprisingly they also use english lowercase letters, but possibly in a d ...
- 新建虚拟机_WIN8 64位系统_启动报错Directory "EZBOOT" not found
准备工作:下载win8 64 镜像文件 1.虚拟机安装win8 64位操作系统,新建虚拟机步骤同XP系统 2.BIOS设置CD/ROM启动,但启动报错,如下,由于镜像文件超过4G,无法从虚拟机安装,需 ...
- springmvc shiro整合cas单点登入
shiro cas分为登入跟登出 maven依赖: <dependency> <groupId>org.apache.shiro</groupId> <art ...
- 【PyQt5-Qt Designer】QComboBox-下拉列表框
知识点: 1.QComboBox下拉列表框的一些常用方法 2.下拉列表框常用信号使用方法 案例:选中下拉框选项时触发信号 #[str] 表示comboBox中的选择框内容如A B C D 等 self ...
- Vue通过build打包后 打开index.html页面是空白的
最近在build打包vue项目遇到了几个问题,如下: 1.npm run build打包项目之后,我们通常是把dist文件里面被压缩后的static文件跟index.html提交到服务器,但最近发现直 ...
- Sql批量修改帝国cms文章发布时间(需unix时间,否则会变为1970-01-01)
在迁移网站时,有时我们需要将帝国cms文章发表时间批量修改为当前时间,在帝国cms后台→系统设置→备份与恢复数据→执行sql语句: update phome_ecms_news set newstim ...
- OC动画CABasicAnimation
//1.创建动画 CABasicAnimation *anima=[CABasicAnimation animationWithKeyPath:@"bounds"]; //1.1设 ...