iOS 小組件 - 瀑布流多選器,技術(shù)設(shè)計(jì)與實(shí)現(xiàn)詳解(三)

一個(gè)通用的標(biāo)簽瀑布流多選器(自定義選項(xiàng)樣式仗谆、統(tǒng)一的點(diǎn)擊切換處理)指巡。

小組件多選器依賴(lài)于 iOS 小組件 - 標(biāo)簽瀑布流Base組件抽取,APP業(yè)務(wù)重構(gòu)(一) 一文中的base組件胸私。

一厌处、需求

IMG_8753.PNG

如設(shè)計(jì)圖所示,需要一個(gè)瀑布流的標(biāo)簽多選組件岁疼。

之前已經(jīng)寫(xiě)過(guò)一個(gè)瀑布流單選器iOS 小組件 - 瀑布流單選器,技術(shù)設(shè)計(jì)與實(shí)現(xiàn)詳解(二))缆娃,以同樣的思路寫(xiě)一個(gè)新的多選器捷绒。

二、技術(shù)設(shè)計(jì)思路

  • 第一贯要,需要一個(gè)能生成通用瀑布流多選器布局的組件暖侨。

  • 第二,可以支持靈活自定義比較重要的字段 (選中文本顏色崇渗、選中文本背景顏色字逗、未選中文本顏色京郑、未選中背景顏色、字體葫掉、間距 等等)

  • 第三些举,自動(dòng)處理選中與反選事件的樣式,返回點(diǎn)擊選中的回調(diào)俭厚。

  • 總結(jié)户魏,因?yàn)榍拔囊呀?jīng)擁有了(第一)和(第二點(diǎn))大部份功能了,后面只需要做一些小細(xì)節(jié)上的處理就可以了挪挤。!!

三叼丑、多選器小組件源碼

BaseView

在這段代碼中,除去前文已經(jīng)完成的基礎(chǔ)功能外扛门,添加的小細(xì)節(jié)有:

  • var hasSelecedClosure: ((Bool) -> ())?
    點(diǎn)擊標(biāo)簽回調(diào)鸠信,判斷是否已選夠目標(biāo)個(gè)數(shù)(可下一步)。
//  瀑布標(biāo)簽多選器

import UIKit

class YAYTagMultipleChoiceView: YAYBaseTagView {
    
    /// 是否已選夠目標(biāo)個(gè)數(shù)(可下一步)
    var hasSelecedClosure: ((Bool) -> ())?
    
    /// 限制最少選中個(gè)數(shù)
    var leastChoiceCount: Int = 1
    
    override init(frame: CGRect, option: YAYBaseTagOption) {
        super.init(frame: frame, option: option)
        layout.scrollDirection = .vertical
        backgroundColor = .clear
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    /// 獲取已選擇標(biāo)簽
    func getSelectedTags() -> ([YAYBaseTagModel]) {
        var selectedTags = [YAYBaseTagModel]()
        for tag in dataArray {
            // 如果記錄了true论寨,即是選中狀態(tài)
            if tag.isSelected ?? false {
                selectedTags.append(tag)
            }
        }
        return selectedTags
    }
    
    override func getSizeForItem(_ tagModel: YAYBaseTagModel, collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        let tagModel = dataArray[indexPath.row]
        let text = "\(tagModel.labelName)"
        // 加5是因?yàn)樗愠鰜?lái)的寬度不夠字體顯示症副,有誤差
        let width: CGFloat = text.textWidth(fontSize: option.fontSize, height: option.titleHeight, fontWeight: option.fontWeight) + option.itemLeftMargin + option.itemRightMargin + 5
        // 超過(guò)限制,文本寬度要恢復(fù)才能出現(xiàn)...
        return CGSize(width: min(option.contentWidth - 5, width), height: option.itemHeight)
    }
    
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: option.cellClass, for: indexPath) as? YAYTagMultipleChoiceCell ?? YAYTagMultipleChoiceCell()
        cell.isSelected = dataArray[indexPath.row].isSelected ?? false
        cell.tagOptionSet(option: option)
        cell.bindData(model: dataArray[indexPath.row])
        return cell
    }
    
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        super.collectionView(collectionView, didSelectItemAt: indexPath)
        
        // 數(shù)據(jù)源記錄政基,選中與反選
        dataArray[indexPath.row].isSelected = !(dataArray[indexPath.row].isSelected ?? false)
        self.reloadData()
        // 是否已選夠目標(biāo)個(gè)數(shù)
        if hasSelecedClosure != nil {
            hasSelecedClosure?(getSelectedTags().count >= leastChoiceCount)
        }
    }
}

BaseOption配置類(lèi)

YAYBaseTagOption 的具體配置在 iOS 小組件 - 標(biāo)簽瀑布流Base組件抽取贞铣,APP業(yè)務(wù)重構(gòu)(一) 文中已經(jīng)介紹過(guò)了。

在通用的瀑布流多選器配置類(lèi) YAYTagMultipleChoiceOption 中主要添加了五個(gè)可自定義的選中配置沮明。

  1. selectedItemTextColor 選中標(biāo)題顏色
  2. selectedItemBackgourdColor 選中背景顏色
  3. borderColor 邊框顏色
  4. selectedBorderColor 選中邊框顏色
  5. borderWidth 邊框大小

以下是配置類(lèi)源碼:

//  瀑布標(biāo)簽多選配置

import UIKit

class YAYTagMultipleChoiceOption: YAYBaseTagOption {
    
