iOS多級選擇框架封裝與專案中的一些坑

3033發表於2019-01-16

###開篇
6月了啊,感覺墮落了一個月,哈哈。今天再更新一篇吧,主要內容,關於之前抽空整理的一個多級選擇框架的封裝和幾個專案中遇到的奇怪的坑。
#####多級選擇框架
實現的框架效果圖如下:

演示gif01.gif

多級篩選程式碼GSMultipleChoiceView地址

  • 主要功能:
    實現左邊存在多個選項,可以自適應滾動和設定字型的寬度和底部下劃線的寬度,篩選的多級選擇,可以記憶上次選中的效果,點選一級篩選,二級篩選關閉並重新整理資料,可以根據點選的不同一級標題顯示不同的二級標題的篩選名稱。篩選左側的一級標題可以大於4個,會自動滾動。
  • 呼叫方法
    一級篩選的載入方法如下
 MultipleChoiceView =[[RedChipMultipleChoiceView alloc]initWithFrame:CGRectMake(0, 64, SCREEN_WIDTH, 45*ratio_width) titles:@[@"待展期", @"未到期", @"已結束",@"全部"] moreSelctBtnTitle:@"篩選" btn_w:SCREEN_WIDTH/5];
複製程式碼

遵循MultipleChoiceView 的代理,為了方便自定義,根據點選篩選之後建立二級標題的顯示

#pragma mark - 頭部控制的代理方法
//點選左邊滾動的返回 點選的具體的點選按鈕
-(void)redChipClicktWith:(NSNumber *)nowSelect{
    
    NSLog(@"-----%ld",[nowSelect integerValue]);
    //    [MultipleChoiceView.moreSelectBtn setTitleColor:[Toolkit getColor:hex_606060] forState:UIControlStateNormal];
    [MultipleChoiceView.moreSelectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
    
    MultipleChoiceView.selcetBtnIsSelect = NO;
    MultipleChoiceView.rightView.image =[UIImage imageNamed:@"紅籌優化新圖示三角-下-@2x"];
    self.SlectbottomView.hidden =YES;
    
    currentSelctNum = nowSelect;
    
    //點選一級標題 下面的關閉  設定預設傳參
    goodList_sort = @"1";
    goodsList_order = @"desc";
    
    //然後點選  請求網路 重新整理tableview
    //此處根據點選後的返回資料 做網路的請求,介面的重新整理等操作 
}
複製程式碼

點選篩選按鈕建立二級標題處理相關邏輯

//點選篩選按鈕
-(void)clickMoreSelcetBtn{
    if ([currentSelctNum integerValue] == 4) {
        arrName = @[@"參與時間",@"結束時間",@"獎勵"];
    }else{
        arrName = @[@"參與時間",@"到期時間",@"獎勵"];
    }
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self prepareMenuViewSubviews];
        
    });
    
    if (MultipleChoiceView.selcetBtnIsSelect) {
        //        [MultipleChoiceView.moreSelectBtn setTitleColor:[Toolkit getColor:hex_606060] forState:UIControlStateNormal];
        [MultipleChoiceView.moreSelectBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        
        MultipleChoiceView.selcetBtnIsSelect = NO;
        MultipleChoiceView.rightView.image =[UIImage imageNamed:@"紅籌優化新圖示三角-下-@2x"];
        self.SlectbottomView.hidden =YES;
    }else{
        //        [MultipleChoiceView.moreSelectBtn setTitleColor:[Toolkit getColor:hex_ff5600] forState:UIControlStateNormal];
        [MultipleChoiceView.moreSelectBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        
        MultipleChoiceView.selcetBtnIsSelect = YES;
        MultipleChoiceView.rightView.image =[UIImage imageNamed:@"紅籌優化新圖示三角-上@2x"];
        self.SlectbottomView.hidden =NO;
    }
}
複製程式碼

實現效果如下:
演示gif02.gif
####專案中的坑
歡樂的時光總是短暫的接下來,說說最近專案中遇到的坑吧,最近負責模組較多,對老程式碼的更改可謂一步一坑啊,下面就從鬱悶程度一點點說一下吧。

00

猝不及防的iOS10.3的坑

商城中對於商品的優惠價格處理的中劃線失效。
原因:在10.3系統升級後(起碼我是這個時候發現的),包含有中文價格或者中文符號的中劃線富文字處理不起作用了。
之前的處理方式程式碼如下:

 NSDictionary *attribtDic = @{NSStrikethroughStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle]};
    NSMutableAttributedString *attribtStr_origin = [[NSMutableAttributedString alloc]initWithString:[NSString stringWithFormat:@"價格:¥%@",[goods_info objectForKey:@"market_price"]] attributes:attribtDic];
    self.current_price_lbl.attributedText=attribtStr_origin;
