UITableView 单元格中的动态形状(Swift)

Posted

技术标签:

【中文标题】UITableView 单元格中的动态形状(Swift)【英文标题】:Dynamic Shapes in UITableView Cell (Swift) 【发布时间】:2016-01-27 22:51:24 【问题描述】:

我是 Swift 的新手,很适合 UIView 类。我有一个带有视图对象(左)和标签(右)的 TableView(下)。表格本身工作正常,标签按预期显示。

我遇到的问题是我希望标签旁边的 View 对象包含各种形状和颜色,具体取决于支持表格的数组中的值...

var tArray = [["Row 1","Row 2", "Row 3", "Row 4", "Row 5"],
              ["Circle","Circle","Square","Square","Diamond"],
              ["Blue","Red","Green","Red","Purple"]]

所以在“第 1 行”旁边,我想要一个蓝色圆圈等。我已将 View 对象链接到自定义类。但我需要一种方法来动态创建形状并填充适当的颜色。

在 TableViewController 中,我有以下内容,它正在调用 Symbol 类,并且我正在返回一个黑色圆圈(我现在是硬编码的圆圈)...

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    cell.cellLabel.text = tArray[0][indexPath.row]
    cell.cellSymbol = Symbol.init()
    return cell

在我的自定义符号类中:

import UIKit

class Symbol: UIView 

var inColor: String
var inShape: String

init (in_color: String, in_shape: String) 

    self.inColor = in_color
    self.inShape = in_shape

    super.init(frame: CGRect(x: 0, y: 0, width: 70, height: 70))



override func drawRect(rect: CGRect) 

    let path = UIBezierPath(ovalInRect: rect)

    switch self.inColor 
    case "Green" : UIColor.greenColor().setFill()
    case "Blue" : UIColor.blueColor().setFill()
    case "Yellow" : UIColor.yellowColor().setFill()
    case "Cyan" : UIColor.cyanColor().setFill()
    case "Red" : UIColor.redColor().setFill()
    case "Brown" : UIColor.brownColor().setFill()
    case "Orange" : UIColor.orangeColor().setFill()
    case "Purple" : UIColor.purpleColor().setFill()
    case "Grey" : UIColor.darkGrayColor().setFill()
    default: UIColor.blackColor().setFill()
    

    path.fill()


required init?(coder aDecoder: NSCoder) 

    self.inColor = ""
    self.inShape = ""

    super.init(coder: aDecoder)



override init(frame: CGRect) 

    self.inColor = ""
    self.inShape = ""
    super.init(frame: frame)

我可能在这一切上都错了,我完全愿意接受其他方法。为了编译,我必须添加所需的 init?并覆盖 init(frame: CGRect) 整体。我还必须对 self.inColor 和 .inShape 进行初始化才能编译,但由于我没有将参数传递给它们,所以我没有什么可分配的。

所以我每次得到的都是一个黑色圆圈。我现在对圆圈进行硬编码以保持简单。开关 self.inColor 每次都是 nil,所以它会下降到默认情况。

任何建议将不胜感激!!!!

【问题讨论】:

到底是什么问题? 我想问题是 - 根据数组中的数据,在每个自定义表格单元格中获得适当颜色的形状的最佳方法是什么?我显然没有选择最好的方法,或者我没有正确执行。我已经放入了一些打印语句,似乎是“必需的初始化?”在我启动第一个符号之前就被调用了。我必须输入的各种 init 让我感到困惑。 【参考方案1】:

当您设置 cellSymbol 时,您正在创建 Symbol 类的新实例。您永远不会修改 cellSymbol 的任何属性,因此它始终是黑色的。

试试:

cell.cellSymbol.inColor = self.tArray[2][indexPath.row]

【讨论】:

谢谢乔治。那运行但没有解决问题。需要的 init 是先被调用的,我不能给它传递任何参数。 别管inits,它是实际的inShapeinColorstrings 驱动你的drawRect。正如@George 所回答,将cell.cellSymbol = Symbol.init() 替换为cell.cellSymbol.inColor = ...【参考方案2】:

https://***.com/a/35049741/218152 已解决您代码中的“始终为黑色”错误。以下是建议的改进。

