我有一个UICollectionViewCell
,里面有一个UIView。使单元出队时,我用必要的数据对其进行了初始化。数据初始化之后,在UIView
内,有一些要显示的图形。但是,什么也没有出现。
最初,它们全都在UICollectionView
cellForItemAt
方法内部并绘制了线条,但是它应该在UIView内部,因此我将其子类化并将代码放置在其中。这是它停止工作的地方。
我尝试覆盖draw方法,使用init内的绘图调用我的方法,然后从单元格中调用它们。我得到了显示在控制台中的打印语句,但屏幕上没有图形。
extension ChooseRouteViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Route", for: indexPath) as! PotentialRouteCell
cell.routeOutline = RouteOverview(frame: CGRect(x: 73 + 4, y: 8, width: (cell.bounds.width - 83), height: 98), route: instructions)
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: possibleRouteCollectionView.bounds.width - 40, height: 150)
}
}
class RouteOverview: UIView {
init(frame: CGRect, route: [Instruction]) {
super.init(frame: frame)
getOutline(from: route)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private struct Overview {
let fromStation: Station
let toStation: Station
let lineName: String
init(from: Station, to: Station, line: String) {
self.fromStation = from
self.toStation = to
self.lineName = line
}
}
private var overview: [Overview] = []
private var keyStations: [String] = []
private var linesToDraw: Int = 0
private var linesDrawn: [CAShapeLayer] = []
private var lineX: CGFloat = 24.0
private var lineY: CGFloat {
return self.bounds.height / 2
}
private var lineLength: CGFloat {
return (self.bounds.width - 48) / CGFloat(overview.count)
}
private func getOutline(from route: [Instruction]) {
for instruction in route {
if instruction.type == .route {
let instructionOverview = Overview(from: instruction.route.first!.station, to: instruction.route.last!.station, line: instruction.line)
overview.append(instructionOverview)
}
}
linesToDraw = overview.count
print("\n Debug: There are \(linesToDraw) lines to draw. Each line is \(lineLength) points long.")
drawLine(fromPoint: CGPoint(x: lineX, y: lineY), toPoint: CGPoint(x: lineX + lineLength, y: lineY), lineName: overview[linesDrawn.count].lineName)
}
private func drawLine(fromPoint start: CGPoint, toPoint end: CGPoint, lineName: String) {
lineX += lineLength
let line = CAShapeLayer()
let path = UIBezierPath()
path.move(to: start)
path.addLine(to: end)
line.lineWidth = 8
line.lineCap = .round
line.strokeColor = UIColor(named: lineName)!.cgColor
line.fillColor = UIColor(named: lineName)!.cgColor
line.path = path.cgPath
self.layer.insertSublayer(line, at: 0)
linesDrawn.append(line)
linesToDraw -= 1
if linesToDraw >= 0 {
addDetail(at: end, lineName: lineName)
}
}
func addDetail(at point: CGPoint, lineName: String) {
if linesToDraw != 0 {
let circle = CAShapeLayer()
let path = UIBezierPath(arcCenter: point, radius: 8, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
circle.lineWidth = 6
circle.strokeColor = UIColor.black.cgColor
circle.fillColor = UIColor.black.cgColor
circle.path = path.cgPath
let innerCircle = CAShapeLayer()
let innerPath = UIBezierPath(arcCenter: point, radius: 4, startAngle: 0, endAngle: CGFloat(Double.pi * 2), clockwise: true)
innerCircle.lineWidth = 6
innerCircle.strokeColor = UIColor.white.cgColor
innerCircle.fillColor = UIColor.white.cgColor
innerCircle.path = innerPath.cgPath
self.layer.addSublayer(circle)
self.layer.insertSublayer(innerCircle, above: circle)
}
let lineNameLabel = RoundLabel(frame: CGRect(x: point.x - (lineLength / 2) - 18, y: point.y + 16, width: 40, height: 24))
lineNameLabel.cornerRadius = 5.0
lineNameLabel.text = String(lineName.prefix(3))
lineNameLabel.textAlignment = .center
lineNameLabel.font = UIFont(name: "London Tube", size: 15.0)
lineNameLabel.backgroundColor = UIColor(named: lineName)!
lineNameLabel.textColor = .white
lineNameLabel.clipsToBounds = true
self.addSubview(lineNameLabel)
self.setNeedsLayout()
self.setNeedsDisplay()
if linesToDraw >= 1 {
drawLine(fromPoint: CGPoint(x: point.x, y: lineY), toPoint: CGPoint(x: point.x + lineLength, y: lineY), lineName: overview[linesDrawn.count].lineName)
}
}
}
它应该为每条路线指示画一条线,以火车线名的颜色表示。在两条线相遇的地方,应该有一个连接器斑点,如伦敦地铁图所示。
答案 0 :(得分:1)
在cellForItemAt
中,将routineOutline
设置为RouteOverview
。因此,您要保存对自定义视图的引用,但是在任何时候都看不到将RouteOverview
添加到视图层次结构。 (您正在向RouteOverview
添加形状图层,但从未添加RouteOverview
本身。)您有时需要调用addSubview
。