为啥我的 UITableView 单元格的渐变子层没有正确显示?
Posted
技术标签:
【中文标题】为啥我的 UITableView 单元格的渐变子层没有正确显示?【英文标题】:Why isn’t the gradient sublayer of my UITableView cell displaying properly?为什么我的 UITableView 单元格的渐变子层没有正确显示? 【发布时间】:2020-05-16 06:16:48 【问题描述】:我有一个带有自定义单元格的UITableView
,我使用渐变作为背景。我在 Swift Playgrounds 中编码,当我运行 Playground 时,带有渐变的单元格没有圆角。
另外,当我在表格中上下滚动时,有时单元格中的渐变会突然“分成两半”(见下图)。我做错了什么?
我的代码:
class ViewController: UITableViewController
// Array that holds the messages
var textMessages = [String]()
let sampleTextField = UITextField(frame: CGRect(x: 20, y: 20, width: 300, height: 40))
override func viewDidLoad()
super.viewDidLoad()
// Reguster custom cell
tableView.register(ChatMessageCell.self, forCellReuseIdentifier: "cell_1")
// Turn off seperators
tableView.separatorStyle = .none
// Set header, footer height
tableView.sectionFooterHeight = 75
tableView.sectionHeaderHeight = 75
// Custom header
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 75))
customView.backgroundColor = UIColor(white: 0.9, alpha: 1)
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 75))
button.setTitle("Submit", for: .normal)
customView.addSubview(button)
return customView
//Custom footer
override func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView?
let customView = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 75))
customView.backgroundColor = UIColor(white: 0.9, alpha: 1)
sampleTextField.placeholder = "Enter text here"
sampleTextField.font = UIFont.systemFont(ofSize: 15)
sampleTextField.borderStyle = .none
sampleTextField.backgroundColor = .white
sampleTextField.autocorrectionType = UITextAutocorrectionType.no
sampleTextField.keyboardType = UIKeyboardType.default
sampleTextField.returnKeyType = UIReturnKeyType.done
sampleTextField.clearButtonMode = UITextField.ViewMode.whileEditing
sampleTextField.contentVerticalAlignment = UIControl.ContentVerticalAlignment.center
sampleTextField.layer.shadowRadius = 10
sampleTextField.layer.shadowColor = UIColor.black.cgColor
sampleTextField.layer.shadowOffset = CGSize(width: 0, height: 0)
sampleTextField.layer.shadowOpacity = 0.5
sampleTextField.layer.cornerRadius = 16
sampleTextField.layer.masksToBounds = true
let buttonZ = UIButton(type: .custom)
buttonZ.setImage(UIImage(named: "send.png"), for: .normal)
buttonZ.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
buttonZ.frame = CGRect(x: CGFloat(sampleTextField.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
buttonZ.backgroundColor = .blue
sampleTextField.rightView = buttonZ
sampleTextField.rightViewMode = .always
buttonZ.addTarget(self, action: #selector(updateView), for: .touchUpInside)
customView.layer.cornerRadius = 20
customView.layer.shadowRadius = 5.0
customView.layer.shadowColor = UIColor.black.cgColor
customView.layer.shadowOffset = CGSize(width: 0, height: 0)
customView.layer.shadowOpacity = 0.8
customView.addSubview(sampleTextField)
return customView
@objc func updateView()
adddatextbruh()
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return textMessages.count
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell_1", for: indexPath) as! ChatMessageCell
cell.selectionStyle = .none
if indexPath.row % 2 == 1
cell.messageLabel.text = textMessages[indexPath.row]
cell.bubbleBackgroundView.backgroundColor = UIColor(white: 0.9, alpha: 1)
return cell
else
cell.messageLabel.text = textMessages[indexPath.row]
//cell.setupConstraints(side: 0)
//cell.bubbleBackgroundView.backgroundColor = .blue
var gradientLayer : CAGradientLayer =
let layer = CAGradientLayer()
layer.colors = [UIColor.red, UIColor.blue].map$0.cgColor
layer.startPoint = CGPoint(x: 0.5, y: 1.0)
layer.endPoint = CGPoint(x: 0.5, y: 0.0)
layer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
layer.frame = cell.bubbleBackgroundView.bounds
layer.masksToBounds = true
return layer
()
cell.bubbleBackgroundView.layer.insertSublayer(gradientLayer, at: 0)
/*
let gradientLayer = CAGradientLayer()
let colorTop : UIColor = .red
let colorBottom : UIColor = .blue
gradientLayer.colors = [colorTop.cgColor, colorBottom.cgColor]
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.locations = [NSNumber(floatLiteral: 0.0), NSNumber(floatLiteral: 1.0)]
gradientLayer.frame = cell.bubbleBackgroundView.bounds
cell.bubbleBackgroundView.layer.insertSublayer(gradientLayer, at: 0)
*/
return cell
//let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! ChatMessageCell
// cell.textLabel?.text = "We want to provide a longer string that is actually going to wrap onto the next line and maybe even a third line."
// cell.textLabel?.numberOfLines = 0
func adddatextbruh()
let botInstance = Bot()
var writtenText = sampleTextField.text
textMessages.append(writtenText!)
tableView.beginUpdates()
tableView.insertRows(at: [
(NSIndexPath(row: textMessages.count-1, section: 0) as IndexPath)], with: .automatic)
tableView.endUpdates()
tableView.scrollToRow(at: IndexPath(row: textMessages.count-1, section: 0), at: UITableView.ScrollPosition.bottom, animated: true)
var botReply = botInstance.replyTo(writtenText!)
textMessages.append(botReply)
tableView.beginUpdates()
tableView.insertRows(at: [
(NSIndexPath(row: textMessages.count-1, section: 0) as IndexPath)], with: .automatic)
tableView.endUpdates()
tableView.scrollToRow(at: IndexPath(row: textMessages.count-1, section: 0), at: UITableView.ScrollPosition.bottom, animated: true)
textMessages.append(getSent().description)
tableView.beginUpdates()
tableView.insertRows(at: [
(NSIndexPath(row: textMessages.count-1, section: 0) as IndexPath)], with: .automatic)
tableView.endUpdates()
tableView.scrollToRow(at: IndexPath(row: textMessages.count-1, section: 0), at: UITableView.ScrollPosition.bottom, animated: true)
【问题讨论】:
【参考方案1】:cellForItem
中的代码似乎很长。将来你甚至会经历它。如果您为UITableViewCell
创建一个subClass
并在其中进行自定义会更好。为了帮助您,我发布了使gradientLayer
在UITableViewCell
中正常工作所需的最低代码。玩弄它以获得您想要的结果。将其发布到您的 Xcode 游乐场,并在您自己进行更改时查看结果。关键是随着单元格帧的更新不断更新梯度层。
import UIKit
import PlaygroundSupport
class ViewController: UITableViewController
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 10
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
ChatCell()
class ChatCell: UITableViewCell
let gradientLayer = CAGradientLayer()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
layer.addSublayer(gradientLayer)
required init?(coder: NSCoder)
fatalError("init(coder:) has not been implemented")
override func layoutIfNeeded()
super.layoutIfNeeded()
gradientLayer.frame = bounds
PlaygroundPage.current.liveView = ViewController()
【讨论】:
以上是关于为啥我的 UITableView 单元格的渐变子层没有正确显示?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我无法使用具有自动布局的渐变子层来定位我的视图?它没有出现
为啥 UITableView 的最后一个单元格的高度用于剩余的空单元格?
为啥我的渐变层覆盖了我的 collectionView 单元格?