项目实战No9 不等高cell高度 相册图片
来源:互联网 发布:淘宝怎么心极多点 编辑:程序博客网 时间:2024/06/05 11:39
一 日期处理
判断时间是不是今年
方法1:手机当前时间nowYear和selfYear比较
- (BOOL)isThisYear{NSCalendar *calendar = [NSCalendar currentCalendar];// 获得年NSInteger nowYear = [calendar component:NSCalendarUnitYear fromDate:[NSDate date]];NSInteger selfYear = [calendar component:NSCalendarUnitYear fromDate:self];return nowYear == selfYear;}
方法2:时间转字符串,比较字符串
- (BOOL)isThisYear{ NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy"; NSString *nowYear = [fmt stringFromDate:[NSDate date]]; NSString *selfYear = [fmt stringFromDate:self]; return [nowYear isEqualToString:selfYear];}
判断是否为今天
方法1:年月日是否都一样
- (BOOL)isToday{NSCalendar *calendar = [NSCalendar currentCalendar];NSDate *now = [NSDate date];return [calendar component:NSCalendarUnitYear fromDate:now] == [calendar component:NSCalendarUnitYear fromDate:self]&& [calendar component:NSCalendarUnitMonth fromDate:now] == [calendar component:NSCalendarUnitMonth fromDate:self]&& [calendar component:NSCalendarUnitDay fromDate:now] == [calendar component:NSCalendarUnitDay fromDate:self];}
方法2
- (BOOL)isToday{NSCalendar *calendar = [NSCalendar currentCalendar];NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear;NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];NSDateComponents *selfCmps = [calendar components:unit fromDate:self];return nowCmps.year == selfCmps.year&& nowCmps.month == selfCmps.month&& nowCmps.day == selfCmps.day;}
方法3
- (BOOL)isToday{NSDateFormatter *fmt = [[NSDateFormatter alloc] init];fmt.dateFormat = @"yyyy-MM-dd";NSString *nowString = [fmt stringFromDate:[NSDate date]];NSString *selfString = [fmt stringFromDate:self];return [nowString isEqualToString:selfString];}
- 是否为昨天,不能直接用天数相减,需要增加判断
- (BOOL)isYesterday{ NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy-MM-dd"; // 获得只有年月日的时间 NSString *nowString = [fmt stringFromDate:[NSDate date]]; NSDate *nowDate = [fmt dateFromString:nowString]; NSString *selfString = [fmt stringFromDate:self]; NSDate *selfDate = [fmt dateFromString:selfString]; // 比较 NSCalendar *calendar = [NSCalendar currentCalendar]; NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear; NSDateComponents *cmps = [calendar components:unit fromDate:selfDate toDate:nowDate options:0]; return cmps.year == 0 && cmps.month == 0 && cmps.day == 1;}
同理,用(return cmps.year == 0
&& cmps.month == 0
&& cmps.day == -1)可以判断是否为明天
时间逻辑运算
今年时间显示格式
- 今天
1> 时间差距 < 1分钟,显示为“刚刚”;
2> 1分钟 =< 时间差距 <= 59分钟,显示为“xx分钟前”;
3> 时间差距 >= 1小时,显示为“xx小时前”; - 昨天
1> 昨天时间格式显示为“18:06:56”; - 其它
1> 时间格式显示为“08-07 18:06:56”;
- 今天
非今年时间显示格式
- 统一显示为“2014-08-07 18:06:56”;
- (NSString *)created_at{ // 日期格式化类 NSDateFormatter *fmt = [[NSDateFormatter alloc] init]; fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss"; // NSString -> NSDate NSDate *createdAtDate = [fmt dateFromString:_created_at]; // 比较【发帖时间】和【手机当前时间】的差值 NSDateComponents *cmps = [createdAtDate intervalToNow]; if (createdAtDate.isThisYear) { if (createdAtDate.isToday) { // 今天 if (cmps.hour >= 1) { // 时间差距 >= 1小时 return [NSString stringWithFormat:@"%zd小时前", cmps.hour]; } else if (cmps.minute >= 1) { // 1分钟 =< 时间差距 <= 59分钟 return [NSString stringWithFormat:@"%zd分钟前", cmps.minute]; } else { return @"刚刚"; } } else if (createdAtDate.isYesterday) { // 昨天 fmt.dateFormat = @"昨天 HH:mm:ss"; return [fmt stringFromDate:createdAtDate]; } else { // 今年的其他时间 fmt.dateFormat = @"MM-dd HH:mm:ss"; return [fmt stringFromDate:createdAtDate]; } } else { // 非今年 return _created_at; }}
二 计算cell高度
Xib起名字注意:控制器加载Xib优先会加载没有..Controller的Xib,如果没有再加在..Controller的Xib
- 加载和xib类名一样的文件
+ (instancetype)viewFromXib{ return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];}
- xib建一个懒加载,cell的set方法频繁调用,会加载很多xib
- (XMGTopicPictureView *)pictureView{ if (!_pictureView) { XMGTopicPictureView *pictureView = [XMGTopicPictureView viewFromXib]; [self.contentView addSubview:pictureView]; _pictureView = pictureView; } return _pictureView;}
- 代码计算cell高度
- 标签高度+文字的高度+图片高度(判断)+底部工具条高度
#pragma mark - 代理方法- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ // cell的高度 CGFloat cellHeight = XMGTopicTextY; // 计算文字的高度 XMGTopic *topic = self.topics[indexPath.row]; CGFloat textW = XMGScreenW - 2 * XMGCommonMargin; CGFloat textH = [topic.text sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize:CGSizeMake(textW, MAXFLOAT)].height; cellHeight += textH + XMGCommonMargin; // 中间内容的高度 if (topic.type != XMGTopicTypeWord) { CGFloat contentW = textW; // 图片的高度 * 内容的宽度 / 图片的宽度 CGFloat contentH = topic.height * contentW / topic.width; cellHeight += contentH + XMGCommonMargin; } // 工具条的高度 cellHeight += XMGTopicToolbarH + XMGCommonMargin; return cellHeight;}
- 文字高度计算另一种写法
CGFloat textH = [topic.text boundingRectWithSize:CGSizeMake(textW, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:15]} context:nil].size.height;
计算cell高度,拖拽时候重复调用,浪费性能,抽取代码放到模型里
重写方法,增加if (_cellHeight == 0) 判断,cell高度只计算一次;
- 计算图片的frame
- 图片尺寸拿到,用layoutsubviews布局
- (void)layoutSubviews { [super layoutSubviews]; self.pictureView.frame = topic.contentFrame; }
- 会报错约束冲突
- 本来设置frame与最终显示效果不一样,注意下面属性:
// 清空自动伸缩属性 self.autoresizingMask = UIViewAutoresizingNone;
把cell的高度(cellHeight)和中间内容的frame(contentFrame)写到模型里面?
1. 模型是用来放数据的
2. 一个模型对应一个cellHeight和contentFrame
- 判断要不要添加gif标识
self.gifView.hidden = !topic.is_gif;
- 查看大图按钮是否隐藏
self.seeBigPictureButton.hidden = !topic.isBigPicture; if (topic.isBigPicture) { // 图片拉伸不带Scale就不会拉伸 self.imageView.contentMode = UIViewContentModeTop; self.imageView.clipsToBounds = YES; } else { self.imageView.contentMode = UIViewContentModeScaleToFill; // 拉伸到填充整个iamgeview self.imageView.clipsToBounds = NO; }
- 如何判断图片是否gif图
- 判断路径最后格式名
NSString *ext = topic.image1.pathExtension.lowercaseString; // 转换为小写gif self.gifView.hidden = ![ext isEqualToString:@"gif"];
取出文件第一个字节,可判断文件属于什么格式,前提要先下载完文件数据
三 下载进度条
- 设置展位图片的内容模式(View→Mode)
- Aspect Fit:伸缩到高度/宽度一致为止
- Aspect Fill:按宽高比伸缩到填充整个imageView,能看到整个图片为止
- 下载图片
// 进度条@property (weak, nonatomic) IBOutlet DALabeledCircularProgressView *progressView;
[self.imageView sd_setImageWithURL:[NSURL URLWithString:topic.image1] placeholderImage:nil options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // 每下载一点图片数据,就会调用一次这个block weakSelf.progressView.hidden = NO; weakSelf.progressView.roundedCorners = 5; weakSelf.progressView.progress = 1.0 * receivedSize / expectedSize; weakSelf.progressView.progressLabel.text = [NSString stringWithFormat:@"%.0f%%", weakSelf.progressView.progress * 100]; weakSelf.progressView.progressLabel.textColor = [UIColor whiteColor]; } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { // 当图片下载完毕后,就会调用这个block weakSelf.progressView.hidden = YES; }];
- 设置进度条圆角和颜色只需要调用一次
- (void)awakeFromNib{ // 清空自动伸缩属性 self.autoresizingMask = UIViewAutoresizingNone; self.progressView.roundedCorners = 5; self.progressView.progressLabel.textColor = [UIColor whiteColor]; self.imageView.userInteractionEnabled = YES; // 可以点击 [self.imageView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageClick)]];}
- 弹出大图片
- (void)imageClick{ if (self.imageView.image == nil) return; XMGSeeBigPictureViewController *seeBig = [[XMGSeeBigPictureViewController alloc] init]; seeBig.topic = self.topic; [self.window.rootViewController presentViewController:seeBig animated:YES completion:nil];}
四 保存大图片
- 查看大图控制器
- 图片尺寸超过屏幕高度,设置图片x和y为(0,0)
- 如果没有超过屏幕高度,居中显示
- (void)viewDidLoad { [super viewDidLoad]; // 滚动控件 UIScrollView *scrollView = [[UIScrollView alloc] init]; scrollView.frame = [UIScreen mainScreen].bounds; scrollView.backgroundColor = [UIColor blackColor]; scrollView.delegate = self; [self.view insertSubview:scrollView atIndex:0]; // 在数组最前面,保证所有控件放在前面 // 图片 UIImageView *imageView = [[UIImageView alloc] init]; [imageView sd_setImageWithURL:[NSURL URLWithString:self.topic.image1]]; [scrollView addSubview:imageView]; self.imageView = imageView; // 图片的尺寸 imageView.x = 0; imageView.width = XMGScreenW; imageView.height = self.topic.height * imageView.width / self.topic.width; if (imageView.height > XMGScreenH) { // 图片过长 imageView.y = 0; scrollView.contentSize = CGSizeMake(0, imageView.height); } else { // 图片居中显示 imageView.centerY = XMGScreenH * 0.5; } // 伸缩 CGFloat maxScale = self.topic.height / imageView.height; if (maxScale > 1.0) { scrollView.maximumZoomScale = maxScale; }}
- 图片实现伸缩
- 遵循UIscrollview代理
#pragma mark - <UIScrollViewDelegate>- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ return self.imageView;}
五 相册图片
- 通过拍照获得一张图片
UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.sourceType = UIImagePickerControllerSourceTypeCamera; [self presentViewController:picker animated:YES completion:nil];
- 从相册中挑选一张图片
UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum; [self presentViewController:picker animated:YES completion:nil];
自定义照相机 : AVCaptureSession
- 遍历相册文件夹
ALAssetsLibrary *Library = [ALAssetsLibrary alloc] init;// 遍历所有文件夹,一个ALAssetsGroup对象就代表一个文件夹 [Library enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {// 遍历文件夹内的所有多媒体文件(图片、视频),一个ALAsset对象代表一张图片 [group enumerateAssetsUsingBlock^(ALAsset *result, NSUInteger index, BOOL *stop) { XMGLog; }]; } failureBlock:nil];
- 文件夹名字
- (NSString *)groupName{ // 先从沙盒中取得名字 NSString *groupName = [[NSUserDefaults standardUserDefaults] stringForKey:XMGGroupNameKey]; if (groupName == nil) { // 沙盒中没有存储任何文件夹的名字 groupName = XMGDefaultGroupName; // 存储名字到沙盒中 [[NSUserDefaults standardUserDefaults] setObject:groupName forKey:XMGGroupNameKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } return groupName;}
- 添加一张图片到某个文件夹中
- (void)addImageToGroup:(ALAssetsGroup *)group{ __weak ALAssetsLibrary *weakLibrary = self.library; // 需要保存的图片 CGImageRef image = self.imageView.image.CGImage; // 添加图片到【相机胶卷】 [weakLibrary writeImageToSavedPhotosAlbum:image metadata:nil completionBlock:^(NSURL *assetURL, NSError *error) { [weakLibrary assetForURL:assetURL resultBlock:^(ALAsset *asset) { // 添加一张图片到自定义的文件夹中 [group addAsset:asset]; [SVProgressHUD showSuccessWithStatus:@"保存成功!"]; } failureBlock:nil]; }];}
- 保存图片
- (IBAction)save{ // 获得文件夹的名字 __block NSString *groupName = [self groupName]; // self的弱引用 XMGWeakSelf; // 图片库 __weak ALAssetsLibrary *weakLibrary = self.library; // 创建文件夹 [weakLibrary addAssetsGroupAlbumWithName:groupName resultBlock:^(ALAssetsGroup *group) { if (group) { // 新创建的文件夹 // 添加图片到文件夹中 [weakSelf addImageToGroup:group]; } else { // 文件夹已经存在 [weakLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) { NSString *name = [group valueForProperty:ALAssetsGroupPropertyName]; if ([name isEqualToString:groupName]) { // 是自己创建的文件夹 // 添加图片到文件夹中 [weakSelf addImageToGroup:group]; *stop = YES; // 停止遍历 } else if ([name isEqualToString:@"Camera Roll"]) { // 文件夹被用户强制删除了 groupName = [groupName stringByAppendingString:@" "]; // 存储新的名字 [[NSUserDefaults standardUserDefaults] setObject:groupName forKey:XMGGroupNameKey]; [[NSUserDefaults standardUserDefaults] synchronize]; // 创建新的文件夹 [weakLibrary addAssetsGroupAlbumWithName:groupName resultBlock:^(ALAssetsGroup *group) { // 添加图片到文件夹中 [weakSelf addImageToGroup:group]; } failureBlock:nil]; } } failureBlock:nil]; } } failureBlock:nil];}
0 0
- 项目实战No9 不等高cell高度 相册图片
- 不等高Cell
- 自定义不等高的cell
- 自定义不等高的cell
- 自定义不等高cell的storyboard方法
- iOS 自定义不等高的cell
- 纯代码计算不等高cell
- UITableView 异步加载图片,cell自适应高度!项目常用。
- 自定义不等高的cell(纯代码frame)
- IOS开发-16.自定义不等高cell
- 自定义不等高cell的纯代码步骤(frame)
- UI基础-UITableView之自定义不等高cell(纯代码)
- UI 一一 自定义不等高cell (Frame方式)
- UI 一一 自定义不等高cell (storyboard方式)
- 自定义等高cell和不等高cell的方式对比
- iOS 自定义cell高度(非等高)
- Cell的自定义高度 图片 文本
- 异步下载图片,动态设置cell高度
- 151 Reverse Words in a String
- C Prime Plus第十三章
- 新手解决winform问题的一点小经验
- 使用IOS7原生API进行二维码条形码的扫描
- idg笔试--e代驾笔试--完美笔试--美团面试回忆总结
- 项目实战No9 不等高cell高度 相册图片
- 结构型模式:适配器模式
- PUNCH算法
- 32-bit程序读取64bit 注册表
- 二叉排序树--源码
- JAVA基础之内部类
- CSS 水平垂直居中 方法三
- 二叉树的深度
- 苹果开发 笔记(75)UISegmentedControl