最近在做一個(gè)關(guān)于標(biāo)簽事件統(tǒng)計(jì)功能的view 吧碾,網(wǎng)上看了一些別人的demo感覺都不合適喂柒,于是想著自己造一個(gè)輪子探探水。
主要實(shí)現(xiàn)圖中所示的功能檬输,話不多少搞起!
第一次寫大神們多包涵呀
下面這個(gè)方法計(jì)算傳進(jìn)來的字符串?dāng)?shù)組匈棘,實(shí)現(xiàn)每個(gè)字符串長(zhǎng)度的計(jì)算丧慈,并做換行判斷,每一行存進(jìn)統(tǒng)計(jì)數(shù)組中
//將標(biāo)簽數(shù)組根據(jù)type以及其他參數(shù)進(jìn)行分組裝入數(shù)組
- (void)disposeTags:(NSArray *)aryName aryCount:(NSArray *)aryCount{
NSMutableArray *tags = [NSMutableArray new];//縱向數(shù)組
NSMutableArray *subTags = [NSMutableArray new];//橫向數(shù)組
float originX = _tagOriginX;
for (NSString *tagTitle in aryName) {
NSUInteger index = [aryName indexOfObject:tagTitle];
//計(jì)算每個(gè)tag的寬度
CGSize contentSize = [tagTitle fdd_sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(self.frame.size.width-_tagOriginX*2, MAXFLOAT)];
NSMutableDictionary *dict = [NSMutableDictionary new];
dict[@"tagTitle"] = tagTitle;//標(biāo)簽標(biāo)題
dict[@"tagCount"] =aryCount[index];
dict[@"viewWith"] = [NSString stringWithFormat:@"%f",contentSize.width+_tagSpace+30];//標(biāo)簽的寬度
if (index == 0) {
dict[@"originX"] = [NSString stringWithFormat:@"%f",originX];//標(biāo)簽的X坐標(biāo)
[subTags addObject:dict];
} else {
if (originX + contentSize.width > self.frame.size.width-_tagOriginX*2) {
//當(dāng)前標(biāo)簽的X坐標(biāo)+當(dāng)前標(biāo)簽的長(zhǎng)度>屏幕的橫向總長(zhǎng)度則換行
[tags addObject:subTags];
//換行標(biāo)簽的起點(diǎn)坐標(biāo)初始化
originX = _tagOriginX;
dict[@"originX"] = [NSString stringWithFormat:@"%f",originX];//標(biāo)簽的X坐標(biāo)
subTags = [NSMutableArray new];
[subTags addObject:dict];
} else {
//如果沒有超過屏幕則繼續(xù)加在前一個(gè)數(shù)組里
dict[@"originX"] = [NSString stringWithFormat:@"%f",originX];//標(biāo)簽的X坐標(biāo)
[subTags addObject:dict];
}
}
if (index +1 == aryName.count) {
//最后一個(gè)標(biāo)簽加完將橫向數(shù)組加到縱向數(shù)組中
[tags addObject:subTags];
disposeAry = tags;
}
//標(biāo)簽的X坐標(biāo)每次都是前一個(gè)標(biāo)簽的寬度+標(biāo)簽左右空隙+標(biāo)簽距下個(gè)標(biāo)簽的距離
originX += contentSize.width+_tagHorizontalSpace+_tagSpace+30;
}
}
下面這個(gè)方法是計(jì)算字符串長(zhǎng)度的封裝方法主卫,只限字符串計(jì)算逃默,用的話可以直接搬走
#pragma mark - 擴(kuò)展方法
@implementation NSString (FDDExtention)
- (CGSize)fdd_sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size {
CGSize resultSize;
if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:@selector(boundingRectWithSize:options:attributes:context:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:@selector(boundingRectWithSize:options:attributes:context:)];
NSDictionary *attributes = @{ NSFontAttributeName:font };
NSStringDrawingOptions options = NSStringDrawingUsesLineFragmentOrigin;
NSStringDrawingContext *context;
[invocation setArgument:&size atIndex:2];
[invocation setArgument:&options atIndex:3];
[invocation setArgument:&attributes atIndex:4];
[invocation setArgument:&context atIndex:5];
[invocation invoke];
CGRect rect;
[invocation getReturnValue:&rect];
resultSize = rect.size;
} else {
NSMethodSignature *signature = [[self class] instanceMethodSignatureForSelector:@selector(sizeWithFont:constrainedToSize:)];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
[invocation setTarget:self];
[invocation setSelector:@selector(sizeWithFont:constrainedToSize:)];
[invocation setArgument:&font atIndex:2];
[invocation setArgument:&size atIndex:3];
[invocation invoke];
[invocation getReturnValue:&resultSize];
}
return resultSize;
}
字符串長(zhǎng)度計(jì)算完成了,下面就可以進(jìn)行所有字符串排列的高度了簇搅。其實(shí)這個(gè)蠻簡(jiǎn)單的 完域,統(tǒng)計(jì)數(shù)組有多少個(gè)元素就代表標(biāo)簽排布有多少行。
//獲取處理后的tagsView的高度根據(jù)標(biāo)簽的數(shù)組
-
(float)getDisposeTagsViewHeight:(NSArray *)ary {
float height = 0;
if (disposeAry.count > 0) {
height = _tagOriginY+disposeAry.count*(_tagHeight+_tagVerticalSpace);
}
return height;
}
下面這個(gè)將標(biāo)簽加載到view上了瘩将,并實(shí)現(xiàn)賦值吟税。
-(void)setTagAryName:(NSArray *)tagAryName aryCount:(NSArray *)aryCount delegate:(id)delegate{
_tagDelegate=delegate;
[self disposeTags:tagAryName aryCount:aryCount];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(_tagOriginX, 0, 200, 30)];
label.text=@"事件類別統(tǒng)計(jì):";
label.textColor=_titleColor;
label.textAlignment=NSTextAlignmentLeft;
label.adjustsFontSizeToFitWidth=YES;
[self addSubview:label];
//遍歷標(biāo)簽數(shù)組,將標(biāo)簽顯示在界面上,并給每個(gè)標(biāo)簽打上tag加以區(qū)分
for (NSArray *iTags in disposeAry) {
NSUInteger i = [disposeAry indexOfObject:iTags];
for (NSDictionary *tagDic in iTags) {
NSUInteger j = [iTags indexOfObject:tagDic];
NSString *tagTitle = tagDic[@"tagTitle"];
float originX = [tagDic[@"originX"] floatValue];
float viewWith = [tagDic[@"viewWith"] floatValue];
NSString *count = tagDic[@"tagCount"];
UIView *NCView=[[UIView alloc]initWithFrame:CGRectMake(originX, _tagOriginY+i*(_tagHeight+_tagVerticalSpace), viewWith, _tagHeight)];
[self addSubview:NCView];
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame=CGRectMake(0, 0, viewWith-30, _tagHeight);
button.layer.borderColor = _borderColor.CGColor;
button.layer.borderWidth = _borderWidth;
button.layer.masksToBounds = _masksToBounds;
button.layer.cornerRadius = _cornerRadius;
button.titleLabel.font = [UIFont systemFontOfSize:_titleSize];
[button setTitle:tagTitle forState:UIControlStateNormal];
[button setTitleColor:_titleColor forState:UIControlStateNormal];
[button setBackgroundImage:_normalBackgroundImage forState:UIControlStateNormal];
[button setBackgroundImage:_highlightedBackgroundImage forState:UIControlStateHighlighted];
button.tag = i*iTags.count+j;
[button addTarget:self action:@selector(buttonAction:) forControlEvents:UIControlEventTouchUpInside];
UILabel *label=[[UILabel alloc]initWithFrame:CGRectMake(viewWith-30, 0, 30, _tagHeight)];
label.text=[NSString stringWithFormat:@"X%@",count];
label.textAlignment=NSTextAlignmentCenter;
label.adjustsFontSizeToFitWidth=YES;
label.textColor=_titleColor;
[NCView addSubview:button];
[NCView addSubview:label];
}
}
self.countLabel=[[UILabel alloc]initWithFrame:CGRectMake(_tagOriginX, [self getDisposeTagsViewHeight:disposeAry], 100, 30)];
self.countLabel.text=[NSString stringWithFormat:@"總計(jì):%ld次",_times];
self.countLabel.textAlignment=NSTextAlignmentLeft;
self.countLabel.adjustsFontSizeToFitWidth=YES;
self.countLabel.textColor=_titleColor;
[self addSubview:self.countLabel];
if (disposeAry.count > 0) {
float contentSizeHeight = _tagOriginY+disposeAry.count*(_tagHeight+_tagVerticalSpace);
self.contentSize = CGSizeMake(self.frame.size.width,contentSizeHeight);
}
if (self.frame.size.height <= 0) {
self.frame = CGRectMake(CGRectGetMinX([self frame]), CGRectGetMinY([self frame]), CGRectGetWidth([self frame]), [self getDisposeTagsViewHeight:disposeAry]+30);
}
}
說了這么多,如何調(diào)用呢姿现? 那么亮點(diǎn)來了 只需要傳進(jìn)來數(shù)組就實(shí)現(xiàn)圖中的功能肠仪。
//計(jì)算出全部展示的高度,讓maxHeight等于計(jì)算出的高度即可,初始化不需要設(shè)置高度
NSArray *tagAryCount=@[@"10",@"8",@"7",@"9",@"2",@"4",@"5",@"3",@"4"];
NSArray* tagAryName = @[@"黑色玫瑰",@"比爾沃吉特",@"鋼鐵烈陽",@"德瑪西亞",@"祖安",@"巨神峰",@"雷瑟守備祖安",@"諾克薩斯暗影島",@"弗雷爾卓德"];
ZHLbView * tagsView = [[ZHLbView alloc] initWithFrame:CGRectMake(0, 200, self.view.frame.size.width, 0)];
[tagsView setTagAryName:tagAryName aryCount:tagAryCount delegate:self];
[self.view addSubview:tagsView];
補(bǔ)充,在demo編寫的過程中 备典,遇到了一些小問題异旧,就是scrollView如果是VC的第一個(gè)子視圖的話 其總是要有一個(gè)64高度的空白區(qū)。
Demo https://github.com/delegateA/ZHLabelLayout.git