我有一個UITableView
其細胞包含在其上我需要執行三件事一個子視圖:在運行時根據內部的值上不同大小的一個UIView將一個掩模層內的UITableViewCell
- 改變其寬度約束一個特定於該單元格的對象
- 根據相同的值更改其背景顏色
- 圍繞視圖的左上角和左下角,但將右角保持原樣(因此
layer.cornerRadius
不是選項)
我用下面的代碼我的自定義UITableViewCell
子類中,實現對僅看,這是我從tableView:cellForRowAt:
叫一側的圓角效果:
func roundLeadingEdgesOfBar() {
let roundedLayer = CAShapeLayer()
roundedLayer.bounds = viewInQuestion.frame
roundedLayer.position = viewInQuestion.center
roundedLayer.path = UIBezierPath(roundedRect: viewInQuestion.bounds,
byRoundingCorners: [.topLeft, .bottomLeft],
cornerRadii: CGSize(width: 2, height: 2)).cgPath
viewInQuestion.layer.mask = roundedLayer
print("frame: \(viewInQuestion.frame)")
}
在上面的代碼中的print
語句產生下列輸出,表明viewInQuestion
具有相同的幀,每次當明確地在屏幕上它具有不:
frame: (175.0, 139.5, 200.0, 5.0)
frame: (175.0, 139.5, 200.0, 5.0)
frame: (175.0, 139.5, 200.0, 5.0)
frame: (175.0, 139.5, 200.0, 5.0)
所以我認爲視圖的寬度約束在我調用這個函數的時候沒有渲染出來。當我滾動整個表中查看,直到所有的細胞都拿出來看,然後滾動回眼簾,一切看起來正確,打印幀都不同,像我所期望的:
frame: (136.5, 79.5, 238.5, 5.0)
frame: (169.5, 79.5, 205.5, 5.0)
frame: (226.0, 79.5, 149.0, 5.0)
frame: (247.5, 79.5, 127.5, 5.0)
我已經在SO上多次讀取以執行取決於從layoutSubviews
內應用的約束的代碼,但是這給了我相同的結果。我甚至嘗試從tableView:willDisplay:forRowAt:
內撥打roundLeadingEdgesOfBar
,無濟於事。
我還發現this response to a similar problem,建議將掩碼圖層代碼放在drawRect:
內。這實際上爲我解決了99%的問題(拋開了性能問題),但仍然存在一些角落案例(沒有雙關語意思)留在非常長的表格視圖中,我仍然看到錯誤的行爲。
我最後的手段是通過performSelector
以0.00001的延遲調用我的舍入函數,它的作用在於,在屏幕消失之前,屏幕上出現大約一秒的錯誤 - 這與理想行爲還很遙遠,更不用說了可怕的代碼,我不得不爲它寫。
有沒有什麼方法可以在UITableViewCell
的視圖中使用其正確的運行時框架可靠地應用形狀圖層?
是您有您的細胞的一個子視圖麻煩的看法?如果是這樣,如果你*不*設置圖層蒙版,大小/位置是否正確? – DonMag
@DonMag是的,它是一個子視圖,不,如果我不設置圖層蒙版,所有單元格的輸出框架都是不正確的(但屏幕上的所有內容都是正確的) – Richard
行 - 請參閱我的答案,並參閱如果這會對你有用。 – DonMag