用 5 种不同的布局绘制 UITableViewCell
Posted
技术标签:
【中文标题】用 5 种不同的布局绘制 UITableViewCell【英文标题】:Draw UITableViewCell with 5 different layout 【发布时间】:2018-07-23 07:37:06 【问题描述】:我需要在 UITableView 中绘制 5 种不同风格的单元格,我需要你的一点帮助!我向你展示我在 ViewController 中写的内容:
var selfHeightCell : CGFloat? // for custom rowHeight
override func viewDidLayoutSubviews()
super.viewDidLayoutSubviews()
self.UITableView.estimatedRowHeight = 200.00;
self.selfHeightCell = UITableViewAutomaticDimension;
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 10
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cardCell", for: indexPath) as! CardCell
switch indexPath.row // this is for test my code
case 0:
selfHeightCell = cell.workTest(drawCard: .verySmallCard)
case 1:
selfHeightCell = cell.workTest(drawCard: .smallCard)
case 2:
selfHeightCell = cell.workTest(drawCard: .mediumCard)
case 3:
selfHeightCell = cell.workTest(drawCard: .basiqCard)
case 4:
selfHeightCell = cell.workTest(drawCard: .bigCard)
case 5:
selfHeightCell = cell.workTest(drawCard: .mediumCard)
case 6:
selfHeightCell = cell.workTest(drawCard: .mediumCard)
case 7:
selfHeightCell = cell.workTest(drawCard: .basiqCard)
case 8:
selfHeightCell = cell.workTest(drawCard: .basiqCard)
case 9:
selfHeightCell = cell.workTest(drawCard: .basiqCard)
default:
selfHeightCell = cell.workTest(drawCard: .basiqCard)
return cell
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
return selfHeightCell!
现在是我的 CardCell 的代码:
func workTest(drawCard: state) -> CGFloat
var heightOfCardRow : CGFloat = 0
switch drawCard
case .verySmallCard:
heightOfCardRow = self.drawCard(height : 60)
case .smallCard:
heightOfCardRow = self.drawCard(height : 100)
case .mediumCard:
heightOfCardRow = self.drawCard(height : 140)
case .basiqCard:
heightOfCardRow = self.drawCard(height : 200)
case .bigCard:
heightOfCardRow = self.drawCard(height : 280)
return heightOfCardRow
func drawCard(height : CGFloat) -> CGFloat
if(cardView.subviews.count == 0)
self.addSubview(cardView)
cardView.frame = CGRect(marginCardWidth,
marginCardHeight,
self.bounds.size.width - (marginCardWidth*2),
height - (marginCardHeight*2))
cardView.layer.cornerRadius = 10
if(self.ShadowLayerCard == nil)
let shadowLayer = CAShapeLayer()
self.ShadowLayerCard = shadowLayer
shadowLayer.path = UIBezierPath(roundedRect: cardView.bounds, cornerRadius: 10).cgPath
shadowLayer.fillColor = UIColor(rgb: 0xffcc00).cgColor
shadowLayer.shadowPath = shadowLayer.path
shadowLayer.shadowColor = UIColor.black.cgColor
shadowLayer.shadowRadius = 5
shadowLayer.shadowOpacity = 0.2
shadowLayer.shadowOffset = CGSize(width: 0, height: 0)
cardView.layer.insertSublayer(shadowLayer, at: 0)
return cardView.bounds.size.height + (marginCardHeight*2)
我给你看一张模拟器的图片:
抱歉所有代码,但我认为有必要解决我的问题。我认为错误是因为我以编程方式绘制或者我以错误的方式自定义单元格的高度!
我的问题是:产生这些问题的坏方法是什么?
【问题讨论】:
代码中有很多错误,UITableViewAutomaticDimension
需要约束,heightForRowAt
在cellForRowAt
之前被调用,所以这里覆盖高度是错误的,cardView
可以在情节提要中创建或使用约束,只需要一种细胞类型,....
@Tj3n 好的,为了修改我的cardView,我在情节提要中添加了这个之后,我在 CardCell 类中编辑了高度的约束?因为在我添加卡片后,我需要根据卡片状态枚举以编程方式添加几个按钮 UIImageView 和其他组件
【参考方案1】:
当使用动态单元格高度时,不要实现 heightForRowAt
,而是让 contentView 根据其内容自行布局,或者给它一个高度约束并在 cellForRowAt
中更改它
考虑那个单元类
class MyCell : UITableViewCell
let redView = UIView()
var redViewHCon:NSLayoutConstraint!
override init(style: UITableViewCellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
redView.translatesAutoresizingMaskIntoConstraints = false
self.contentView.addSubview(redView)
redView.backgroundColor = .red
NSLayoutConstraint.activate( [
redView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 20),
redView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 0),
redView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: 0),
redView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: -20)
])
redViewHCon = redView.heightAnchor.constraint(equalToConstant: 300)
redViewHCon.isActive = true
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
//
在cellForRowAt
let cell = tableView.dequeueReusableCell(withIdentifier:"pp") as! MyCell
cell.redViewHCon.constant = CGFloat((indexPath.row + 1) * 100)
//
在viewDidLoad
中添加这一行
tableView.register(MyCell.self, forCellReuseIdentifier: <#setIdentifier#>)
【讨论】:
感谢您的回复,但我以编程方式绘制卡片,请问如何“让 contentView 根据其内容自行布局”? 当你向它添加元素时,从上到下正确地钩住约束,然后它将根据没有任何常量的内容进行拉伸,但这对于标签和按钮等内在元素来说,如果你添加一个视图说那么你应该为它定义一个高度 对不起,但我不明白我需要做什么,首先我删除我的 heightForRowAt 函数,这是一个坏主意,但我需要以编程方式添加 cardView 的约束就是它? 我只是在我初始化我的自定义单元格时遇到了问题。我有这个错误Fatal error: init(coder:) has not been implemented
。我用你的代码
我使用故事板。并注册什么?以上是关于用 5 种不同的布局绘制 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章