複製程式碼

新的解決方式如下:

    NSUInteger length = [[NSString stringWithFormat:@"價格:¥%@",[goods_info objectForKey:@"market_price"]] length];
    NSMutableAttributedString *attri = [[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"價格:¥%@",[goods_info objectForKey:@"market_price"]]];
    [attri setAttributes:@{NSStrikethroughStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle], NSBaselineOffsetAttributeName : @(NSUnderlineStyleSingle),NSForegroundColorAttributeName:[UIColor lightGrayColor]} range:NSMakeRange(3,length-3)];
    [self.current_price_lbl setAttributedText:attri];
		
複製程式碼

由程式碼可知,主要是增加一個富文字屬性:

NSBaselineOffsetAttributeName : @(NSUnderlineStyleSingle)
複製程式碼

既然都到這裡了,就索性再放兩個平時常用的兩種富文字處理方式
顯示富文字段落:

 NSAttributedString * attrStr = [[NSAttributedString alloc] initWithData:[shareTexe dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
 [self.midDesclabel setAttributedText:attrStr];
 [self.midDesclabel sizeToFit];
複製程式碼

對部分文字做富文字處理

cell.voucher_RedChipCountLabel.textColor = [Toolkit getColor:hex_606060];
NSMutableAttributedString* attribute=[[NSMutableAttributedString alloc] initWithString:indexRow_RedChipCountStr];
[attribute addAttribute:NSForegroundColorAttributeName value:[Toolkit getColor:hex_ff5600] range:NSMakeRange(5, indexRow_RedChipCountStr.length - 5)];
[attribute addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:14] range:NSMakeRange(0, 5)];
[attribute addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:16] range:NSMakeRange(5, indexRow_RedChipCountStr.length - 5)];
cell.voucher_RedChipCountLabel.attributedText = attribute;

複製程式碼

######Zxing-Object二維碼顯示的坑
下面開始測試中沒有遇到,但是使用者反饋的坑

01

  • 發生場景,生成一張帶二維碼的圖片,兩種方式處理,一種是儲存到本地識別,一種是直接分享到qq。
  • 問題:有部分使用者二維碼無法識別,生成的圖片儲存到本地直接識別可以識別,直接分享到qq,部分圖片無法識別。
    生成二維碼方法如下:
    dispatch_async(dispatch_get_main_queue(), ^{
            
            if (str != nil) {
                ZXMultiFormatWriter *writer = [[ZXMultiFormatWriter alloc] init];
                ZXEncodeHints *hints = [ZXEncodeHints hints];
                hints.encoding = NSUTF8StringEncoding;
                hints.dataMatrixShape =ZXDataMatrixSymbolShapeHintForceSquare;
                hints.margin = [NSNumber numberWithInt:0.];
                
                hints.errorCorrectionLevel = [ZXQRCodeErrorCorrectionLevel errorCorrectionLevelH];
                NSString *qrString = str;
                ZXBitMatrix *result = [writer encode:qrString format:kBarcodeFormatQRCode width:500 height:500 hints:hints error:nil];
                
                if (result) {
                    CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];
                    UIImage *image1 =   [UIImage imageWithCGImage:image];//二維碼原圖
                    self.shareErWeiMaView.image =image1;
                    
                } else {
                    self.shareErWeiMaView.image = nil;
                }
            }
        });
複製程式碼

由於對生成二維碼的容錯等級和範圍都做了設定,又並無logo遮擋,重點是儲存到本地可以識別,所以比較奇怪,最終解決方式增大了範圍。

  ZXBitMatrix *result = [writer encode:qrString format:kBarcodeFormatQRCode width:500 height:500 hints:hints error:nil];
複製程式碼

對上句程式碼中的範圍做了增大,解決了部分二維碼不能識別的問題。

#####未解之謎的神坑,心塞
一直未能復現,所以多說說。

  • bug來源:使用者反饋
  • 原因:在多級篩選的時候,顯示混亂,初次點選混亂,重新整理一下正常,具體介面是,篩選的已結束介面的顯示。

正常顯示的已結束頁面如下圖:

