ios 如何实现淘宝一类选择商品自适应长度

你的小可爱已上线

淘宝点击商品可以进行商品的选择比如大小之类的,这类可以选择用collectionView来写,下面我讲述一下我的项目中所用的界面做一个简单的分析和实现想法,如果有更好的想法可以分享给我。

效果.gif

规格上面的是一个固定的view,规格下面第一个粉框框是collectionView,根据文字大小实现动态显示,数量一个框是UICollectionReusableView可以设为footer

先来分析下如何是实现动态获取string长度

//collectionItemSize
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize.init(width: self.getWidthWithText(text: self.dataArr[indexPath.row] as NSString, height: 30*W, font: 12*W)+20*W, height: 30*W)
    }
 //获取长度
    func getWidthWithText(text:NSString,height:CGFloat,font:CGFloat) -> CGFloat{
        let size = text.boundingRect(with: CGSize.init(width: CGFloat(MAXFLOAT), height: height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : UIFont.systemFont(ofSize: font) ], context: nil)
        return size.width
    }
    

进行collectionItemSize宽度赋值,如果是网络数据我们可以进行再model其中加一个属性为width把这个获取到string宽度进行封存,在cell内赋值时候要对这个label的宽度重新赋值,实现动态显示宽度。

再来分析下如何实现单选问题,这个问题就很好解决创建一个全局变量cell,当每次点击时候进行一次赋值和样式改变就好了,我还是附上代码

 func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let cell = collectionView.cellForItem(at: indexPath) as!XBSetAddGoodsCollectionViewCell
        if (self.selectCell != cell) {
            cell.titleLable.backgroundColor = #colorLiteral(red: 0.9921568627, green: 0.5921568627, blue: 0.3254901961, alpha: 1)
            cell.titleLable.textColor = UIColor.white
            if self.selectCell != nil {
                selectCell.titleLable.backgroundColor = #colorLiteral(red: 0.9647058824, green: 0.9647058824, blue: 0.9647058824, alpha: 1)
                selectCell.titleLable.textColor = LabelColor_51
            }
            selectCell = cell
        }else{
            cell.titleLable.backgroundColor = #colorLiteral(red: 0.9921568627, green: 0.5921568627, blue: 0.3254901961, alpha: 1)
            cell.titleLable.textColor = UIColor.white
            selectCell = cell
        }
    }

那么有人肯定问了,你的cell为何可以居左面,这个问题嘛 网上很多解决办法 毕竟都是大佬写好的我也不想自己写,毕竟我不是大佬,只是一个搬砖的,我就拿来搬了这样我把方法也分给大家吧!到底是哪个大佬我也忘了,光顾复制了,哈哈哈哈哈!

1.首先你创建一个继承UICollectionViewFlowLayout的类
/// 对齐方向的枚举, 可拓展, 命名可根据自己喜好
enum AlignType : NSInteger {
    case left = 0
    case center = 1
    case right = 2
}

class CollectionViewAlignFlowLayout: UICollectionViewFlowLayout {
    //两个Cell之间的距离
    var betweenOfCell : CGFloat{
        didSet{
            self.minimumInteritemSpacing = betweenOfCell
        }
    }
    //cell对齐方式
    var cellType : AlignType = AlignType.center
    //在居中对齐的时候需要知道这行所有cell的宽度总和
    var sumCellWidth : CGFloat = 0.0
    
