iOS实现高性能简单易用的星星评分控件

时间:2022-05-24 08:31:04

前言

做为老司机的你们有没有遇到过这样的需求?每个商品或者商家的item都有个星级或者其他评分,大概像以下的效果图

iOS实现高性能简单易用的星星评分控件

实现方案:

  • 大神自己写个通用空间(在时间充足的情况下)
  • 网上找个比较好的第三方 (时间比较紧凑的情况下)
  • 更直接的,自己直接放几个imageview或者layer

思考:功能是实现了,但是性能好像有点受影响。具体原因要看第三方框架的实现原理,当然了也有做的很好的。我是个性能控,当我拿到这个需求的时候,也尝试用一些第三方,但结果不尽人意。最后xwstarview就此产生了。

xwstarview(高性能星星控件)

推荐理由:

  • 简单易用
  • 高性能,采用yylabel异步绘制
  • 支持自定义星星样式,间距

局限性:

  • 目前只支持半星,一星评分
  • 目前只支持图片
  • 依赖yylabel

xwstarmaker(外观配置)

开发者可以配置间距,最大值,默认图片,选中图片

 
1
2
3
4
5
6
@interface xwstarmaker : nsobject
@property (nonatomic, assign) cgfloat space;
@property (nonatomic, strong) nsstring *defaultimage;
@property (nonatomic, strong) nsstring *selectimage;
@property (nonatomic,assign) nsinteger maxvalue;
@end

xwstarview.m(核心代码)

眼尖的同学已经看到了,xwstarview直接继承了yylabel,熟悉yylaebl的开发者可能知道我要干嘛了。

 
1
2
3
4
5
6
7
8
9
10
11
12
#import "yylabel.h"
#import "xwstarmaker.h"
@class xwstarview;
@protocol xwstarviewdelegate <nsobject>
@optional
-(void)xw_starview:(xwstarview*)tagview star:(nsinteger)star;
@end
@interface xwstarview : yylabel
@property (nonatomic, assign) nsinteger score;
@property (nonatomic,weak) id<xwstarviewdelegate> delegate;
-(instancetype)initwithframe:(cgrect)frame maker:(void (^)(xwstarmaker *))makeblock;
@end

具体的实现细节看.m文件

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@interface xwstarview ()
@property (nonatomic,strong) xwstarmaker *maker;
@end
@implementation xwstarview
-(instancetype)initwithframe:(cgrect)frame maker:(void (^)(xwstarmaker *))makeblock{
 if (self = [super initwithframe:frame]) {
   self.maker = [[xwstarmaker alloc] init];
  if (makeblock) {
   makeblock(self.maker);
  }
  self.displaysasynchronously = yes;
  self.fadeonasynchronouslydisplay = no;
  [self creatscoreattr];
 }
 return self;
}
#pragma mark - private
-(void)creatscoreattr{
 nsmutableattributedstring *text = [nsmutableattributedstring new];
 uifont *font = [uifont systemfontofsize:0];
 for (int i = 0; i < self.maker.maxvalue; i++) {
  uiimage *image = [uiimage imagenamed:self.maker.defaultimage];
  nsmutableattributedstring *attachtext = [nsmutableattributedstring yy_attachmentstringwithcontent:image contentmode:uiviewcontentmodeleft attachmentsize:cgsizemake(image.size.width + self.maker.space, image.size.height) aligntofont:font alignment:yytextverticalalignmentcenter];
//添加点击事件
  __weak typeof(&*self) weakself = self;
  [attachtext yy_settexthighlightrange:nsmakerange(0, 1) color:nil backgroundcolor:nil tapaction:^(uiview *containerview, nsattributedstring *text, nsrange range, cgrect rect){
   if (weakself.delegate && [weakself.delegate respondstoselector:@selector(xw_starview:star:)]) {
    [weakself.delegate xw_starview:weakself star:i];
   }
  }];
  [text appendattributedstring:attachtext];
 }
 self.attributedtext = text;
}
 
-(void)setscore:(nsinteger)score{
 if (_score == score)
 {
  return;
 }
 _score = score;
 //获取图片资源
 nsarray *attachments = self.textlayout.attachments;
 for (int i = 0; i < attachments.count; i++) {
  yytextattachment *attachment = attachments[i];
  attachment.content = [uiimage imagenamed:i <= _score self.maker.selectimage : self.maker.defaultimage];
 }
 
}
@end

只要你是个ios程序员大概都看得懂代码吧。实现很简单,但是效果却不一般,特别在复杂列表使用的时候很明显。

xwstarview使用

 
1
2
3
4
5
6
_scoreview = [[xwstarview alloc] initwithframe:cgrectmake(0, self.frame.size.height - 40, self.frame.size.width, 40) maker:^(xwstarmaker *maker){
  maker.defaultimage = @"goods_score_empt.png";
  maker.selectimage = @"goods_score_full.png";
  maker.space = 10;
 }];
 _scoreview.delegate = self;

xwstarview是yylabel的爱好者不错的选择哦,如果满足你的业务需求,性能方面会让你很满意的,不信你就试试(哈哈,调皮了)。当然了萝卜青菜各有所爱,不喜勿喷。

总结

程序员的快乐应该是每天不断的学习,不断的发现新东西,让自己不被抛弃,至少我是那么认为的(嘻嘻),你呢?

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://www.jianshu.com/p/30399b207dd3