正常已結束.png
正常的未結束包含倒數計時的資料如下圖:

正常倒數計時.png
使用者反饋bug,介面截圖如下:

反饋圖.png

由圖可以看到,在已結束的時候顯示了倒數計時,對一個tableview來說,第一時間就是複用出了問題,或者控制元件的顯示隱藏判斷邏輯出了問題。
在老程式碼中分別用timeLabel 和endTimeLabel 來分別顯示已結束的標題和倒數計時的標題,通過後臺的一個欄位來控制標題的顯示內容。
根據後臺返回資料的不同的幾種cell情況來決定timeLabel 和endTimeLabel的顯示和隱藏。
這兩個控制元件佈局如下:

   [self.cell_iconImageView_1 makeConstraints:^(MASConstraintMaker* make){
        make.top.equalTo(self.contentView).offset(15*ratio_width);
        make.bottom.equalTo(self.contentView).offset(-15*ratio_width);
        make.left.equalTo(self.contentView).offset(10*ratio_width);
        make.width.equalTo(self.cell_ImageView_1.height);
    }];
    [self.timeLabel makeConstraints:^(MASConstraintMaker* make){
        make.top.equalTo(self.addRewardMoney.mas_bottom).offset(5*ratio_width);
        make.left.equalTo(self.cell_iconImageView_1.right).offset(10*ratio_width);
        make.right.equalTo(self.contentView);
        make.height.equalTo(19*ratio_width);
    }];
    [self.endTimeLabel makeConstraints:^(MASConstraintMaker* make){
        make.bottom.equalTo(self.contentView).offset(-10*ratio_width);
        make.left.equalTo(self.cell_iconImageView_1.right).offset(10*ratio_width);
        make.right.equalTo(self.contentView);
        make.height.equalTo(25*ratio_width);
    }];
複製程式碼

這兩個控制元件都是根據圖片,從左開始排列,並且存在一定交叉,我們故意讓他們同時顯示如下:

假設錯誤圖.png
可以看到,就算是顯示隱藏錯誤,出現時為止應該是上圖所示,不應該存在如下圖反饋圖所顯示的內容

反饋圖示記
因此

  • 疑惑1:此倒數計時為止壓根沒有控制元件存在,怎麼會顯示。
  • 疑惑2:控制元件的顯示內容在每個cell時皆有判斷不會出現上述情況。
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{}

              NSInteger status = [[NSString stringWithFormat:@"%@",[[_dataArray_ing objectAtIndex:indexPath.section] objectForKey:@"ostatus"]] integerValue];
                if (status == 2) {
                    
                    cell.timeLabel.text=@"已結束";
                    
                }else{
                 
                    if (seconds==0) {
                        if ([[[_dataArray_ing objectAtIndex:indexPath.section] objectForKey:@"activity"] intValue]==10) {
                            cell.timeLabel.text=@"已到期";
                        }
                        else
                        {
                            cell.timeLabel.text=@"待展期";
                        }
                    }else{
                        if ([_dataArray_ing count]>[totalLastTime count]&&[totalLastTime count]<(indexPath.section+1)) {
                            NSDictionary *dic = @{@"indexPath":[NSString stringWithFormat:@"%ld",indexPath.section],@"lastTime": [[_dataArray_ing objectAtIndex:indexPath.section] objectForKey:@"remain_time" ]};
                            [totalLastTime addObject:dic];
                            cell.timeLabel.text= [NSString stringWithFormat:@"剩餘時間:%@",[Toolkit formatSecondToData:seconds]];
                        }
                    }

                }
複製程式碼
  • 疑惑3 開發過程中,多個測試賬號,以及三天的測試周期中從未出現這種情況,再反饋後幾個人多次測試仍未出現。
  • 疑惑4 據反饋說初次點選是這樣上拉重新整理恢復就更奇怪了,因為每次點選新的一級選單就等於是一次新的重新整理。

可惜的是並未反饋使用者的賬號資訊,而且只有一個反饋,不然非拉著後臺到底哪裡的問題。

01

####後記
好久沒更新,墮落的一個月,開始繼續進步吧,哈哈,今天主要就說這些吧,希望封裝對有需要的,以及遇到同樣bug的有所幫助,話說今天的簡書伺服器是怎麼了,顯示打不開網頁,寫著寫著又打不開了,忽然好慫,萬一簡書壞了,這些文章咋辦。。。。等了半小時終於好了,終於好了。唉

02

相關文章