    /// 選中標(biāo)題顏色
    var selectedItemTextColor: UIColor = themeColor
    /// 選中背景顏色
    var selectedItemBackgourdColor: UIColor = themeColor.withAlphaComponent(0.08)
    /// 邊框顏色
    var borderColor: CGColor = themeColor.withAlphaComponent(0.12).cgColor
    /// 選中邊框顏色
    var selectedBorderColor: CGColor = themeColor.cgColor
    /// 邊框大小
    var borderWidth: CGFloat = 1

    init(leftM: CGFloat = 24, rightM: CGFloat = 24, contentWidth: CGFloat = screenWidth) {
        super.init()
        
        self.leftM = leftM
        self.rightM = rightM
        self.contentWidth = contentWidth - leftM - rightM
        
        cellClass = "YAYTagMultipleChoiceCell"
        topM = 25
        titleHeight = 22
        itemHeight = 46
        itemCorner = 23
        minimumLineSpacing = 16
        minimumInteritemSpacing = 16
        fontSize = 16
        fontWeight = .medium
        itemLeftMargin = 24
        itemRightMargin = 24
        itemBackGroundColor = .white
        itemTextColor = contentColor
        
    }
}

BaseCell 元素

YAYTagMultipleChoiceCell 主要是根據(jù)多選器配置類(lèi)辕坝,自動(dòng)處理選中與未選中的樣式,綁定標(biāo)簽文本荐健。

//  瀑布標(biāo)簽多選cell

import UIKit

class YAYTagMultipleChoiceCell: YAYBaseTagCell {
    
    // MARK: - bindData
    
    override func tagOptionSet(option: YAYBaseTagOption) {
        super.tagOptionSet(option: option)
        
        guard let tagOption = option as? YAYTagMultipleChoiceOption else { return }

        titleLabel.snp.makeConstraints { make in
            make.centerY.equalToSuperview()
            make.left.equalToSuperview().offset(tagOption.itemLeftMargin)
            make.right.equalToSuperview().offset(-tagOption.itemRightMargin)
            make.height.equalTo(option.titleHeight)
        }
        
        // 切換選中狀態(tài)
        if isSelected {
            titleLabel.textColor = tagOption.selectedItemTextColor
            contentView.backgroundColor = tagOption.selectedItemBackgourdColor
            
            contentView.layer.borderColor = tagOption.selectedBorderColor
            contentView.layer.borderWidth = tagOption.borderWidth
            contentView.layer.masksToBounds = true
        }
        else {
            titleLabel.textColor = tagOption.itemTextColor
            contentView.backgroundColor = tagOption.itemBackGroundColor
            
            contentView.layer.borderColor = tagOption.borderColor
            contentView.layer.borderWidth = tagOption.borderWidth
            contentView.layer.masksToBounds = true
        }
    }
    
    override func bindData(model: YAYBaseTagModel) {
        super.bindData(model: model)
        titleLabel.text = model.labelName
    }

}

四酱畅、具體使用與效果

實(shí)際使用

類(lèi)似前文標(biāo)簽iOS 小組件 - 標(biāo)簽瀑布流Base組件抽取,APP業(yè)務(wù)重構(gòu)(一)江场、iOS 小組件 - 瀑布流單選器纺酸,技術(shù)設(shè)計(jì)與實(shí)現(xiàn)詳解(二)例子一樣,根據(jù)不同的 YAYTagMultipleChoiceOption 即可生成功能相同址否,樣式不同的多選器餐蔬,這里業(yè)務(wù)只做了一種樣式的瀑布流多選器,故沒(méi)有更多的使用例子佑附。

截屏2025-02-07 10.18.50.png

具體多選效果

實(shí)際運(yùn)行中樊诺,選夠了3個(gè)最低個(gè)數(shù)后,可進(jìn)行下一步音同。

IMG_8754.PNG

最后词爬,又雙叒叕完成了一個(gè)開(kāi)箱即用的瀑布流多選器通用小組件,以后類(lèi)似的場(chǎng)景就可以直接引用該組件了权均。

最最最后顿膨,完結(jié)撒花

告辭.jpeg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末锅锨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子恋沃,更是在濱河造成了極大的恐慌必搞,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芽唇,死亡現(xiàn)場(chǎng)離奇詭異顾画,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)匆笤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)研侣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人炮捧,你說(shuō)我怎么就攤上這事庶诡。” “怎么了咆课?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵末誓,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我书蚪,道長(zhǎng)喇澡,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任殊校,我火速辦了婚禮晴玖,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘为流。我一直安慰自己呕屎,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布敬察。 她就那樣靜靜地躺著秀睛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪莲祸。 梳的紋絲不亂的頭發(fā)上蹂安,一...
    開(kāi)封第一講書(shū)人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音虫给,去河邊找鬼藤抡。 笑死,一個(gè)胖子當(dāng)著我的面吹牛抹估,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播弄兜,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼药蜻,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼瓷式!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起语泽,我...
    開(kāi)封第一講書(shū)人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贸典,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后踱卵,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體廊驼,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年惋砂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妒挎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡西饵,死狀恐怖酝掩,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情眷柔,我是刑警寧澤期虾,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站驯嘱,受9級(jí)特大地震影響镶苞,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鞠评,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一茂蚓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧谢澈,春花似錦煌贴、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至敬鬓,卻和暖如春淹朋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钉答。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工础芍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人数尿。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓仑性,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親右蹦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诊杆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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