十六 iOS之 酷炫弹幕(二)
来源:互联网 发布:天龙八部天空视角数据 编辑:程序博客网 时间:2024/04/30 10:38
这次基于上一次的demo做更复杂点的功能,原理是 通过加载我自己准备的plist文件里的数据,生成一张张图文混排的图片,让它们从屏幕上飘过,就达到了弹幕效果
效果图:每次点击屏幕就飘出一条弹幕
一 主要添加了一个plist文件,和一个模型类 DGDanMuModel
- DGDanMuModel.h
#import <UIKit/UIKit.h>//弹幕类型枚举, 0就是其他人,1就是自己typedef enum { DGDanMuTypeOther, DGDanMuTypeMe,} DGDanMuType;@interface DGDanMuModel : NSObject/**弹幕类型*/@property(nonatomic,assign)DGDanMuType type;/**用户名*/@property(nonatomic,copy)NSString * username;/**文本内容*/@property(nonatomic,copy)NSString * text;/**头像*/@property(nonatomic,strong)UIImage * icon;/**表情图片名数组*/@property(nonatomic,strong)NSArray<NSString*> * emotions;/** 字典转模型方法*/+(instancetype)danMuWithDict:(NSDictionary*)dict;@end
- DGDanMuModel.m
#import "DGDanMuModel.h"@implementation DGDanMuModel/** 字典转模型方法 @param dict 要转的字典 @return 模型对象 */+(instancetype)danMuWithDict:(NSDictionary*)dict{ id obj = [[self alloc]init]; [obj setValuesForKeysWithDictionary:dict]; return obj;}@end
二 在DGDanMuView
中增加了一个绘制弹幕的方法
如下图,分成四部分去绘制这个图:头像、名称、文本、表情,相应部分的位置大小都参照这个图去计算
- 这个方法的核心代码
/** 根据弹幕模型生成弹幕图片 */-(DGImage*)imageWithDanMu:(DGDanMuModel*)danMu{ //绘制文字使用的字体 UIFont * font = [UIFont systemFontOfSize:13]; //间距 CGFloat marginX = 5; //头像的尺寸 CGFloat iconH = 30; CGFloat iconW = iconH; //表情图片的尺寸 CGFloat emotioW = 25; CGFloat emotionH = emotioW; //计算用户名占据的实际区域 CGSize nameSize = [danMu.username boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size; //用户名字体高度 CGFloat nameFontH = nameSize.height; //计算内容占据的实际区域 CGSize textSize = [danMu.text boundingRectWithSize:CGSizeMake(MAXFLOAT, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:font} context:nil].size; //内容字体高度 CGFloat textFontH = textSize.height; //位图上下文的尺寸 CGFloat contextH = iconH; //位图上下文的宽度 = 头像的宽度 + 1个间距 + 1个间距 + 用户名的宽度 + 1个间距 + 内容的宽度 + 表情的宽度 * 个数 + 1个间距 CGFloat contextW = iconW + marginX * 2 + nameSize.width + marginX + textSize.width + marginX + danMu.emotions.count * emotioW; CGSize contextSize = CGSizeMake(contextW, contextH); //开启位图上下文 UIGraphicsBeginImageContextWithOptions(contextSize, NO, 0); //获得位图上下文 CGContextRef ctx = UIGraphicsGetCurrentContext(); //将上下文保存一份到栈中,因为绘制头像时会裁剪点一部分上下文 CGContextSaveGState(ctx); //--------------绘制头像-------------// //设置头像尺寸 CGRect iconFrame = CGRectMake(0, 0, iconW, iconH); //绘制头像圆形 CGContextAddEllipseInRect(ctx, iconFrame); //超出圆形范围内的内容裁减掉 CGContextClip(ctx); UIImage * icon = danMu.type ? [UIImage imageNamed:@"me"] : [UIImage imageNamed:@"other"]; //绘制头像 [icon drawInRect:iconFrame]; //------------- 绘制背景图片----------------// //将上下文出栈 CGContextRestoreGState(ctx); //绘制背景图片 CGFloat bgX = iconW + marginX; CGFloat bgY = 0; CGFloat bgW = contextW - bgX; CGFloat bgH = contextH; danMu.type ? [[UIColor orangeColor] set] : [[UIColor whiteColor] set]; [[UIBezierPath bezierPathWithRoundedRect:CGRectMake(bgX, bgY, bgW, bgH) cornerRadius:20] fill]; //-----------------绘制用户名---------------// CGFloat nameX = bgX + marginX; CGFloat nameY = (contextH - nameFontH) * 0.5; CGRect nameRect = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); [danMu.username drawInRect:nameRect withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName : danMu.type ? [UIColor blackColor] : [UIColor orangeColor]}]; //----------------绘制文本区域 --------------------// CGFloat textX = nameX + nameSize.width + marginX; CGFloat textY = (contextH - textFontH) * 0.5; CGRect textRect = CGRectMake(textX, textY, textSize.width, textSize.height); [danMu.text drawInRect:textRect withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName : danMu.type ? [UIColor whiteColor] : [UIColor blackColor]}]; //----------------绘制表情图片 --------------------// __block CGFloat emotionX = textX + textSize.width; CGFloat emotionY = (contextH - emotionH) * 0.5; [danMu.emotions enumerateObjectsUsingBlock:^(NSString * _Nonnull emotionName, NSUInteger idx, BOOL * _Nonnull stop) { //加载表情图片 UIImage * emotion = [UIImage imageNamed:emotionName]; [emotion drawInRect:CGRectMake(emotionX, emotionY, emotioW, emotionH)]; emotionX += emotioW; }]; //从位图上下文获得绘制好的图片 UIImage * image = UIGraphicsGetImageFromCurrentImageContext(); //根据屏幕比例返回这张图片 return [[DGImage alloc]initWithCGImage:image.CGImage scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp];}
github demo: BarragePerfectDemo
阅读全文
1 0
- 十六 iOS之 酷炫弹幕(二)
- 十五 iOS之 酷炫弹幕
- iOS之弹幕效果
- iOS之弹幕效果
- iOS封装 之 直播弹幕
- 猫猫学IOS(二十六)UI之iOS抽屉效果小Demo
- (素材源码)猫猫学IOS(二十六)UI之iOS抽屉效果小Demo
- 《Motion Design for iOS》(二十六)
- iOS入门(二十六)iOS程序启动流程
- iOS弹幕
- iOS学习(二十六)Objective-C 分类
- Qt浅谈之十六:TCP和UDP(之二)
- 东软实训(二十六)
- 日拱一卒(二十六)
- 软件工程(二十六)
- 十六 iOS之 倒影效果
- ios项目(十六)
- OpenGL入门学习(十六之二)(转)
- 利用unity实现简单的贪吃蛇游戏
- 牛客网-剑指offer-04-重建二叉树
- 文章标题
- 网页布局之div与table的比较
- java.lang.IllegalArgumentException: pointerIndex out of range
- 十六 iOS之 酷炫弹幕(二)
- php缓存技术详细介绍及php缓存的实现代码
- spacetree组织架构图 实现异步加载子节点,和定制化内容展示
- ucos-iii学习之任务优先级
- 上传图片的拦截器
- 比特币开发者指南
- RN的一些坑,本人小白记录下学习RN遇到的问题加textinput值的取出
- jsp内置对象
- D3思维导图案例+二叉树数据转json数组