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 是先被调用的,我不能给它传递任何参数。 别管init
s,它是实际的inShape
和inColor
strings 驱动你的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 默认单元格中的自定义分隔符显示意外行为