【问题标题】: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)
    }
}

【问题讨论】:

    标签: ios swift uitableview uikit


    【解决方案1】:

    cellForItem 中的代码似乎很长。将来你甚至会经历它。如果您为UITableViewCell 创建一个subClass 并在其中进行自定义会更好。为了帮助您,我发布了使gradientLayerUITableViewCell 中正常工作所需的最低代码。玩弄它以获得您想要的结果。将其发布到您的 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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-19
      相关资源
      最近更新 更多