加载时出现 TableView 单元格大小调整/自动布局问题。但第二次重新加载后修复? - 图

TableView Cells resizing / Auto layout issue on load. But fixes after second reload? - Graph

有没有人知道为什么 tableView Cells 会调整大小?或者为什么他们在重新加载时调整大小?

我有一个单元格,我在其中从 ImageView 制作了一个图表。这个 imageView 有一个 1:1 纵横比,并且在 X 和 Y 的单元格中居中。然后我做了一些数学运算并使用 imageView 的最大边界来设置第二个 imageView,它是一个圆圈,以便在 graph-imageView 中绘制数据。

我还有一个 didSelectAtRow() 函数,可以重新加载轴上的单元格和 hides/unhides 标签。由于整行都被重新加载,imageView 中的绘图也被删除并重新绘制。

目前我遇到了一个奇怪的问题,即在单元格刷新几次之前,图表无法正确绘制点。即使在数学上,它也应该正确定位。

如何修复重新加载时单元格和 imageView 大小的变化,以便它在加载时正确显示?另外,为什么尺寸会改变?

负载单元格:

configureCell(): ---
x: Max  238.0
y: Max  238.0
hideDescriptionLabels()
point.silicaX:  3.32
X: xGood
point.aluminaY:  0.45
Y: yGood
x: Max  238.0
y: Max  238.0
xAdjust:  19.833333333333332
graphX:  111.86
yAdjust:  11.9
graphY:  142.79999999999998
aluminaAdjust:  4.5
(xGood, yGood):
x:  238.0
y:  238.0
xRect:  104.36
yRect:  135.29999999999998
imageRect:  (104.36, 135.29999999999998, 15.0, 15.0)

第一次重新加载时的单元格:

configureCell(): ---
x: Max  238.0
y: Max  238.0
hideDescriptionLabels()
point.silicaX:  3.32
X: xGood
point.aluminaY:  0.45
Y: yGood
x: Max  238.0
y: Max  238.0
xAdjust:  19.833333333333332
graphX:  111.86
yAdjust:  11.9
graphY:  142.79999999999998
aluminaAdjust:  4.5
(xGood, yGood):
x:  238.0
y:  238.0
xRect:  104.36
yRect:  135.29999999999998
imageRect:  (104.36, 135.29999999999998, 15.0, 15.0)

第二次和所有后续重新加载时的单元格:

configureCell(): ---
x: Max  324.0
y: Max  324.0
hideDescriptionLabels()
point.silicaX:  3.32
X: xGood
point.aluminaY:  0.45
Y: yGood
x: Max  324.0
y: Max  324.0
xAdjust:  27.0
graphX:  152.28
yAdjust:  16.2
graphY:  194.4
aluminaAdjust:  4.5
(xGood, yGood):
x:  324.0
y:  324.0
xRect:  144.78
yRect:  186.9
imageRect:  (144.78, 186.9, 15.0, 15.0)
    


编辑 1:

我一直在研究自动约束。我最终完全删除了它们并且在加载时看起来点出现在正确的位置:

(注:此图与其他图大小相同。)

但是,因为没有约束,图像是错误的size/location。

加载时 imageView 的框架似乎发生了奇怪的事情。并且在从笔尖唤醒几秒钟后重新加载视图之前,它不会重置。


编辑 2:

进一步探索加载时 imageView 边界的边缘:

被唤醒几秒后重新加载两次:

似乎约束没有正确加载。在重新加载单元格之前,它们不会得到修复。


编辑 3:

这个问题似乎在单元格是显示单元格加载时发生。

编辑:加载 viewController 时,如果带有图形的单元格不在屏幕上,则绘图会准确显示。但是,如果您刷新单元格,问题会在第一次重新加载时出现,并在随后的所有重新加载时得到解决。


编辑 4:添加了绘制基于与 imageView 边界相关的点的点的代码。

@IBOutlet weak var graphImageView: UIImageView!
   var maxX: CGFloat?
   var maxY: CGFloat?
   
   var xData = 0.0
   var yData = 0.0
   
   // X:
   let xGood = 0.75..<6.5
   // Y:
   let yGood = 0.1..<1.0

func configureCell(point: (silicaX: Double, aluminaY: Double), hideLabels: Bool) {
    xData = point.silicaX
    yData = point.aluminaY
    plotGraph()
}




func plotGraph() {
        // X:
        var xAdjust: CGFloat = 0.0
        var graphX: CGFloat = 0.0
        
        // Setup For Point:
        print("xData: ", xData)
        switch xData {
            
        case xGood:
            print("X: xGood")
            
            xAdjust = graphImageView.bounds.maxX / (6.0/(0.5)) // Account for missing 0.5 not diplayed (6/.5)\
            
            let xTick = graphImageView.bounds.maxX / 6
            graphX = xTick * CGFloat(xData) - xAdjust
            
        default:
            print("X: Default ---")
        }
        
        // Y:
        var yAdjust: CGFloat = 0.0
        var graphY: CGFloat = 0.0
        let aluminaAdjust = CGFloat(yData * 10)
        
        switch yData {
            
        case yGood:
            print("Y: yGood")
            yAdjust = graphImageView.bounds.maxY / (1 / 0.05) // Account for missing 0.05 not diplayed
            
            let yTick = (graphImageView.bounds.maxY / 10)
            
            graphY = graphImageView.bounds.maxY - (yTick * aluminaAdjust) + yAdjust // Subtract?
            
        default:
            print("Y: Default ---")
        }
        // Setup Dot:
        let imageView = UIImageView()
        
        // Image Rect:
        var imageRectSize: CGFloat = 30
        var xRect: CGFloat = 0.0
        var yRect: CGFloat = 0.0
        
        // Display Dot:
        switch (xData, yData) {
            
        // Good:
        case (xGood, yGood):
            print("(xGood, yGood):")
            imageRectSize = 15
            imageView.backgroundColor = .label
            
            xRect = graphX - (imageRectSize / 2)
            yRect = graphY - (imageRectSize / 2)
            
        // Error:
        default:
            print("Default: (point.silicaX, point.aluminaY) ---")
        }
        
        // Set Dot Position:
        let imageRect = CGRect(x: xRect, y: yRect, width: imageRectSize, height: imageRectSize)
        
        // Set Dot Properties:
        imageView.layer.cornerRadius = imageRectSize / 2
        imageView.layer.masksToBounds = true
        
        // Add Dot To View:
        imageView.frame = imageRect
        graphImageView.addSubview(imageView)
    }

编辑 5:添加约束图像


编辑 6:

我添加了以下代码:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        switch indexPath {
        case [sectionAnalysis, rowChart]:
            let graphCell = cell as! GraphTableViewCell
            graphCell.plotGraph()
        default:
            break
        }
    }

它似乎解决了重新加载时绘图(和 UIImageView 的边界)的问题。所以现在问题似乎仅限于当 viewController 加载时单元格在屏幕上时。

原来这是我需要的代码,以便在单元格完成设置后再次 运行 该函数。或者基本上设置所有布局。

 override func layoutSubviews() {
       super.layoutSubviews()
        plotGraph()
    }