    override init() {
        betweenOfCell = 5.0
        super.init()
        scrollDirection = UICollectionViewScrollDirection.vertical
        minimumLineSpacing = 5
        sectionInset = UIEdgeInsetsMake(5, 5, 5, 5)
    }
    convenience init(_ cellType:AlignType){
        self.init()
        self.cellType = cellType
    }
    convenience init(_ cellType: AlignType, _ betweenOfCell: CGFloat){
        self.init()
        self.cellType = cellType
        self.betweenOfCell = betweenOfCell
    }
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        
        let layoutAttributes_super : [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: rect) ?? [UICollectionViewLayoutAttributes]()
        let layoutAttributes:[UICollectionViewLayoutAttributes] = NSArray(array: layoutAttributes_super, copyItems:true)as! [UICollectionViewLayoutAttributes]
        var layoutAttributes_t : [UICollectionViewLayoutAttributes] = [UICollectionViewLayoutAttributes]()
        for index in 0..<layoutAttributes.count{
            
            let currentAttr = layoutAttributes[index]
            let previousAttr = index == 0 ? nil : layoutAttributes[index-1]
            let nextAttr = index + 1 == layoutAttributes.count ?
                nil : layoutAttributes[index+1]
            
            layoutAttributes_t.append(currentAttr)
            sumCellWidth += currentAttr.frame.size.width
            
            let previousY :CGFloat = previousAttr == nil ? 0 : previousAttr!.frame.maxY
            let currentY :CGFloat = currentAttr.frame.maxY
            let nextY:CGFloat = nextAttr == nil ? 0 : nextAttr!.frame.maxY
            
            if currentY != previousY && currentY != nextY{
                if currentAttr.representedElementKind == UICollectionElementKindSectionHeader{
                    layoutAttributes_t.removeAll()
                    sumCellWidth = 0.0
                }else if currentAttr.representedElementKind == UICollectionElementKindSectionFooter{
                    layoutAttributes_t.removeAll()
                    sumCellWidth = 0.0
                }else{
                    self.setCellFrame(with: layoutAttributes_t)
                    layoutAttributes_t.removeAll()
                    sumCellWidth = 0.0
                }
            }else if currentY != nextY{
                self.setCellFrame(with: layoutAttributes_t)
                layoutAttributes_t.removeAll()
                sumCellWidth = 0.0
            }
        }
        return layoutAttributes
    }
    
    /// 调整Cell的Frame
    ///
    /// - Parameter layoutAttributes: layoutAttribute 数组
    func setCellFrame(with layoutAttributes : [UICollectionViewLayoutAttributes]){
        var nowWidth : CGFloat = 0.0
        switch cellType {
        case AlignType.left:
            nowWidth = self.sectionInset.left
            for attributes in layoutAttributes{
                var nowFrame = attributes.frame
                nowFrame.origin.x = nowWidth
                attributes.frame = nowFrame
                nowWidth += nowFrame.size.width + self.betweenOfCell
            }
            break;
        case AlignType.center:
            nowWidth = (self.collectionView!.frame.size.width - sumCellWidth - (CGFloat(layoutAttributes.count - 1) * betweenOfCell)) / 2
            for attributes in layoutAttributes{
                var nowFrame = attributes.frame
                nowFrame.origin.x = nowWidth
                attributes.frame = nowFrame
                nowWidth += nowFrame.size.width + self.betweenOfCell
            }
            break;
        case AlignType.right:
            nowWidth = self.collectionView!.frame.size.width - self.sectionInset.right
            for var index in 0 ..< layoutAttributes.count{
                index = layoutAttributes.count - 1 - index
                let attributes = layoutAttributes[index]
                var nowFrame = attributes.frame
                nowFrame.origin.x = nowWidth - nowFrame.size.width
                attributes.frame = nowFrame
                nowWidth = nowWidth - nowFrame.size.width - betweenOfCell
            }
            break;
        }
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
2.声明一个全局变量var flowlayout: CollectionViewAlignFlowLayout!并且实现代理就好,完事!
        flowlayout = CollectionViewAlignFlowLayout(AlignType.left, 10*W)
        flowlayout.minimumLineSpacing = 10*W
        flowlayout.minimumInteritemSpacing = 15*W
        flowlayout.sectionInset = UIEdgeInsets.init(top: 10*W, left: 10*W, bottom: 10*W, right: 10*W)
        
        let collectionView = UICollectionView(frame: CGRect(x:0, y: 0, width:0, height:0), collectionViewLayout: flowlayout)

我的git demo地址:https://github.com/sunrose11/CollectionViewShopCart
下面的加减号 我是用的别人的 还是那句话自己写的有bug,这个哥们的写的很好而且很多样子,就一个类的代码量 我很是喜欢。给大家他的git:https://github.com/jkpang

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容

  • 月亮像是被掰开的橘子 远远的,在那里挂着 也许是我近视的缘故 好想上去咬它一口 尝尝是不是小丑橘 而我却喜欢酸的
    说什么话不像说谎h阅读 151评论 0 0
  • 今天是国庆节,祖国的生日,带着自豪而愉悦的心情,翻开了这篇文章。 《音乐表演艺术中的真与美》作者是南京艺术学院音乐...
    雨文兒阅读 821评论 0 0
  • 1.初中所谓的朋友,到高中还会联系么?(感觉不会了) 2.同学经常说衣服,我不怎么爱打扮,穿着舒服就行,但是有时会...
    陌墨离伤阅读 121评论 0 0
  • 我爱你 低到尘埃里 无法言语 无法自拔 唯有那对你情深义重的眷恋 我的心都在你那里 你能看见吗?
    石川河女神阅读 189评论 0 1