(13)发送微博调用相机里面的图片以及调用相机
最后更新于:2022-04-01 07:27:21
## 一:效果
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9a56914.jpg)
## 二:代码
相机部分就简单多了,几行代码调用而已,但是如果你要是想实现更多丰富的功能,需要自己写。利用AssetsLibrary.framework,利用这个框架可以获得手机上的所有相册图片,写一个图片选择控制器。
~~~
- (void)openCamera
{
[self openImagePickerController:UIImagePickerControllerSourceTypeCamera];
}
- (void)openAlbum
{
// 如果想自己写一个图片选择控制器,得利用AssetsLibrary.framework,利用这个框架可以获得手机上的所有相册图片
// UIImagePickerControllerSourceTypePhotoLibrary > UIImagePickerControllerSourceTypeSavedPhotosAlbum
[self openImagePickerController:UIImagePickerControllerSourceTypePhotoLibrary];
}
- (void)openImagePickerController:(UIImagePickerControllerSourceType)type
{
if (![UIImagePickerController isSourceTypeAvailable:type]) return;
UIImagePickerController *ipc = [[UIImagePickerController alloc] init];
ipc.sourceType = type;
ipc.delegate = self;
[self presentViewController:ipc animated:YES completion:nil];
}
~~~
实现代理
~~~
#pragma mark - UIImagePickerControllerDelegate
/**
* 从UIImagePickerController选择完图片后就调用(拍照完毕或者选择相册图片完毕)
*/
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
// info中就包含了选择的图片
UIImage *image = info[UIImagePickerControllerOriginalImage];
// 添加图片到photosView中
[self.photosView addPhoto:image];
// dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// self.picking = NO;
// });
}
~~~
(12)发送微博自定义工具条代理实现点击事件
最后更新于:2022-04-01 07:27:18
## 一:效果
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9a17e42.jpg)
## 二:封装好的工具条
### NYComposeToolbar.h
带代理方法
~~~
#import <UIKit/UIKit.h>
typedef enum {
NYComposeToolbarButtonTypeCamera, // 拍照
NYComposeToolbarButtonTypePicture, // 相册
NYComposeToolbarButtonTypeMention, // @
NYComposeToolbarButtonTypeTrend, // #
NYComposeToolbarButtonTypeEmotion // 表情
} NYComposeToolbarButtonType;
@class NYComposeToolbar;
@protocol NYComposeToolbarDelegate <NSObject>
@optional
- (void)composeToolbar:(NYComposeToolbar *)toolbar didClickButton:(NYComposeToolbarButtonType)buttonType;
@end
@interface NYComposeToolbar : UIView
@property (nonatomic, weak) id<NYComposeToolbarDelegate> delegate;
@end
~~~
### NYComposeToolbar.m
~~~
//
// NYComposeToolbar.m
// 黑马微博2期
//
// Created by apple on 14-10-20.
// Copyright (c) 2014年 heima. All rights reserved.
//
#import "NYComposeToolbar.h"
@implementation NYComposeToolbar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"compose_toolbar_background"]];
// 初始化按钮
[self setupBtn:@"compose_camerabutton_background" highImage:@"compose_camerabutton_background_highlighted" type:NYComposeToolbarButtonTypeCamera];
[self setupBtn:@"compose_toolbar_picture" highImage:@"compose_toolbar_picture_highlighted" type:NYComposeToolbarButtonTypePicture];
[self setupBtn:@"compose_mentionbutton_background" highImage:@"compose_mentionbutton_background_highlighted" type:NYComposeToolbarButtonTypeMention];
[self setupBtn:@"compose_trendbutton_background" highImage:@"compose_trendbutton_background_highlighted" type:NYComposeToolbarButtonTypeTrend];
[self setupBtn:@"compose_emoticonbutton_background" highImage:@"compose_emoticonbutton_background_highlighted" type:NYComposeToolbarButtonTypeEmotion];
}
return self;
}
/**
* 创建一个按钮
*/
- (void)setupBtn:(NSString *)image highImage:(NSString *)highImage type:(NYComposeToolbarButtonType)type
{
UIButton *btn = [[UIButton alloc] init];
[btn setImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
btn.tag = type;
[self addSubview:btn];
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 设置所有按钮的frame
NSUInteger count = self.subviews.count;
CGFloat btnW = self.width / count;
CGFloat btnH = self.height;
for (NSUInteger i = 0; i<count; i++) {
UIButton *btn = self.subviews[i];
btn.y = 0;
btn.width = btnW;
btn.x = i * btnW;
btn.height = btnH;
}
}
- (void)btnClick:(UIButton *)btn
{
if ([self.delegate respondsToSelector:@selector(composeToolbar:didClickButton:)]) {
// NSUInteger index = (NSUInteger)(btn.x / btn.width);
[self.delegate composeToolbar:self didClickButton:btn.tag];
}
}
@end
~~~
## 三:调用
设置代理并且实现代理方法
~~~
/**
* 添加工具条
*/
- (void)setupToolbar
{
NYComposeToolbar *toolbar = [[NYComposeToolbar alloc] init];
toolbar.width = self.view.width;
toolbar.height = 44;
toolbar.y = self.view.height - toolbar.height;
toolbar.delegate = self;
[self.view addSubview:toolbar];
self.toolbar = toolbar;
}
~~~
代理方法
~~~
#pragma mark - NYComposeToolbarDelegate
- (void)composeToolbar:(NYComposeToolbar *)toolbar didClickButton:(NYComposeToolbarButtonType)buttonType
{
switch (buttonType) {
case NYComposeToolbarButtonTypeCamera: // 拍照
// [self openCamera];
NYLog(@"--- 拍照");
break;
case NYComposeToolbarButtonTypePicture: // 相册
NYLog(@"--- 相册");
// [self openAlbum];
break;
case NYComposeToolbarButtonTypeMention: // @
NYLog(@"--- @");
break;
case NYComposeToolbarButtonTypeTrend: // #
NYLog(@"--- #");
break;
case NYComposeToolbarButtonTypeEmotion: // 表情\键盘
NYLog(@"--- 表情");
break;
}
}
~~~
(11)发送微博自定义TextView实现带占位文字
最后更新于:2022-04-01 07:27:16
## 一:效果
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d99ca889.jpg)
## 二:代码:
由于系统自带的UITextField:和UITextView:不能满足我们的需求,所以我们需要自己设计一个。
UITextField:
1.文字永远是一行,不能显示多行文字
2.有placehoder属性设置占位文字
3.继承自UIControl
4.监听行为
1> 设置代理
2> addTarget:action:forControlEvents:
3> 通知:UITextFieldTextDidChangeNotification
UITextView:
1.能显示任意行文字
2.不能设置占位文字
3.继承自UIScollView
4.监听行为
1> 设置代理
2> 通知:UITextViewTextDidChangeNotification
### NYTextView.h
~~~
//
// Created by apple on 14-10-20.
// Copyright (c) 2014年 heima. All rights reserved.
// 增强:带有占位文字
#import <UIKit/UIKit.h>
@interface NYTextView : UITextView
/** 占位文字 */
@property (nonatomic, copy) NSString *placeholder;
/** 占位文字的颜色 */
@property (nonatomic, strong) UIColor *placeholderColor;
@end
~~~
### NYTextView.m
~~~
// Created by apple on 14-10-20.
// Copyright (c) 2014年 heima. All rights reserved.
//
#import "NYTextView.h"
@implementation NYTextView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 不要设置自己的delegate为自己
// self.delegate = self;
// 通知
// 当UITextView的文字发生改变时,UITextView自己会发出一个UITextViewTextDidChangeNotification通知
[NYNotificationCenter addObserver:self selector:@selector(textDidChange) name:UITextViewTextDidChangeNotification object:self];
}
return self;
}
- (void)dealloc
{
[NYNotificationCenter removeObserver:self];
}
/**
* 监听文字改变
*/
- (void)textDidChange
{
// 重绘(重新调用)
[self setNeedsDisplay];
}
- (void)setPlaceholder:(NSString *)placeholder
{
_placeholder = [placeholder copy];
[self setNeedsDisplay];
}
- (void)setPlaceholderColor:(UIColor *)placeholderColor
{
_placeholderColor = placeholderColor;
[self setNeedsDisplay];
}
- (void)setText:(NSString *)text
{
[super setText:text];
// setNeedsDisplay会在下一个消息循环时刻,调用drawRect:
[self setNeedsDisplay];
}
- (void)setFont:(UIFont *)font
{
[super setFont:font];
[self setNeedsDisplay];
}
- (void)drawRect:(CGRect)rect
{
// [NYRandomColor set];
// UIRectFill(CGRectMake(20, 20, 30, 30));
// 如果有输入文字,就直接返回,不画占位文字
if (self.hasText) return;
// 文字属性
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = self.font;
attrs[NSForegroundColorAttributeName] = self.placeholderColor?self.placeholderColor:[UIColor grayColor];
// 画文字
// [self.placeholder drawAtPoint:CGPointMake(5, 8) withAttributes:attrs];
CGFloat x = 5;
CGFloat w = rect.size.width - 2 * x;
CGFloat y = 8;
CGFloat h = rect.size.height - 2 * y;
CGRect placeholderRect = CGRectMake(x, y, w, h);
[self.placeholder drawInRect:placeholderRect withAttributes:attrs];
}
@end
~~~
(10)微博cell中图片的显示以及各种填充模式简介
最后更新于:2022-04-01 07:27:14
## 一效果
如果直接设置会有拉伸等等的状况,这里主要介绍图片显示的一些细节
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d999a2c9.jpg)
## 二:代码
代码实现其实很简单,微博当中用了一个photos来存放九宫格这些图片,然后用了一个photo类来做每个photo,并且在上面显示gif等的样式,很多很多小技巧,直接上代码
九宫格根据行列设置等算法,不难
~~~
#import "HWStatusPhotosView.h"
#import "HWPhoto.h"
#import "HWStatusPhotoView.h"
#define HWStatusPhotoWH 70
#define HWStatusPhotoMargin 10
#define HWStatusPhotoMaxCol(count) ((count==4)?2:3)
@implementation HWStatusPhotosView // 9
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
}
return self;
}
- (void)setPhotos:(NSArray *)photos
{
_photos = photos;
int photosCount = photos.count;
// 创建足够数量的图片控件
// 这里的self.subviews.count不要单独赋值给其他变量
while (self.subviews.count < photosCount) {
HWStatusPhotoView *photoView = [[HWStatusPhotoView alloc] init];
[self addSubview:photoView];
}
// 遍历所有的图片控件,设置图片
for (int i = 0; i<self.subviews.count; i++) {
HWStatusPhotoView *photoView = self.subviews[i];
if (i < photosCount) { // 显示
photoView.photo = photos[i];
photoView.hidden = NO;
} else { // 隐藏
photoView.hidden = YES;
}
}
}
- (void)layoutSubviews
{
[super layoutSubviews];
// 设置图片的尺寸和位置
int photosCount = self.photos.count;
int maxCol = HWStatusPhotoMaxCol(photosCount);
for (int i = 0; i<photosCount; i++) {
HWStatusPhotoView *photoView = self.subviews[i];
int col = i % maxCol;
photoView.x = col * (HWStatusPhotoWH + HWStatusPhotoMargin);
int row = i / maxCol;
photoView.y = row * (HWStatusPhotoWH + HWStatusPhotoMargin);
photoView.width = HWStatusPhotoWH;
photoView.height = HWStatusPhotoWH;
}
}
+ (CGSize)sizeWithCount:(int)count
{
// 最大列数(一行最多有多少列)
int maxCols = HWStatusPhotoMaxCol(count);
int cols = (count >= maxCols)? maxCols : count;
CGFloat photosW = cols * HWStatusPhotoWH + (cols - 1) * HWStatusPhotoMargin;
// 行数
int rows = (count + maxCols - 1) / maxCols;
CGFloat photosH = rows * HWStatusPhotoWH + (rows - 1) * HWStatusPhotoMargin;
return CGSizeMake(photosW, photosH);
}
@end
~~~
photo的代码
~~~
#import "HWStatusPhotoView.h"
#import "HWPhoto.h"
#import "UIImageView+WebCache.h"
@interface HWStatusPhotoView()
@property (nonatomic, weak) UIImageView *gifView;
@end
@implementation HWStatusPhotoView
- (UIImageView *)gifView
{
if (!_gifView) {
UIImage *image = [UIImage imageNamed:@"timeline_image_gif"];
UIImageView *gifView = [[UIImageView alloc] initWithImage:image];
[self addSubview:gifView];
self.gifView = gifView;
}
return _gifView;
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// 内容模式
self.contentMode = UIViewContentModeScaleAspectFill;
// 超出边框的内容都剪掉
self.clipsToBounds = YES;
}
return self;
}
- (void)setPhoto:(HWPhoto *)photo
{
_photo = photo;
// 设置图片
[self sd_setImageWithURL:[NSURL URLWithString:photo.thumbnail_pic] placeholderImage:[UIImage imageNamed:@"timeline_image_placeholder"]];
// 显示\隐藏gif控件
// 判断是够以gif或者GIF结尾
self.gifView.hidden = ![photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"];
}
- (void)layoutSubviews
{
[super layoutSubviews];
self.gifView.x = self.width - self.gifView.width;
self.gifView.y = self.height - self.gifView.height;
}
@end
~~~
## 三:注意地方
### 显示\隐藏gif控件
~~~
// 判断是够以gif或者GIF结尾
self.gifView.hidden = ![photo.thumbnail_pic.lowercaseString hasSuffix:@"gif"];
~~~
### 字符串分类根据字符串字体和最大宽度来得到所占据的高度宽度
~~~
/**
* 根据字符串字体和最大宽度来得到所占据的高度宽度
*
* @param font 字体
* @param maxW 最大宽度
*
* @return 长宽size
*/
- (CGSize)sizeWithFont:(UIFont *)font maxW:(CGFloat)maxW
{
NSMutableDictionary *attrs = [NSMutableDictionary dictionary];
attrs[NSFontAttributeName] = font;
CGSize maxSize = CGSizeMake(maxW, MAXFLOAT);
return [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size;
}
/**
* 在宽度为最大值时候根据字体得到宽高
*
* @param font 字体
*
* @return 长宽size
*/
- (CGSize)sizeWithFont:(UIFont *)font
{
return [self sizeWithFont:font maxW:MAXFLOAT];
}
~~~
### UIImageView图片设置
~~~
/**
UIViewContentModeScaleToFill : 图片拉伸至填充整个UIImageView(图片可能会变形)
UIViewContentModeScaleAspectFit : 图片拉伸至完全显示在UIImageView里面为止(图片不会变形)
UIViewContentModeScaleAspectFill :
图片拉伸至 图片的宽度等于UIImageView的宽度 或者 图片的高度等于UIImageView的高度 为止
UIViewContentModeRedraw : 调用了setNeedsDisplay方法时,就会将图片重新渲染
UIViewContentModeCenter : 居中显示
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
经验规律:
1.凡是带有Scale单词的,图片都会拉伸
2.凡是带有Aspect单词的,图片都会保持原来的宽高比,图片不会变形
*/
// 内容模式self(imageView对象)
self.contentMode = UIViewContentModeScaleAspectFill;
// 超出边框的内容都剪掉
self.clipsToBounds = YES;
~~~
(9)微博模型之时间相关重要操作,判断刚刚,昨天,今年等等
最后更新于:2022-04-01 07:27:12
## 一:效果
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d997f634.jpg)
—-因为本人黑苹果,系统时间乱跳 时间显示的不准,但是代码没有问题
## 二:实现代码
~~~
/**
1.今年
1> 今天
* 1分内: 刚刚
* 1分~59分内:xx分钟前
* 大于60分钟:xx小时前
2> 昨天
* 昨天 xx:xx
3> 其他
* xx-xx xx:xx
2.非今年
1> xxxx-xx-xx xx:xx
*/
- (NSString *)created_at
{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
// 如果是真机调试,转换这种欧美时间,需要设置locale
fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
// 设置日期格式(声明字符串里面每个数字和单词的含义)
// E:星期几
// M:月份
// d:几号(这个月的第几天)
// H:24小时制的小时
// m:分钟
// s:秒
// y:年
fmt.dateFormat = @"EEE MMM dd HH:mm:ss Z yyyy";
// _created_at = @"Tue Sep 30 17:06:25 +0600 2014";
// 微博的创建日期
NSDate *createDate = [fmt dateFromString:_created_at];
// 当前时间
NSDate *now = [NSDate date];
// 日历对象(方便比较两个日期之间的差距)
NSCalendar *calendar = [NSCalendar currentCalendar];
// NSCalendarUnit枚举代表想获得哪些差值
NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
// 计算两个日期之间的差值
NSDateComponents *cmps = [calendar components:unit fromDate:createDate toDate:now options:0];
if ([createDate isThisYear]) { // 今年
if ([createDate isYesterday]) { // 昨天
fmt.dateFormat = @"昨天 HH:mm";
return [fmt stringFromDate:createDate];
} else if ([createDate isToday]) { // 今天
if (cmps.hour >= 1) {
return [NSString stringWithFormat:@"%d小时前", cmps.hour];
} else if (cmps.minute >= 1) {
return [NSString stringWithFormat:@"%d分钟前", cmps.minute];
} else {
return @"刚刚";
}
} else { // 今年的其他日子
fmt.dateFormat = @"MM-dd HH:mm";
return [fmt stringFromDate:createDate];
}
} else { // 非今年
fmt.dateFormat = @"yyyy-MM-dd HH:mm";
return [fmt stringFromDate:createDate];
}
}
~~~
### 时间分类来做判断
这里用到了时间分类来做判断是否是今天啦,是否是明天啦之类的东西,总之,这个很强大了
~~~
//
// NSDate+Extension.m
// 黑马微博2期
//
// Created by apple on 14-10-18.
// Copyright (c) 2014年 heima. All rights reserved.
//
#import "NSDate+Extension.h"
@implementation NSDate (Extension)
/**
* 判断某个时间是否为今年
*/
- (BOOL)isThisYear
{
NSCalendar *calendar = [NSCalendar currentCalendar];
// 获得某个时间的年月日时分秒
NSDateComponents *dateCmps = [calendar components:NSCalendarUnitYear fromDate:self];
NSDateComponents *nowCmps = [calendar components:NSCalendarUnitYear fromDate:[NSDate date]];
return dateCmps.year == nowCmps.year;
}
/**
* 判断某个时间是否为昨天
*/
- (BOOL)isYesterday
{
NSDate *now = [NSDate date];
// date == 2014-04-30 10:05:28 --> 2014-04-30 00:00:00
// now == 2014-05-01 09:22:10 --> 2014-05-01 00:00:00
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
// 2014-04-30
NSString *dateStr = [fmt stringFromDate:self];
// 2014-10-18
NSString *nowStr = [fmt stringFromDate:now];
// 2014-10-30 00:00:00
NSDate *date = [fmt dateFromString:dateStr];
// 2014-10-18 00:00:00
now = [fmt dateFromString:nowStr];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
NSDateComponents *cmps = [calendar components:unit fromDate:date toDate:now options:0];
return cmps.year == 0 && cmps.month == 0 && cmps.day == 1;
}
/**
* 判断某个时间是否为今天
*/
- (BOOL)isToday
{
NSDate *now = [NSDate date];
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-dd";
NSString *dateStr = [fmt stringFromDate:self];
NSString *nowStr = [fmt stringFromDate:now];
return [dateStr isEqualToString:nowStr];
}
@end
~~~
## 三:补充
星期和月份英文
一月 January 简写 Jan.
二月 February 简写 Feb.
三月 March 简写 Mar.
四月 April 简写 Apr.
五月 May 简写 May
六月 June 简写 Jun.
七月 July 简写 Jul.
八月 August 简写 Aug.
九月September 简写Sep.
十月 October 简写 Oct.
十一月November 简写 Nov.
十二月December 简写 Dec.
星期一: Mon.=Monday
星期二: Tue.=Tuesday
星期三: Wed.=Wednesday
星期四: Thu.=Thursday
星期五: Fri.=Friday
星期六: Sat.=Saturday
星期天: Sun.=Sunday
(8)用AFNetworking和SDWebImage简单加载微博数据
最后更新于:2022-04-01 07:27:09
## 一:效果
没有图文混排,也没有复杂的UI,仅仅是简单的显示出微博数据,主要介绍AFNetworking和SDWebImage的简单用法
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d992ef9e.jpg)
## 二:加载数据AFNetworking
### AFNetworking用法
AFNetworking的用法大体有三步:
一:下载第三方框架(githup也好,百度也好,多的是)
二:导入头文件 `#import "AFNetworking.h"`
三:开始写代码(以上两步所有的第三方框架都通用)
1,请求管理者
~~~
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
~~~
2,拼接请求参数
~~~
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"*****"] = @"*****";
params[@"*****"] = @"*****";
params[@"*****"] = @"*****";
。。。。
///可以写很多参数
~~~
3,发送请求
~~~
[mgr GET:@"https:请求的网址" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
//这里写请求成功用的代码
NSLog(@"请求成功 --- %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//这里写请求失败用的代码
NSLog(@"请求失败 --- %@",error);
}];
~~~
下面贴出微博项目中的代码
### 加载最新的微博数据
~~~
/**
* //加载最新的微博数据
*
*
*/
-(void)loadNewStatus
{
//1,请求管理者
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
//2,拼接请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
HWAccount *account = [HWAccountTool account];
params[@"access_token"] = account.access_token;
// params[@"count"] = @20;
//3,发送请求
[mgr GET:@"https://api.weibo.com/2/statuses/friends_timeline.json" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
HWLog(@"请求成功 --- %@", responseObject);
//取得微博数组
self.statuses = responseObject[@"statuses"];
//刷新表格
[self.tableView reloadData];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
HWLog(@"请求失败 --- %@",error);
}];
}
~~~
## 三:SDWebImage用法
SDWebImage的用法大体有三步:
一:下载第三方框架(githup也好,百度也好,多的是)
二:导入头文件 `#import "UIImageView+WebCache.h" (这里面很多头文件,看自己具体需要那种了)`
三:开始写代码(以上两步所有的第三方框架都通用)
这个代码写起来就更简单了,例如微博中我们想要让他自己下载缓存一张图片用作每个tableViewCell的图片,并且显示一张占位图片,一句代码就搞定了
~~~
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:placehoder];
~~~
然后需要做防止程序内存溢出的操作
一:在程序AppDelegate 中写入头文件`#import "SDWebImageManager.h"`
二:调用方法,在整个程序内存警报时候调用`-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application
`
三:方法内写入
~~~
//整个程序内存警报时候调用
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
SDWebImageManager *mgr = [SDWebImageManager sharedManager];
//1,取消下载
[mgr cancelAll];
//2,清除内存中的所有图片
[mgr.imageCache clearMemory];
}
~~~
这里贴出cell全部代码供参考
~~~
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"status";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
//用indexPathRow取出对应的一条微博字典
NSDictionary *status = self.statuses[indexPath.row];
//设置微博作者
NSDictionary *user = status[@"user"];
cell.textLabel.text = user[@"name"];
//设置微博内容
cell.detailTextLabel.text = status[@"text"];
//设置微博头像
NSString *imageUrl = user[@"profile_image_url"];
//占位图
UIImage *placehoder = [UIImage imageNamed:@"avatar_default_small"];
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:placehoder];
return cell;
}
~~~
(7)程序启动新特性用UICollectionViewController实现
最后更新于:2022-04-01 07:27:07
## 一:效果
这里实现了大多数app都会有的软件新特性的功能,用的是UICollectionViewController实现的
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d98d93f5.jpg)
## 二:思路
这里用了UICollectionViewController实现,就是做一个没有间隙,每个cell都是一个屏幕的UICollectionViewController,自定义的。然后把下面的UIPageControl 还有最后一页的开始以及分享按钮放入就OK了。
调用的时候,首先获取当前的app的版本号,然后再获取上一个版本。进行两个版本的比较。当前版本和上一个版本不同,当前版本是从infoDictionary中拿到的,上一个版本是从自己存的NSUserDefaults 中的NYVersionKey拿到的,并且苹果允许上传小于当前版本的app,如果是第一个版本时候,上一个版本还没有值,也会不同。
根据结果设置window的不同根控制器。
自定义UICollectionViewController步骤:
要注意:
1.初始化的时候设置布局参数
2.collertionView必须注册cell
3.自定义cell
## 三:代码
调用部分代码:AppDelegate
~~~
//1,获取当前的版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[@"CFBundleVersion"];
//2,获取上一次的版本号
NSString *lastVersion = [[NSUserDefaults standardUserDefaults]objectForKey:NYVersionKey];
NYLog(@"currentVersion == %@ , lastVersion == %@ ",currentVersion, lastVersion);
//判断是否有新的版本
if ([currentVersion isEqualToString:lastVersion]) {
//如果没有新的版本(当前版本和上一个版本不同,当前版本是从infoDictionary中拿到的,上一个版本是从自己存的NSUserDefaults 中的NYVersionKey拿到的,并且苹果允许上传小于当前版本的app,如果是第一个版本时候,上一个版本还没有值,也会不同。)
//创建tabBarVC
NYTabBarController *tabBarVC = [[NYTabBarController alloc]init];
//设置窗口跟控制器
self.window.rootViewController = tabBarVC;
}else{//如果有新的版本
//进入新特性界面
NYNewFeatureController *newFeatureVC = [[NYNewFeatureController alloc]init];
newFeatureVC.view.backgroundColor = [UIColor redColor];
self.window.rootViewController = newFeatureVC;
//用偏好设置,保存当前版本。
[[NSUserDefaults standardUserDefaults]setObject:currentVersion forKey:NYVersionKey];
}
~~~
* * *
自定义的collectionViewController
### NYNewFeatureController.m
~~~
//
// NYNewFeatureController.m
// 猫猫微博
//
// Created by apple on 15-8-1.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYNewFeatureController.h"
#import "NYNewFeatureCell.h"
@interface NYNewFeatureController ()
@property (nonatomic, weak) UIPageControl *control;
@end
@implementation NYNewFeatureController
static NSString * const reuseIdentifier = @"cell";
- (void)viewDidLoad {
[super viewDidLoad];
//注册cell,默认就会创建这个类型的cell
[self.collectionView registerClass:[NYNewFeatureCell class] forCellWithReuseIdentifier:reuseIdentifier];
//分页
self.collectionView.pagingEnabled = YES;
//取消弹簧效果
self.collectionView.bounces = NO;
//不显示滚动条
self.collectionView.showsHorizontalScrollIndicator = NO;
// 添加pageController
[self setUpPageControl];
// Do any additional setup after loading the view.
}
// 添加pageController
- (void)setUpPageControl
{
// 添加pageController,只需要设置位置,不需要管理尺寸
UIPageControl *control = [[UIPageControl alloc] init];
control.numberOfPages = 4;
control.pageIndicatorTintColor = [UIColor blackColor];
control.currentPageIndicatorTintColor = [UIColor redColor];
// 设置center
control.center = CGPointMake(self.view.width * 0.5, self.view.height);
_control = control;
[self.view addSubview:control];
}
/*使用UICollectionViewController要注意:
1.初始化的时候设置布局参数
2.collertionView必须注册cell
3.自定义cell
*/
-(instancetype)init
{
//
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
//设置cell的尺寸
layout.itemSize = [UIScreen mainScreen].bounds.size;
//清空cell间隔的行距
layout.minimumLineSpacing = 0;
//设置cell的滑动方向
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
return [super initWithCollectionViewLayout:layout];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UICollectionView代理和数据源
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 4;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
// dequeueReusableCellWithReuseIdentifier
// 1.首先从缓存池里取cell
// 2.看下当前是否有注册Cell,如果注册了cell,就会帮你创建cell
// 3.没有注册,报错
NYNewFeatureCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
// 拼接图片名称 3.5 320 480
CGFloat screenH = [UIScreen mainScreen].bounds.size.height;
NSString *imageName = [NSString stringWithFormat:@"new_feature_%ld",indexPath.row + 1];
if (screenH > 480) { // 5 , 6 , 6 plus
imageName = [NSString stringWithFormat:@"new_feature_%ld-568h",indexPath.row + 1];
}
cell.image = [UIImage imageNamed:imageName];
[cell setIndexPath:indexPath count:4];
return cell;
}
#pragma mark - UIScrollView代理
// 只要一滚动就会调用
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
// 获取当前的偏移量,计算当前第几页
int page = scrollView.contentOffset.x / scrollView.bounds.size.width + 0.5;
// 设置页数
_control.currentPage = page;
}
@end
~~~
自定义的cell
### NYNewFeatureCell.h
~~~
//
// NYNewFeatureCell.h
// 猫猫微博
//
// Created by apple on 15-8-1.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface NYNewFeatureCell : UICollectionViewCell
@property (nonatomic, strong) UIImage *image;
// 判断是否是最后一页
- (void)setIndexPath:(NSIndexPath *)indexPath count:(int)count;
@end
~~~
### NYNewFeatureCell.m
~~~
//
// NYNewFeatureCell.m
// 猫猫微博
//
// Created by apple on 15-8-1.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYNewFeatureCell.h"
#import "NYTabBarController.h"
@interface NYNewFeatureCell()
@property (nonatomic, weak) UIImageView *imageView;
//分享按钮
@property (nonatomic, weak) UIButton *shareButton;
//开始按钮
@property (nonatomic, weak) UIButton *startButton;
@end
@implementation NYNewFeatureCell
//分享按钮懒加载
- (UIButton *)shareButton
{
if (_shareButton == nil) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@"分享给大家" forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"new_feature_share_false"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"new_feature_share_true"] forState:UIControlStateSelected];
[btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn sizeToFit];
[self.contentView addSubview:btn];
_shareButton = btn;
}
return _shareButton;
}
//开始按钮懒加载
- (UIButton *)startButton
{
if (_startButton == nil) {
UIButton *startBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[startBtn setTitle:@"开始微博" forState:UIControlStateNormal];
[startBtn setBackgroundImage:[UIImage imageNamed:@"new_feature_finish_button"] forState:UIControlStateNormal];
[startBtn setBackgroundImage:[UIImage imageNamed:@"new_feature_finish_button_highlighted"] forState:UIControlStateHighlighted];
[startBtn sizeToFit];
[startBtn addTarget:self action:@selector(start) forControlEvents:UIControlEventTouchUpInside];
[self addSubview:startBtn];
_startButton = startBtn;
}
return _startButton;
}
-(UIImageView *)imageView
{
if (_imageView == nil) {
UIImageView *imageV = [[UIImageView alloc]init];
_imageView = imageV;
// 注意:一定要加载contentView
[self.contentView addSubview:imageV];
}
return _imageView;
}
// 布局子控件的frame
-(void)layoutSubviews
{
[super layoutSubviews];
self.imageView.frame = self.bounds;
// 分享按钮
self.shareButton.center = CGPointMake(self.width * 0.5, self.height * 0.8);
// 开始按钮
self.startButton.center = CGPointMake(self.width * 0.5, self.height * 0.9);
}
-(void)setImage:(UIImage *)image
{
_image = image;
self.imageView.image = image;
}
// 判断当前cell是否是最后一页
-(void)setIndexPath:(NSIndexPath *)indexPath count:(int)count
{
if (indexPath.row == count - 1) { // 最后一页,显示分享和开始按钮
self.shareButton.hidden = NO;
self.startButton.hidden = NO;
}else{ // 非最后一页,隐藏分享和开始按钮
self.shareButton.hidden = YES;
self.startButton.hidden = YES;
}
}
// 点击开始微博的时候调用
- (void)start
{
// 进入tabBarVc
NYTabBarController *tabBarVc = [[NYTabBarController alloc] init];
// 切换根控制器:可以直接把之前的根控制器清空
NYKeyWindow.rootViewController = tabBarVc;
}
@end
~~~
(6)导航控制器NavigationController 的滑动回退功能实现
最后更新于:2022-04-01 07:27:05
## 一:效果
第二篇里面写了怎样自定义navigation实现自定义的导航控制器左右按钮样式,但是当我们自己实现后,系统自带的向右边滑动来实现回退的功能就不能用了。
这里主要实现滑动回退功能
。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d98a6564.jpg)
## 二:代码实现思路
首先 在 NYNavigationController.m中放一个popDelegate来放置要更改的手势代理对象
~~~
@interface NYNavigationController ()<UINavigationControllerDelegate>
@property (nonatomic, strong) id popDelegate;
@end
~~~
重写 UINavigationControllerDelegate 的方法`- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated`
viewDidLoad中设置代理方法,并且预先设置手势代理用来还原
~~~
- (void)viewDidLoad {
[super viewDidLoad];
//记住手势代理 用来还原
_popDelegate = self.interactivePopGestureRecognizer.delegate;
self.delegate = self;
}
~~~
~~~
//导航控制器跳转完成的控制器
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self.viewControllers[0]) { // 是根控制器
//还原手势代理
self.interactivePopGestureRecognizer.delegate = _popDelegate;
}else{ // 非根控制器
//设置手势代理为空,就可以实现滑动了
//实现滑动返回功能
//清空滑动返回手势的代理,就能实现滑动返回功能了。
self.interactivePopGestureRecognizer.delegate = nil;
}
}
~~~
## 三: 全部navigationController的代码
内部包括设置左右按钮等等功能
~~~
//
// NYNavigationController.m
// 猫猫微博
//
// Created by apple on 15-7-29.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYNavigationController.h"
#import "UIBarButtonItem+Item.h"
@interface NYNavigationController ()<UINavigationControllerDelegate>
@property (nonatomic, strong) id popDelegate;
@end
@implementation NYNavigationController
+ (void)initialize
{
// 获取当前类下面的UIBarButtonItem
UIBarButtonItem *item = [UIBarButtonItem appearanceWhenContainedIn:self, nil];
// 设置导航条按钮的文字颜色 为黄色
NSMutableDictionary *titleAttr = [NSMutableDictionary dictionary];
titleAttr[NSForegroundColorAttributeName] = [UIColor orangeColor];
[item setTitleTextAttributes:titleAttr forState:UIControlStateNormal];
}
- (void)viewDidLoad {
[super viewDidLoad];
//记住手势代理 用来还原
_popDelegate = self.interactivePopGestureRecognizer.delegate;
self.delegate = self;
}
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[super pushViewController:viewController animated:animated];
// 设置非根控制器导航条内容
if (self.viewControllers.count != 0) { //非根控制器
//设置导航条的内容
//设置导航条左边和右边
//如果把导航条上的返回按钮覆盖了,那么就没有了滑动返回功能
//设置左边按钮
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_back"] highImage:[UIImage imageNamed:@"navigationbar_back_highlighted"] target:self action:@selector(backToPre) forControlEvents:UIControlEventTouchUpInside];
//设置右边按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem barButtonItemWithImage:[UIImage imageNamed:@"navigationbar_more"] highImage:[UIImage imageNamed:@"navigationbar_more_highlighted"] target:self action:@selector(backToRoot ) forControlEvents:UIControlEventTouchUpInside];
}
}
-(void)backToPre{
//返回上一个控制器
[self popViewControllerAnimated:YES];
}
-(void)backToRoot{
//返回根控制器
[self popToRootViewControllerAnimated:YES];
}
#pragma mark - UINavigationControllerDelegate 实现滑动回退功能
//导航控制器跳转完成的控制器
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (viewController == self.viewControllers[0]) { // 是根控制器
//还原手势代理
self.interactivePopGestureRecognizer.delegate = _popDelegate;
}else{ // 非根控制器
//设置手势代理为空,就可以实现滑动了
//实现滑动返回功能
//清空滑动返回手势的代理,就能实现滑动返回功能了。
self.interactivePopGestureRecognizer.delegate = nil;
}
}
@end
~~~
## 四:注意
设置手势代理为空后必须要在该用的时候给设置回去,系统内部东西不能随便乱改,要么会出现难以预料的bug。在跟控制器的时候不小心做了回退滑动那样的操作会让再次进入下一个页面的导航控制器的右边按钮点击无效,app就崩溃了。
~~~
self.interactivePopGestureRecognizer.delegate = nil;
~~~
(5)微博自定义搜索框searchBar
最后更新于:2022-04-01 07:27:02
## 一:效果
用UITextField简单定义一个搜索框
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d98916b2.jpg)
## 二:调用:
调用的代码,很简单,直接init就可以,以后加功能自己添加就行了。
~~~
- (void)viewDidLoad {
[super viewDidLoad];
// 创建搜索框
NYSearchBar *searchBar = [[NYSearchBar alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 35)];
searchBar.placeholder = @"猫猫搜索";
// 设置titleView为搜索框
self.navigationItem.titleView = searchBar;
}
~~~
## 三:代码:
NYSearchBar.m文件内容
NYSearchBar.h文件里面没有东西,
思路很简单,就是左边放一个图片而已,可以自己添加其他东东。
~~~
//
// NYSearchBar.m
// 猫猫微博
//
// Created by apple on 15-7-29.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYSearchBar.h"
@implementation NYSearchBar
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.font = [UIFont systemFontOfSize:13];
self.background = [UIImage imageWithStretchableName:@"searchbar_textfield_background"];
// 设置左边的view
// initWithImage:默认UIImageView的尺寸跟图片一样
UIImageView *imageV = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"searchbar_textfield_search_icon"]];
// 为了空出左边一小块设置的
imageV.width += 10;
imageV.contentMode = UIViewContentModeCenter;
self.leftView = imageV;
// 一定要设置,想要显示搜索框左边的视图,一定要设置左边视图的模式
self.leftViewMode = UITextFieldViewModeAlways;
}
return self;
}
@end
~~~
推荐一个iOS学习帅气的网站 : code4app
各种各样的iOS效果和源码都用,随下随用。
(4)微博自定义tabBar中间的添加按钮
最后更新于:2022-04-01 07:27:00
## 一:效果图
自定义tabBar实现最下面中间的添加按钮
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9851330.jpg)
## 二:思路
首先在自己的tabBarController中把系统的tabBar设置成自己的tabBar(NYTabBar),这里由于tabBar的属性是readonly的,所以我们要用kvc或者是消息管理来设置他
然后就写自己的NYTabBar。这个写起来首先 遍历当前tabBar上的所有view,如果是UITabBarButton,就取出来重新设置他们的位置,并且重新赋值,接下来就是空出中间的添加的位置,然后把添加按钮放上去,就ok了。
## 三:代码
### 调用
首先是如何调用的代码
~~~
//自定义tabBar
NYTabBar *tabBar = [[NYTabBar alloc]initWithFrame:self.tabBar.frame];
//用kvc把readly的tabBar属性改成自定义的
[self setValue:tabBar forKey:@"tabBar"];
~~~
### NYTabBar.m
NYTabBar.h文件就不写了 ,里面啥都没有
NYTabBar.m:
~~~
//
// NYTabBar.m
// 猫猫微博
//
// Created by apple on 15-7-24.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYTabBar.h"
@interface NYTabBar()
/**
* 添加增加按钮
*/
@property (nonatomic, weak) UIButton *addButton;
@end
@implementation NYTabBar
-(UIButton *)addButton
{
if (_addButton == nil) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add"] forState:UIControlStateNormal];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button"] forState:UIControlStateNormal];
[btn setImage:[UIImage imageNamed:@"tabbar_compose_icon_add_highlighted"] forState:UIControlStateHighlighted];
[btn setBackgroundImage:[UIImage imageNamed:@"tabbar_compose_button_highlighted"] forState:UIControlStateHighlighted];
_addButton = btn;
//是按钮的尺寸默认跟背景图片一样大
[btn sizeToFit];
[self addSubview:_addButton];
}
return _addButton;
}
//调整子空间的位置
-(void)layoutSubviews
{
[super layoutSubviews];
CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnY = 0;
CGFloat btnW = w / 5;
CGFloat btnH = h;
int i = 0;
//1 , 遍历当前tabBar上的所有view
for (UIView *tabBarBtn in self.subviews) {
//2,如果是UITabBarButton,就取出来重新设置他们的位置
if ([tabBarBtn isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
btnX = i * btnW;
tabBarBtn.frame = CGRectMake(btnX, btnY, btnW, btnH);
//当到了第二个时候,再加一个位置空竹添加按钮的位置。
if (i==1) {
i++;
}
i++;
}
}
//设置添加按钮 add按钮的位置
self.addButton.center = CGPointMake(w * 0.5, h * 0.5);
}
@end
~~~
## 四:补充
调用的时候还可以用消息管理
~~~
//自定义tabBar
NYTabBar *tabBar = [[NYTabBar alloc]initWithFrame:self.tabBar.frame];
/*这个地方还有一种用消息管理设置的,这样也可以,使用个步骤是
1:先导入头文件#import <objc/message.h>
2:到项目中Build Settings中查找msg ,然后把yes改成no
3:代码写objc_msgSend调用就行了
注意:这样的方法框架中比较多,目的为了不让人看懂,还有显得c牛逼,——————没啥鸟用。。
*/
//用消息管理设置
objc_msgSend(self, @selector(setTabBar:),tabBar);
~~~
步骤:
1:先导入头文件
~~~
#import <objc/message.h>
~~~
2:到项目中Build Settings中查找msg ,然后把yes改成no
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9866aff.jpg)
3:代码写objc_msgSend调用就行了
注意:这样的方法框架中比较多,目的为了不让人看懂,还有显得c牛逼,——————没啥鸟用。。
(3)微博主框架-UIImage防止iOS7之后自动渲染_定义分类
最后更新于:2022-04-01 07:26:58
## 一:效果对比
当我们设置tabBarController的tabBarItem.image的时候,默认情况下会出现图片变成蓝色的效果,这是因为ios7之后会对图片自动渲染成蓝色
代码
~~~
UIViewController *home = [[UIViewController alloc]init];
//设置标题
home.tabBarItem.title = @"首页";
//设置未选中时候的图片
home.tabBarItem.image = [UIImage imageNamed:@"tabbar_home"];
//设置选中时候的图片
home.tabBarItem.selectedImage = [UIImage imageNamed:@"tabbar_home_selected"];
home.view.backgroundColor = [UIColor blueColor];
~~~
效果:![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d979e85e.jpg)
我们需要改成这样的效果
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97b173c.jpg)
## 二:解决方法
解决方法有两个,一种是用xcode自带的功能设置,另一种是用纯代码的方式来解决——之前猫猫见过自定义的tabBar。。。弱爆了(有增加了一点牛zhuang掰bi手段 )
### 第一种,代码方式解决
代码:
~~~
//首页
UIViewController *home = [[UIViewController alloc]init];
home.tabBarItem.title = @"首页";
home.tabBarItem.image = [UIImage imageNamed:@"tabbar_home"];
UIImage *selImage = [UIImage imageNamed:@"tabbar_home_selected"];
//设置渲染模式为原始
home.tabBarItem.selectedImage = [selImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
home.view.backgroundColor = [UIColor blueColor];
~~~
注意上下对比下原来代码,
### 第二种方法
在图片中找到图片 第三个 –》 render as(渲染器) –》 original image(原始的图片)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97c3e12.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97e9ca6.jpg)
选中第二个 original image 就ok了 不过这方法要挨着设置
## 三:建立UIImage的分类
直接建立分类 一句代码搞定
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9816d64.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d984141d.jpg)
然后写代码了就是
### UIImage+image.h中的代码
~~~
//
// UIImage+image.h
// 猫猫微博
//
// Created by apple on 15-7-22.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (image)
/**
* 加载最原始的图片,没有渲染过
*
* @param imageName 图片名称
*
* @return UIImage对象
*/
+(instancetype)imageWithOriginalName:(NSString *)imageName;
@end
~~~
### UIImage+image.m中的代码
~~~
//
// UIImage+image.m
// 猫猫微博
//
// Created by apple on 15-7-22.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "UIImage+image.h"
@implementation UIImage (image)
+(instancetype)imageWithOriginalName:(NSString *)imageName
{
//ios7之后会自动渲染,不让渲染有两种方法
//1:在图片中找到图片 第三个 --》 render as(渲染器) --》 original image(原始的图片)
//2:代码设置
UIImage *image = [UIImage imageNamed:imageName];
//设置渲染模式为原始
return [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
@end
~~~
## 四:调用
这样调用的时候直接一句代码就可以完成了
首先要在头文件导入
~~~
#import "UIImage+image.h"
~~~
然后调用就这样掉
~~~
home.tabBarItem.selectedImage = [UIImage imageWithOriginalName:@"tabbar_home_selected"];
~~~
偶了
* * *
ps:注意代码抽取,更好用,简单说,两句代码能用一句写,那就抽出来,以前猫猫就是觉得一两句抽不抽的无所谓,复制下就行了,前段时间帮忙做项目吃了大亏 哭一个先,%>_<%
(2)微博主框架-自定义导航控制器NavigationController
最后更新于:2022-04-01 07:26:56
## 一:添加导航控制器
上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController)。
为啥要做自定义呢,因为为了更好地封装代码,并且系统的UINavigationController不能满足我们的需求了,所以得自定义。
首先,我们在NYTabBarViewController的
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage方法中写了这个:
~~~
// 先给外面传进来的小控制器 包装 一个导航控制器
NYNavigationController *nav = [[NYNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:nav];
~~~
来给设置的各个Controller包装一个导航控制器。
这时候系统会自动给添加一个。然后呢我们要对导航控制器进行改进。
### 框架结构
目前情况下的UI架构如下图所示:一个IWTabBarController拥有4个导航控制器作为子控制器,每个导航控制器都有自己的根控制器(栈底控制器)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d96d5886.jpg)
* * *
### 重要代码
1.给控制器包装一个导航控制器并且放入tabbarController中
~~~
// 先给外面传进来的小控制器 包装 一个导航控制器
NYNavigationController *nav = [[NYNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:nav];
~~~
* * *
## 二:导航控制器左右item的设置
在NYMessageCenterViewController中我们添加了cell,并使之可以点击,点击后进入到另一个界面(test1) 再点击界面的view进入另外一个界面(test2)
首先放入20行假数据——UITableView的数据源方法
返回一组,20行,每行内容cell设置
~~~
#pragma mark - Table view data source 数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Return the number of rows in the section.
return 20;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *ID = @"ID";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];
}
cell.textLabel.text = [NSString stringWithFormat:@"test~~~~message - %d", indexPath.row];
return cell;
}
~~~
然后是cell的点击方法了 不用死记全部方法名字,简单敲一下tableview 查找didSele方法(学iOS对英语挺高老快了)灵活运用xcode的自动提示功能。
~~~
#pragma mark - 代理方法
//cell的点击事件
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NYTest1ViewController *test1 = [[NYTest1ViewController alloc] init];
test1.title = @"测试1控制器";
[test1.navigationController setNavigationBarHidden:NO];
[self.navigationController pushViewController:test1 animated:YES];
}
~~~
test1是我们自己做的一个测试类,其中我们做了两个如图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d96ee815.jpg)
这时候,我们的消息界面就有了cell的数据并且可以点击了。如图效果:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d970cdd6.jpg)
(到test2的push和1的一样,不过是用的view的touch方法)
这时候我们要做导航控制器的左右item了。
然后我们设置导航控制器的左右item (写私信按钮等)
如图:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97344b7.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9746bda.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9756390.jpg)
~~~
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"写私信" style:UIBarButtonItemStylePlain target:self action:@selector(composeMsg)];
//设置右侧按钮为不可点击状态
self.navigationItem.rightBarButtonItem.enabled = NO;
NYLog(@"NYMessageCenterViewController-viewDidLoad");
}
~~~
其中的UIBarButtonItem 的创建方法不是系统给的,而是我们为了实现黄色的效果自己写的分类实现的。
### 分类实现UIBarButtonItem的自定义创建方法:
~~~
//
// UIBarButtonItem+Extension.m
// 猫猫微博
//
// Created by apple on 15-6-4.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "UIBarButtonItem+Extension.h"
@implementation UIBarButtonItem (Extension)
/**
* 创建一个item
*
* @param target 点击item后调用哪个对象的方法
* @param action 点击item后调用target的哪个方法
* @param image 图片
* @param highImage 高亮的图片
*
* @return 创建完的item
*/
+(UIBarButtonItem *)itemWithTarget:(id)target action:(SEL)action image:(NSString *)image highImage:(NSString *)highImage
{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
//设置图片
[backBtn setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];
[backBtn setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];
[backBtn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
//设置尺寸
CGSize imageSize = backBtn.currentBackgroundImage.size;
backBtn.frame = CGRectMake(0, 0, imageSize.width, imageSize.height);
UIBarButtonItem *itemBtn = [[UIBarButtonItem alloc] initWithCustomView:backBtn];
return itemBtn;
}
@end
~~~
这里设置尺寸用到了
~~~
CGSize imageSize = backBtn.currentBackgroundImage.size;
~~~
在我们学习UI的transform的时候,我们知道 是不能直接这么设置size的,但是为啥这里能呢? 很简单 ,我们对UIView写了一个分类
~~~
//
// UIView+Extension.m
// 猫猫微博
//
// Created by apple on 15-6-2.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "UIView+Extension.h"
@implementation UIView (Extension)
-(void)setX:(CGFloat)x
{
CGRect frame = self.frame;
frame.origin.x = x;
self.frame = frame;
}
-(CGFloat)x
{
return self.frame.origin.x;
}
-(void)setY:(CGFloat)y
{
CGRect frame = self.frame;
frame.origin.y = y;
self.frame = frame;
}
-(CGFloat)y
{
return self.frame.origin.y;
}
-(void)setWidth:(CGFloat)width
{
CGRect frame = self.frame;
frame.size.width = width;
self.frame = frame;
}
-(CGFloat)width
{
return self.frame.size.width;
}
-(void)setHeight:(CGFloat)height
{
CGRect frame = self.frame;
frame.size.height = height;
self.frame = frame;
}
-(CGFloat)height
{
return self.frame.size.height;
}
-(void)setSize:(CGSize)size
{
CGRect frame = self.frame;
frame.size = size;
self.frame = frame;
}
-(CGSize)size
{
return self.frame.size;
}
-(void)setOrigin:(CGPoint)origin
{
CGRect frame = self.frame;
frame.origin = origin;
self.frame = frame;
}
-(CGPoint)origin
{
return self.frame.origin;
}
@end
~~~
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97344b7.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9746bda.jpg)
并且为了改变系统原生的 美丽的蓝色情调,换成微博的黄色。。。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9777370.jpg)
我们要重写NYNavigationController初始加载方法 (initialize)以及重写pushViewController方法,让push 的时候会自动带着箭头按钮和右边的更多按钮(UIBarButtonItem)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9756390.jpg)
~~~
//
// NYNavigationController.m
// 猫猫微博
//
// Created by apple on 15-6-4.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYNavigationController.h"
@interface NYNavigationController ()
@end
@implementation NYNavigationController
+(void)initialize
{
// 设置整个项目所有item的主题样式
UIBarButtonItem *item = [UIBarButtonItem appearance];
// 普通状态
NSMutableDictionary *textAttrsNormal = [NSMutableDictionary dictionary];
textAttrsNormal[NSForegroundColorAttributeName] = [UIColor orangeColor];
textAttrsNormal[NSFontAttributeName] = [UIFont systemFontOfSize:14];
[item setTitleTextAttributes:textAttrsNormal forState:UIControlStateNormal];
// 不可用状态
NSMutableDictionary *textAttrsDisabled = [NSMutableDictionary dictionary];
textAttrsDisabled[NSFontAttributeName] = [UIFont systemFontOfSize:14];
textAttrsDisabled[NSForegroundColorAttributeName] = [UIColor colorWithRed:0.6 green:0.6 blue:0.6 alpha:0.7];
[item setTitleTextAttributes:textAttrsDisabled forState:UIControlStateDisabled];
}
/**
* 重写这个方法目的:能够拦截所有push进来的控制器
*
* @param viewController 即将push进来的控制器
*/
-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// 这时push进来的控制器viewController,不是第一个子控制器(不是根控制器)
if (self.viewControllers.count > 0) {
/* 自动显示和隐藏tabbar */
viewController.hidesBottomBarWhenPushed = YES;
// 设置左边的箭头按钮
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(back) image:@"navigationbar_back" highImage:@"navigationbar_back_highlighted"];
// 设置右边的更多按钮
viewController.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(more) image:@"navigationbar_more" highImage:@"navigationbar_more_highlighted"];
}
[super pushViewController:viewController animated:animated];
}
-(void)back
{
#warning 这里要用self,不是self.navigationController
// 因为self本来就是一个导航控制器,self.navigationController这里是nil的
[self popViewControllerAnimated:YES];
}
-(void)more
{
//回到根
[self popToRootViewControllerAnimated:YES];
}
@end
~~~
最后就是各个页面的调用了
首页:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d97344b7.jpg)
~~~
- (void)viewDidLoad
{
[super viewDidLoad];
/* 设置导航栏上面的内容 */
self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(friendSearch) image:@"navigationbar_friendsearch" highImage:@"navigationbar_friendsearch_highlighted"];
self.navigationItem.rightBarButtonItem = [UIBarButtonItem itemWithTarget:self action:@selector(pop) image:@"navigationbar_pop" highImage:@"navigationbar_pop_highlighted"];
}
~~~
我:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9777370.jpg)
~~~
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"设置" style:0 target:self action:@selector(setting)];
}
~~~
消息里面的写私信(这里设置默认不可用状态)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9746bda.jpg)
~~~
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"写私信" style:UIBarButtonItemStylePlain target:self action:@selector(composeMsg)];
//设置右侧按钮为不可点击状态
self.navigationItem.rightBarButtonItem.enabled = NO;
NYLog(@"NYMessageCenterViewController-viewDidLoad");
}
~~~
(1)微博主框架-子控制器的添加
最后更新于:2022-04-01 07:26:53
## 一:简单介绍
这是新浪微博的iOS端项目,来自于黑马的一个实战项目。(本人没有培训,纯属自学,但人要学会感恩,虽然是自己买的学习资料,但是饮水思源!!)
主要分成五大模块,本次全部运用纯代码实现,其中会用到很多前面学过得内容,如果有的地方有重复的知识点,说明这个知识点真的很重要,没有时间看视频学习或者培训的朋友们,可以看猫猫的这一系列博客,猫猫会竭尽所能的完善他。
有什么不全面的地方,欢迎大家回复我,猫猫会尽快改正的。
## 二:建立项目导入素材
第一步首先我们要建立我们的项目了,在这儿我并没有用最新版的xcode6,而是用的xcode5.1,为什么用的5.1而不是6呢?
首先:我所学习的视频是用的xcode5.1,这是最主要的原因,猫猫作为一个体育生,自学编程两年所得到的经验就是,在看视频自学的时候尽可能让自己的一切与别人实体教学一样,猫猫曾经在学android时候就因为android 的sdk不一样,新出的碎片化跟视频中的操作不一样而大大打击学习的积极性。
其次:企业还有很多再用5.1甚至是4.1(据朋友说。。。)当然,这个也可以看出主要原因啦。不过猫猫建议,在学到一定水平的时候,多接收下新的知识,当然我觉得旧的更重要,不说咱国语有云,温故知新,万变不离其宗,学扎实旧的知识,新的知识上手搜easy。
建立项目
选择Single View Application 选择下一步
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d959e00a.jpg)
写入项目名称猫猫微博(名字随便) 选择下一步
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d95c636b.jpg)
然后就是下一步下一步了
因为我们要用纯代码,所以先删除其他没用的Controller还有Main.storyboard
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d95e47b3.jpg)
Remove References 表示只是在xcode中删除,但是在文件中还有。
Move To Trash 就代表,直接进入了系统废纸篓了
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d960b3a5.jpg)
然后导入素材(我们用到的图片) images.xcassets
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d961d361.jpg)
applcon里面的是在手机首页的那个图
launchimage是指得应用加载时候开始的那个图片
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9637323.jpg)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9650f6a.jpg)
对于第一个图片的空白位置,我们可以直接通过修改json文件来控制,当然,直接拖拽进去也可以(相当于修改json)
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d966aec0.jpg)
## 三:创建window
前面有博客写过程序运行时候会经过哪些步骤。
因为我们删除了Main.storyboard,这时候运行程序会报错,我们需要修改图里面的main 删除他,改成空
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d9680c4b.jpg)
这时候运行程序,将会是这样:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d96ae0e9.jpg)
乌七八黑。。。
然后我们要在NYAppDelegate.m来写代码了。
~~~
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//1.创建窗口
self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
//2.设置根控制器
NYTabBarViewController *tabbarC = [[NYTabBarViewController alloc] init];
self.window.rootViewController = tabbarC;
//3.显示窗口
[self.window makeKeyAndVisible];
return YES;
}
~~~
简单三步,就可以显示了。
自己写NYTabBarViewController.m
~~~
//
// NYTabBarViewController.m
// 猫猫微博
//
// Created by apple on 15-6-2.
// Copyright (c) 2015年 znycat. All rights reserved.
//
#import "NYTabBarViewController.h"
#import "NYHomeViewController.h"
#import "NYMessageCenterViewController.h"
#import "NYDiscoverViewController.h"
#import "NYProfileViewController.h"
#import "NYNavigationController.h"
@interface NYTabBarViewController ()
@end
@implementation NYTabBarViewController
-(void)viewDidLoad
{
[super viewDidLoad];
// 1.初始化子控制器
// 1.初始化子控制器
NYHomeViewController *home = [[NYHomeViewController alloc] init];
[self addChildVc:home title:@"首页" image:@"tabbar_home" selectedImage:@"tabbar_home_selected"];
NYMessageCenterViewController *messageCenter = [[NYMessageCenterViewController alloc] init];
[self addChildVc:messageCenter title:@"消息" image:@"tabbar_message_center" selectedImage:@"tabbar_message_center_selected"];
NYDiscoverViewController *discover = [[NYDiscoverViewController alloc] init];
[self addChildVc:discover title:@"发现" image:@"tabbar_discover" selectedImage:@"tabbar_discover_selected"];
NYProfileViewController *profile = [[NYProfileViewController alloc] init];
[self addChildVc:profile title:@"我" image:@"tabbar_profile" selectedImage:@"tabbar_profile_selected"];
}
/**
* 添加一个子控制器
*
* @param childVc 子控制器
* @param title 标题
* @param image 图片
* @param selectedImage 选中的图片
*/
- (void)addChildVc:(UIViewController *)childVc title:(NSString *)title image:(NSString *)image selectedImage:(NSString *)selectedImage
{
// 设置子控制器的文字
childVc.title = title; // 同时设置tabbar和navigationBar的文字
// childVc.tabBarItem.title = title; // 设置tabbar的文字
// childVc.navigationItem.title = title; // 设置navigationBar的文字
// 设置子控制器的图片
childVc.tabBarItem.image = [UIImage imageNamed:image];
childVc.tabBarItem.selectedImage = [[UIImage imageNamed:selectedImage]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// 设置文字的样式
NSMutableDictionary *textAttrs = [NSMutableDictionary dictionary];
textAttrs[NSForegroundColorAttributeName] = NYColor(123, 123, 123);
NSMutableDictionary *selectTextAttrs = [NSMutableDictionary dictionary];
selectTextAttrs[NSForegroundColorAttributeName] = [UIColor orangeColor];
[childVc.tabBarItem setTitleTextAttributes:textAttrs forState:UIControlStateNormal];
[childVc.tabBarItem setTitleTextAttributes:selectTextAttrs forState:UIControlStateSelected];
// 先给外面传进来的小控制器 包装 一个导航控制器
NYNavigationController *nav = [[NYNavigationController alloc] initWithRootViewController:childVc];
// 添加为子控制器
[self addChildViewController:nav];
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
@end
~~~
这里用到了面向对象的思路来设计代码,我们需要一个NYTabBarViewController,要创建他,谁最清楚呢?当然是他自己了,所以我们就把代码放到他自己里面。做好代码的重构。
而对于
“NYHomeViewController.h”
“NYMessageCenterViewController.h”
“NYDiscoverViewController.h”
“NYProfileViewController.h”
“NYNavigationController.h”
这些,大家先把他看做是tableViewController或者ViewController就可以了,就是一个个的类,还没有实现功能。
效果就是这样:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-01-20_569f1d96bec8f.jpg)
前言
最后更新于:2022-04-01 07:26:51
> 原文出处:[移动开发专栏文章](http://blog.csdn.net/column/details/iosweibo.html)
> 作者:[翟乃玉](http://blog.csdn.net/u013357243)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
#iOS新浪微博项目
> iOS新浪微博项目,猫猫自学微博项目的学习笔记,代码与学习素材笔记等等都有,主要分享经验记录难点。