UITableViewCell對我何時reloadData被呼叫時發生的事情感到非常困惑。當 tableview 首次加載時,每個單元格都有正確的舍入。頂部的頂角是圓形的,中間沒有圓形,底部只有底部。
這是第一次加載時的樣子:

tableview.reloadData如果 a被呼叫(1 次或多次)
,會發生以下情況
這是創建單元格的代碼(in func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath))
guard let cell = tableView.dequeueReusableCell(withIdentifier: MyCell().reuseIdentifier, for: indexPath) as? MyCell else { return UITableViewCell() }
if indexPath.row == 0 {
cell.roundCorners(corners: (top: true, bottom: false))
}
if indexPath.row == 1 {
cell.roundCorners(corners: (top: false, bottom: false))
}
if indexPath.row == 2 {
cell.roundCorners(corners: (top: false, bottom: true))
}
這是圓角的代碼:
func roundCorners(corners: (top: Bool, bottom: Bool)) {
if !corners.top && !corners.bottom {
roundCorners(withRadius: 0)
} else if corners.top && corners.bottom {
roundCorners(withRadius: 20)
} else if corners.top {
roundCorners(corners: [.topLeft, .topRight], radius: 20)
} else if corners.bottom {
roundCorners(corners: [.bottomLeft, .bottomRight], radius: 20)
}
}
// and the actual rounding methods
func roundCorners() {
roundCorners(withRadius: bounds.size.height * 0.5)
}
func roundCorners(withRadius radius: CGFloat) {
layer.cornerRadius = radius
layer.masksToBounds = true
}
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
func maskedCorners(withRadius radius: CGFloat) {
layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
layer.cornerRadius = radius
clipsToBounds = true
}
func maskedCorners(corners: CACornerMask, radius: CGFloat) {
layer.maskedCorners = corners
layer.cornerRadius = radius
clipsToBounds = true
}
我嘗試了幾件沒有用的事情。
我沒有重用單元格(我認為可能重用它們的方式是在使用繪圖呼叫),而是嘗試每次都實體化單元格
我嘗試將單元格邊框重置為 0,然后設定哪些角應該是圓的
我嘗試在更新邊框后呼叫 .setNeedsDisplay()
我還要注意,如果我注釋掉舍入呼叫,則根本不會發生舍入,因此該問題與上面的代碼嚴格隔離。
非常愿意接受關于為什么在第一次 reloadData() 呼叫它之后會圍繞中間單元格并保持它向前移動的建議。
uj5u.com熱心網友回復:
對于這樣的布局,您不必撰寫代碼,而是可以使用 tableview style Inset Grouped。
只需轉到您的Storyboard settings> Table attribute inspector> Style> 選擇Inset Grouped:

這是輸出:

uj5u.com熱心網友回復:
夫妻問題...
1 - 您在bounds單元格布局完成之前使用,因此UIBezierPath(roundedRect: bounds, ...)可能是錯誤的。
2 - 在這段代碼中:
func roundCorners(corners: (top: Bool, bottom: Bool)) {
if !corners.top && !corners.bottom {
// NOT setting a layer mask
roundCorners(withRadius: 0)
} else if corners.top && corners.bottom {
// NOT setting a layer mask
roundCorners(withRadius: 20)
} else if corners.top {
// YES setting a layer mask
roundCorners(corners: [.topLeft, .topRight], radius: 20)
} else if corners.bottom {
// YES setting a layer mask
roundCorners(corners: [.bottomLeft, .bottomRight], radius: 20)
}
}
單元格被重復使用,因此您可以獲得用于第一行或最后一行的單元格 - 設定圖層蒙版的位置 - 然后將其用作“中間”行并且圖層蒙版未清除。
因此,要么清除“中間”行 ( layer.mask = nil) 的掩碼,要么始終呼叫使用掩碼的函式:
func roundCorners(corners: (top: Bool, bottom: Bool)) {
if !corners.top && !corners.bottom {
roundCorners(corners: [], radius: 0)
} else if corners.top && corners.bottom {
roundCorners(corners: [], radius: 20)
} else if corners.top {
roundCorners(corners: [.topLeft, .topRight], radius: 20)
} else if corners.bottom {
roundCorners(corners: [.bottomLeft, .bottomRight], radius: 20)
}
}
編輯
以下是一些示例代碼,您可能會發現它們使事情更易于管理......
細胞類
class RoundedCornersCell: UITableViewCell {
enum CornerStyle {
case solo, top, middle, bottom
}
public var cornerStyle: CornerStyle = .middle {
didSet {
setNeedsLayout()
}
}
public var cornerRadius: CGFloat = 20.0 {
didSet {
setNeedsLayout()
}
}
override func layoutSubviews() {
super.layoutSubviews()
var theCorners: UIRectCorner = []
switch cornerStyle {
case .solo:
theCorners = .allCorners
case .top:
theCorners = [.topLeft, .topRight]
case .bottom:
theCorners = [.bottomLeft, .bottomRight]
case .middle:
()
}
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: theCorners, cornerRadii: CGSize(width: cornerRadius, height: cornerRadius))
let mask = CAShapeLayer()
mask.path = path.cgPath
layer.mask = mask
}
}
示例控制器類
class ExampleTableVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
var myData: [Int] = []
var shuffledData: [Int]!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
myData = Array(1...5)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
tableView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
tableView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
tableView.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
])
tableView.register(RoundedCornersCell.self, forCellReuseIdentifier: "rcc")
tableView.dataSource = self
tableView.delegate = self
tableView.rowHeight = 60
tableView.backgroundColor = .clear
shuffledData = myData
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return shuffledData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let c = tableView.dequeueReusableCell(withIdentifier: "rcc", for: indexPath) as! RoundedCornersCell
// if there's only one row
if tableView.numberOfRows(inSection: indexPath.section) == 1 {
c.cornerStyle = .solo
} else {
c.cornerStyle =
indexPath.row == 0 ? .top
: indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 ? .bottom
: .middle
}
c.textLabel?.text = "\(shuffledData[indexPath.row])"
return c
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
shuffledData = myData.shuffled()
tableView.reloadData()
}
}
uj5u.com熱心網友回復:
您可以對 tableView 進行圓角:
tableView.layer.cornerRadius = 20
tableView.clipsToBounds = true
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/521909.html
標籤:IOS迅速合适的视图
