草庐IT

UICollectionViewCell init初始化传参数实现

生命不止运动不息 2023-03-28 原文

问题: 想在初始化UICollectionViewCell的时候,根据类型来区分布局?

我们知道 复用的UICollectionViewCell 都是通过initWithFrame 来初始化的。

但是这个函数,如我们增加了一个参数,新增的这个参数如何传值进去呢?

方案:重写 UICollectionViewCell的初始化函数,写上需要的参数,然后根据需要的参数类型,分别写几个子cell,在 UICollectionView 注册cell时,分别根据类型注册子cell。 在UICollectionView的创建cell代理方法中,使用父cell。

注册cell:

let cv = UICollectionView.init(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .white
        cv.dataSource = self
        self.view.addSubview(cv)
        
        ///这里分别注册不同类型的cell
        if type == .wechat {
            cv.register(WechatVideoCell.self, forCellWithReuseIdentifier: "cell")
        }else if type == .bilibili{
            cv.register(BiliVideoCell.self, forCellWithReuseIdentifier: "cell")
        }else if type == .tiktok {
            cv.register(TiktokVideoCell.self, forCellWithReuseIdentifier: "cell")
        }

cell的代理代码:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as? VideoCell
        cell?.model = self.datas?[indexPath.row]
        
        return cell ?? UICollectionViewCell()
    }

示例Cell代码:

// MARK: - Cell
class VideoCell: UICollectionViewCell {
    
    var titleL = UILabel()
    var coverView = UIImageView()
    var timeL = UILabel()
    
    var model: CellModel?{
        didSet{
            titleL.text = model?.title
            coverView.image = UIImage.init(named: model?.cover ?? "")
        }
    }
    
    init(frame: CGRect, type: ListType) {
        super.init(frame: frame)
            
        //针对不同的类型,做你想做的事 ?
        var titleH: CGFloat = 20.0
        if type == .wechat {
            titleH = 20.0
            VStack(titleL,coverView).embedIn(self.contentView)
        }else if type == .bilibili {
            titleH = 30.0
            
            VStack(coverView).embedIn(self.contentView)
            HStack(titleL).embedIn(self.contentView).align(.center)
            
        }else if type == .tiktok {
            titleH = 40.0
            
            VStack(coverView,titleL).embedIn(self.contentView)
        }
        
        titleL.align(.center).color("#FFF")
        titleL.pin(.h(titleH),.lowHugging).bg("random")
        coverView.mode(.scaleAspectFill).pin(.lowHugging)
        
        
        self.backgroundColor = Color("#EEE")
        
        coverView.clipsToBounds = true
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class CellModel: NSObject {
    var title: String?
    var cover: String?
}


// MARK: - 用来作为传参的子cell
class WechatVideoCell: VideoCell{
    override init(frame: CGRect) {
        //这里调用父类的时候,指定类型
        super.init(frame: frame, type: .wechat)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class BiliVideoCell: VideoCell{
    override init(frame: CGRect) {
        //这里调用父类的时候,指定类型
        super.init(frame: frame, type: .bilibili)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class TiktokVideoCell: VideoCell{
    override init(frame: CGRect) {
        //这里调用父类的时候,指定类型
        super.init(frame: frame, type: .tiktok)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

完整demo地址

链接: https://pan.baidu.com/s/1bVkAb7EbPZonJGYm0JsOZA?pwd=gkbt 提取码: gkbt

gitee:
https://gitee.com/dosedo/init-collection-cell-demo.git

有关UICollectionViewCell init初始化传参数实现的更多相关文章

  1. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  4. ruby - 如何在 Ruby 中拆分参数字符串 Bash 样式? - 2

    我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  7. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  8. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  9. ruby - 定义方法参数的条件 - 2

    我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano

  10. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

随机推荐