iOS 一個(gè)標(biāo)簽自動(dòng)布局的view

最近在做一個(gè)關(guān)于標(biāo)簽事件統(tǒng)計(jì)功能的view 吧碾,網(wǎng)上看了一些別人的demo感覺都不合適喂柒,于是想著自己造一個(gè)輪子探探水。


事件告警統(tǒng)計(jì)關(guān)注-事件列表.jpg

主要實(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末提佣,一起剝皮案震驚了整個(gè)濱河市吮蛹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌拌屏,老刑警劉巖匹涮,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異槐壳,居然都是意外死亡然低,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門务唐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雳攘,“玉大人,你說我怎么就攤上這事枫笛《置穑” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵刑巧,是天一觀的道長(zhǎng)喧兄。 經(jīng)常有香客問我无畔,道長(zhǎng),這世上最難降的妖魔是什么吠冤? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任浑彰,我火速辦了婚禮,結(jié)果婚禮上拯辙,老公的妹妹穿的比我還像新娘郭变。我一直安慰自己,他們只是感情好涯保,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布诉濒。 她就那樣靜靜地躺著,像睡著了一般夕春。 火紅的嫁衣襯著肌膚如雪未荒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天及志,我揣著相機(jī)與錄音茄猫,去河邊找鬼。 笑死困肩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脆侮。 我是一名探鬼主播锌畸,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼靖避!你這毒婦竟也來了潭枣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤幻捏,失蹤者是張志新(化名)和其女友劉穎盆犁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體篡九,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谐岁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了榛臼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伊佃。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沛善,靈堂內(nèi)的尸體忽然破棺而出航揉,到底是詐尸還是另有隱情,我是刑警寧澤金刁,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布帅涂,位于F島的核電站议薪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏媳友。R本人自食惡果不足惜斯议,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庆锦。 院中可真熱鬧捅位,春花似錦、人聲如沸搂抒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽求晶。三九已至焰雕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芳杏,已是汗流浹背矩屁。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留爵赵,地道東北人吝秕。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像空幻,于是被迫代替她去往敵國(guó)和親烁峭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法秕铛,類相關(guān)的語法约郁,內(nèi)部類的語法,繼承相關(guān)的語法但两,異常的語法鬓梅,線程的語...
    子非魚_t_閱讀 31,625評(píng)論 18 399
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,085評(píng)論 25 707
  • 一、自我介紹: 大家好谨湘,我是半個(gè)西瓜绽快,可以叫我小西。我來自陜西安康紧阔,90后谎僻,傳說中的警花(ps:說這話...
    安小西27閱讀 481評(píng)論 2 0
  • 我的血已流盡 連接了通往藍(lán)天的路 代表我的樹 是把利劍 刺穿藍(lán)天的心臟 女人蜷曲的頭發(fā)鎖緊太陽的憤怒 冰冷的雨的斧...
    心種閱讀 362評(píng)論 0 2
  • 楊絳先生在《走到人生邊上》中談到人生實(shí)苦,她這樣說:在這個(gè)物欲橫流的人世間寓辱,人生一世實(shí)在是夠苦的艘绍。你存心做一個(gè)與世...
    Innerpeace_4769閱讀 2,767評(píng)論 0 1