更改 CollectionView 单元内的 UIView 宽度

Posted

技术标签:

【中文标题】更改 CollectionView 单元内的 UIView 宽度【英文标题】:Change UIView width inside CollectionView Cell 【发布时间】:2021-01-03 22:59:32 【问题描述】:

我将 UIView "statusbar" 作为单元格内的背景,其工作方式类似于进度条。橙色视图是状态栏:

问题

当我启动应用程序时,状态栏正在上升以供演示使用。但是之后我无法更改状态栏的宽度(在layoutSubviews() 中设置之后)。

这是我的单元类代码:

import UIKit

class MyCollectionViewCell: UICollectionViewCell 
    @IBOutlet weak var myLabel: UILabel!
    @IBOutlet weak var statusbar: UIView!
    var newWidth = 0
    
    override func layoutSubviews() 
        self.layer.cornerRadius = 15.0
        self.layer.masksToBounds = true
        statusbar.frame = CGRect(x: 0, y: 0, width: newWidth, height: Int(self.frame.height))
        super.layoutSubviews()
    


extension MyCollectionViewCell
    func setStatusbar(completedTasks: Int, totalTasks: Int)
        newWidth = Int((Double(self.frame.width) * (Double(completedTasks) / Double(totalTasks)))) //calculates new width with given tasks
        
        //Local var attempt: (not working)
        /**var frameRect = statusbar.frame;
        frameRect.size.width = newWidth;
        statusbar.frame = frameRect; **/
        
        //Change CGRect attempt: (not working)
        statusbar.frame = CGRect(x: 0, y: 0, width: newWidth, height: Int(self.frame.height))
        
        //Somehow update the cells... should call layoutSubviews here?
        reloadInputViews()
    

在我的 ViewController.swift 中,我将状态栏宽度更改为 cell.setStatusbar(completedTasks: indexPath.row, totalTasks: 47)

以下是 ViewController.swift 中的两个重要函数,我想从中更改状态栏:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell
    cell.myLabel.text = self.items[indexPath.row]
    cell.backgroundColor = UIColor(rgb: 0xF444444)
    cell.setStatusbar(completedTasks: indexPath.row, totalTasks: 47) //Makes the statusbar increasing with every cell for testing when launched
    return cell


func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    // handle tap events
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell
    cell.setStatusbar(completedTasks: 47, totalTasks: 47) //Should make the statusbar to 100% (equal width as cell) for testing!
    collectionview.reloadData()

有人可以帮我吗...我只是无法更改“状态栏”(橙色 UIView):/

谢谢!

【问题讨论】:

【参考方案1】:

不要在didSelectItemAt 中调用collectionview.reloadData(),因为这会导致所有单元格自行重新加载并将completedTasks 设置回indexPath.row

调用setStatusBar 或调用layoutSubviews 后,您不需要重新加载collectionview(无论如何,您不应该直接调用它,您应该使用setNeedsLayout

【讨论】:

以上是关于更改 CollectionView 单元内的 UIView 宽度的主要内容,如果未能解决你的问题,请参考以下文章

点击tableview内的collectionview单元格导航

单元格获取其前一个单元格的索引 - Tableview 内的 Collectionview

为 tableview 单元内的 collectionview 加载更多功能

为啥当我向下滚动iOS(tableView内的collectionview)时取消选择单元格?

当点击collectionView单元格内的按钮时,如何从tableViewCell内的collectionView获取表视图行并推送到viewController

tableView 单元格内的多个 collectionView 单元格在滚动时更改设计