【发布时间】:2021-03-31 15:16:54
【问题描述】:
我正在编写一个 GraphViewController 类,其中包含一组图形(LineChartView 类型)。但是,当我尝试以集合视图的单元格格式显示这些图表时(使用被调用的类GraphCell),LineChartView 对象似乎没有加载任何数据,即使这些函数在内部调用GraphViewController 班级。到目前为止,这是我的代码的相关位:
class GraphViewController: UIViewController {
//lazy var only calculated when called
lazy var lineChartView: LineChartView = {
let chartView = LineChartView()
chartView.backgroundColor = .systemBlue
chartView.rightAxis.enabled = false //right axis contributes nothing
let yAxis = chartView.leftAxis
yAxis.labelFont = .boldSystemFont(ofSize: 12)
yAxis.setLabelCount(6, force: false)
yAxis.labelTextColor = .white
yAxis.axisLineColor = .white
yAxis.labelPosition = .outsideChart
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.labelFont = .boldSystemFont(ofSize: 12)
xAxis.setLabelCount(6, force: false)
xAxis.labelTextColor = .white
xAxis.axisLineColor = .systemBlue
chartView.animate(xAxisDuration: 1)
return chartView
}()
var graphColl: UICollectionView!
var graphs: [LineChartView] = []
var graphReuseID = "graph"
var homeViewController: ViewController = ViewController()
let dataPts = 50
var yValues: [ChartDataEntry] = []
var allWordsNoPins: [Word] = []
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
setUpViews();
setUpConstraints()
}
func setUpViews(){
let layout = UICollectionViewFlowLayout()
layout.minimumLineSpacing = padding/3.2
layout.scrollDirection = .vertical
graphColl = UICollectionView(frame: .zero, collectionViewLayout: layout)
graphColl.translatesAutoresizingMaskIntoConstraints = false
graphColl.dataSource = self
graphColl.delegate = self
//must register GraphCell class before calling dequeueReusableCell
graphColl.register(GraphCell.self, forCellWithReuseIdentifier: graphReuseID)
graphColl.backgroundColor = .white
view.addSubview(graphColl)
print("stuff assigned")
assignData()
setData()
graphs.append(lineChartView)
}
可以假设setUpConstraints() 工作正常,因为图形集合确实出现了。以下是必须处理我正在使用的集合视图的所有函数:
//INSIDE GraphViewController
extension GraphViewController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize{
//collectionView.frame.height -
let size = 25*padding
let sizeWidth = collectionView.frame.width - padding/3
return CGSize(width: sizeWidth, height: size)
}
}
extension GraphViewController: UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return graphs.count //total number of entries
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let graphColl = collectionView.dequeueReusableCell(withReuseIdentifier: graphReuseID, for: indexPath) as! GraphCell
graphColl.configure(graph: graphs[indexPath.item])
return graphColl
}
}
和:
//configure function INSIDE GraphCell
func configure(graph: LineChartView){
chartView = graph
}
这里是assignData() 和setData() 函数:
func setData(){
let set1 = LineChartDataSet(entries: yValues, label: "Word Frequency")
let data = LineChartData(dataSet: set1)
set1.drawCirclesEnabled = true
set1.circleRadius = 3
set1.mode = .cubicBezier //smoothes out curve
set1.setColor(.white)
set1.lineWidth = 3
set1.drawHorizontalHighlightIndicatorEnabled = false //ugly yellow line
data.setDrawValues(false)
lineChartView.data = data
}
func assignData(){
setUpTempWords()
let dataValues = allWordsNoPins
print(allWordsNoPins.count)
for i in 0...dataPts-1{
yValues.append(ChartDataEntry(x: Double(i), y: Double(dataValues[i].count)))
}
}
也可以假设setUpTempWords() 函数工作正常,因为下面的截图:
在这里,我在 GraphViewController 类中的 GraphColl UICollectionView 变量上直接绘制了 LineChartView 类型的 lineChartView 对象。显示数据。但是,当我尝试在 GraphCell 类中绘制相同的图表时,我得到了
“没有可用的图表数据。”我已经在我的 GraphViewController 类中跟踪了调用,根据 viewDidLoad() 函数的设置方式,我可以得出结论,正在调用 lineChartView 设置方法(assignData() 等)。作为参考,这是我的 GraphCell 类代码:
import UIKit
import Charts
class GraphCell: UICollectionViewCell {
var chartView = LineChartView()
var graphCellBox: UIView!
override init(frame: CGRect){
super.init(frame: frame)
contentView.backgroundColor = .blue
chartView.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(chartView)
graphCellBox = UIView()
graphCellBox.translatesAutoresizingMaskIntoConstraints = false
//graphCellBox.backgroundColor = cellorange
graphCellBox.layer.cornerRadius = 15.0
contentView.addSubview(graphCellBox)
setUpConstraints()
}
func setUpConstraints(){
NSLayoutConstraint.activate([
graphCellBox.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
graphCellBox.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
graphCellBox.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
graphCellBox.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
chartView.topAnchor.constraint(equalTo: graphCellBox.topAnchor),
chartView.bottomAnchor.constraint(equalTo: graphCellBox.bottomAnchor),
chartView.leadingAnchor.constraint(equalTo: graphCellBox.leadingAnchor),
chartView.trailingAnchor.constraint(equalTo: graphCellBox.trailingAnchor),
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure(graph: LineChartView){
chartView = graph
}
}
附带说明,将 lineChartView 更改为非惰性(普通)变量并不能解决此问题。我怀疑惰性声明是问题所在,因为该图仅在调用时才会被初始化,但事实并非如此。感谢您阅读这篇文章,我将不胜感激任何方向或指导!
【问题讨论】:
-
在
UICollectionViewCell中,您正在使用chartView配置(添加子视图、锚点等)所有内容,但之后,您将其替换为chartView = graph,期望之前的视图仍然正确?我不认为它应该是这样工作的。相反,正如问题中所建议的那样,对图表使用“容器视图”,即“占位符视图”。
标签: ios swift charts uicollectionview cocoapods