@IBInspectable

更少的代码,更多的功能

用这个替换你的整个Symbol 类:

@IBDesignable class Symbol: UIView 

    var color = UIColor.blackColor()
    
    @IBInspectable var inColor: String = "Black" 
        didSet 
            switch inColor 
            case "Green" : color = UIColor.greenColor()
            case "Blue" : color = UIColor.blueColor()
            case "Yellow" : color = UIColor.yellowColor()
            case "Cyan" : color = UIColor.cyanColor()
            case "Red" : color = UIColor.redColor()
            case "Brown" : color = UIColor.brownColor()
            case "Orange" : color = UIColor.orangeColor()
            case "Purple" : color = UIColor.purpleColor()
            case "Grey" : color = UIColor.darkGrayColor()
            default: color = UIColor.blackColor()
            
        
    

    override func drawRect(rect: CGRect) 
        color.setFill()
        let path = UIBezierPath(ovalInRect: rect)
        path.fill()
    

使用它的方式与使用前一个相同 (cell.cellSymbol.inColor = ...)。它的优点是还可以从 Interface Builder 进行可视化编辑。它也不需要特殊初始化(没有init)。

此实现具有直接接受UIColor 的额外优势,如cell.cellSymbol.color = ... 进一步的改进包括使用 tintColor 而不是创建自己的实例、不区分大小写的颜色、枚举而不是名称。

【讨论】:

哇。我从来不知道 IBInspectable 和 IBDesignable。看起来真的很有用。有很多东西要学...【参考方案3】:

感谢@SwiftArchitect 完成了大部分工作。我在形状部分添加了。正如@SwiftArchitect 所指出的,还有其他改进需要改进,但效果很好!

import UIKit

@IBDesignable class Symbol: UIView 

var color = UIColor.blackColor()

@IBInspectable var inShape: String = "Circle"

@IBInspectable var inColor: String = "Black" 
    didSet 
        switch inColor 
        case "Green" : color = UIColor.greenColor()
        case "Blue" : color = UIColor.blueColor()
        case "Yellow" : color = UIColor.yellowColor()
        case "Cyan" : color = UIColor.cyanColor()
        case "Red" : color = UIColor.redColor()
        case "Brown" : color = UIColor.brownColor()
        case "Orange" : color = UIColor.orangeColor()
        case "Purple" : color = UIColor.purpleColor()
        case "Grey" : color = UIColor.darkGrayColor()
        default: color = UIColor.blackColor()
        
    



override func drawRect(rect: CGRect) 

    var path = UIBezierPath()

    switch shape 
    case "Circle": path = UIBezierPath(ovalInRect: rect)
    case "Square" : path = UIBezierPath(roundedRect: rect, cornerRadius: 5.0)
    case "Triangle" :
        path.moveToPoint(CGPoint(x: frame.width / 2, y: 0))
        path.addLineToPoint(CGPoint(x: 0, y: frame.height))
        path.addLineToPoint(CGPoint(x: frame.width, y: frame.height))
    case "Diamond" :
        path.moveToPoint(CGPoint(x: frame.width / 2, y: 0))
        path.addLineToPoint(CGPoint(x: 0, y: frame.height / 2))
        path.addLineToPoint(CGPoint(x: frame.width / 2, y: frame.height))
        path.addLineToPoint(CGPoint(x: frame.width, y: frame.height / 2))
    default: print("unknown shape")

    

    color.setFill()
    path.fill()



【讨论】:

你不能直接使用inShape 而不是给shape 分配相同的值然后使用它吗? 好的,谢谢。我以为我有一个实际上没有的范围问题。编辑了上面的代码。

以上是关于UITableView 单元格中的动态形状(Swift)的主要内容,如果未能解决你的问题,请参考以下文章

如何让 UITableView 在动态高度单元格中滚动到底部?

UITableView 自定义单元格高度未正确管理 swift 中的动态约束

更改单元格中的数据后,UITableView 中的自定义单元格将无法正确重新加载

UITableview 默认单元格中的自定义分隔符显示意外行为

如何从动态 UITableView 单元格中获取 UILabel 的大小?

Swift:如何在动态 UITableView 的自定义单元格中获取滑块的值?