草庐IT

ios - UICollectionView 自调整大小自定义单元格

coder 2023-09-05 原文

我的印象是,UICollectionView 中的自动调整单元格大小在 iOS 8 中变得非常简单。所以,我可能在这里遗漏了一些东西。

我使用 UICollectionViewFlowLayout 的子类作为我的布局:

class BuildCollectionViewFlowLayout: UICollectionViewFlowLayout {
    required init(coder: NSCoder) {
        super.init(coder: coder)

        self.minimumLineSpacing = 1
        self.sectionInset.top = 20
        self.estimatedItemSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: 90)
    }
}

然后我的 ViewControllerUICollectionViewController 的子类,如下所示:

class ViewController: UICollectionViewController {

    let CellIdentifier = "CellIdentifier"
    let apiClient: APIClient()

    var builds:Array<JSON>? = []

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.
        self.collectionView.registerClass(BuildProjectStatusCollectionViewCell.self, forCellWithReuseIdentifier: CellIdentifier)

        self.apiClient.getProjects({ (projects, error) -> Void in
            if (error == nil) {
                dispatch_async(dispatch_get_main_queue(), {
                    self.builds = projects
                    self.collectionView.reloadData()
                })
            }
            else {

            }
        })
    }

    override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.builds!.count;
    }

    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        var cell:BuildProjectStatusCollectionViewCell = self.collectionView.dequeueReusableCellWithReuseIdentifier(CellIdentifier, forIndexPath: indexPath) as BuildProjectStatusCollectionViewCell;
        cell.setup(self.builds?[indexPath.row])

        return cell;
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

最后是我的 View 单元格:

class BuildProjectStatusCollectionViewCell : UICollectionViewCell {

    var projectNameLabel: UILabel!
    var lastCommitMessageLabel: UILabel!

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.initialize()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.initialize()
    }

    override func awakeFromNib() {
        self.initialize()
    }

    func initialize() {
        self.contentView.frame = self.bounds;
        self.contentView.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight

        self.projectNameLabel = UILabel(forAutoLayout: ())
        self.lastCommitMessageLabel = UILabel(forAutoLayout: ())
        self.lastCommitMessageLabel.autoresizingMask = UIViewAutoresizing.FlexibleHeight
        self.lastCommitMessageLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping
        self.lastCommitMessageLabel.numberOfLines = 0

        self.contentView.addSubview(self.projectNameLabel)
        self.contentView.addSubview(self.lastCommitMessageLabel)

        setNeedsUpdateConstraints()
    }

    func setup(project:JSON!) -> Void {
        self.projectNameLabel!.text = project["name"].stringValue
        let builds: Array<JSON> = project["builds"].arrayValue!

        if builds.count == 1 {
            if builds[0]["status"].stringValue == "success" {
                self.backgroundColor = UIColor(red: 68/255, green: 175/255, blue: 105/255, alpha: 1.0)
            }
            else {
                self.backgroundColor = UIColor(red: 254/255, green: 57/255, blue: 48/255, alpha: 1.0)
            }

            self.lastCommitMessageLabel!.text = builds[0]["message"].stringValue
        }
    }

    override func preferredLayoutAttributesFittingAttributes(layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes! {
        let attr: UICollectionViewLayoutAttributes = layoutAttributes.copy() as UICollectionViewLayoutAttributes
        // Without this, it crashes. AutoLayout constraints playing around. Error: the item width must be less than the width of the UICollectionView minus the section insets left and right values.

        return attr;
    }

    override func updateConstraints() {
        super.updateConstraints()

        self.projectNameLabel.autoPinEdgesToSuperviewEdgesWithInsets(UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5), excludingEdge: ALEdge.Bottom)
        self.lastCommitMessageLabel.autoPinEdge(ALEdge.Top, toEdge: ALEdge.Bottom, ofView: self.projectNameLabel, withOffset: 10)
        self.lastCommitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Leading, withInset: 5)
        self.lastCommitMessageLabel.autoPinEdgeToSuperviewEdge(ALEdge.Trailing, withInset: 25)
    }
}

单元格的大小设置为布局类中的 estimatedItemSize

我是否应该在 preferredLayoutAttributesFittingAttributes 方法中手动计算项目高度?

如果是这样, TableView 不支持 100% 自动调整行大小吗? ( http://www.appcoda.com/self-sizing-cells/ )

最佳答案

您不需要覆盖 preferredLayoutAttributesFittingAttributes。而且您的覆盖不会调用 super,根据文档:

The default implementation of this method adjusts the size values to accommodate changes made by a self-sizing cell. Subclasses can override this method and use it to adjust other layout attributes too. If you override this method and want the cell size adjustments, call super first and make your own modifications to the returned attributes.

因此您收到的警告是合法的。它告诉您您的单元格不能比您的 Collection View 宽。这可能是因为您在设置 estimatedItemSize 时没有考虑项目间间距(默认情况下大于 0)。尝试设置小得多的尺寸。它应该有效。

如果您正在做的只是尝试自动调整一个维度的大小(即始终保持全宽),那就别费心了。它不会起作用,因为 estimatedItemSize 意味着两个维度都可以调整大小。

关于ios - UICollectionView 自调整大小自定义单元格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26568095/

有关ios - UICollectionView 自调整大小自定义单元格的更多相关文章

  1. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  2. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  3. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  4. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  5. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  6. ruby-on-rails - 如何在 Rails 3 中创建自定义脚手架生成器? - 2

    有这些railscast。http://railscasts.com/episodes/218-making-generators-in-rails-3有了这个,你就会知道如何创建样式表和脚手架生成器。http://railscasts.com/episodes/216-generators-in-rails-3通过这个,您可以了解如何添加一些文件来修改脚手架View。我想把两者结合起来。我想创建一个生成器,它也可以创建脚手架View。有点像RyanBates漂亮的生成器或web_app_themegem(https://github.com/pilu/web-app-theme)。我

  7. ruby-on-rails - Prawn - 表格单元格内的链接 - 2

    我正在尝试用Prawn生成PDF。在我的PDF模板中,我有带单元格的表格。在其中一个单元格中,我有一个电子邮件地址:cell_email=pdf.make_cell(:content=>booking.user_email,:border_width=>0)我想让电子邮件链接到“mailto”链接。我知道我可以这样链接:pdf.formatted_text([{:text=>booking.user_email,:link=>"mailto:#{booking.user_email}"}])但是将这两行组合起来(将格式化文本作为内容)不起作用:cell_email=pdf.make_c

  8. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  9. ruby-on-rails - 从应用程序中自定义文件夹内的命名空间自动加载 - 2

    我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty

  10. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

随机推荐