繁体   English   中英

Swift:表格视图单元格上的渐变

[英]Swift: gradient on a cell of a tableview

在 tableView 的单元格上,我尝试使用以下 Swift 代码定义渐变:

func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

    var cell:UITableViewCell = self.tableView?.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
    cell.backgroundColor=UIColor.clearColor()
    let gradient : CAGradientLayer = CAGradientLayer()
    var arrayColors:Array<AnyObject> = [UIColor.blackColor().CGColor, UIColor.whiteColor().CGColor]
    gradient.colors=arrayColors
    gradient.frame = cell.bounds
    cell.layer.insertSublayer(gradient, atIndex: UInt32(indexPath.row))

    return cell
 }

行为非常混乱:第一次加载视图时,所有单元格都有白色背景。 如果我上下滚动,一些内容的单元格会消失(标题和副标题),渐变最终出现在这些单元格中(随机地,其他一些单元格保持白色背景)。 是否与此演员表 -> UInt32(indexPath.row) 有关?

渐变是一种视觉装饰。 它特定于细胞类。 细胞的外观是细胞的责任。 它应该在单元类中定义。 它绝对不属于 cellForRowAtIndexPath,它应该只是为正确的行选择正确的单元格。 但是您正在以该方法配置单元的内部结构,这与排队的工作方式相结合,会导致所有问题。

1)创建 UITableViewCell 的子类(以编程方式,IB ..它并不重要)

2) 将awakeFromNib 或layoutSubviews 中的图层添加到backroundView 属性中。

3) 在 tableViewController 的 viewDidLoad 中注册单元格。

我有一个类似的问题,我的错误是直接在单元格中插入带有渐变的新图层,尝试将新图层插入到 backgroundView 中,像这样

let gradient = CAGradientLayer()
// layer setup...
cell.backgroundView = UIView()
cell.backgroundView?.layer.insertSublayer(gradientLayer, atIndex: 0)

希望这可以帮助。

进一步扩展伯爵格雷和希德拉答案,

当您向特定视图添加渐变时,您需要为渐变图层设置实际框架。

如果您在视图上添加了最初加载的渐变图层的视图确实加载了,那么您必须将其放入,然后它不会按预期调整大小,您可以通过两种方式解决此问题。

第一:通过计算视图的大小手动给出框架,但这是非常忙碌的,因为你必须为每个 iPhone 变化计算你可以计算宽度和高度比。

 let bounds = UIScreen.main.bounds
 let deviceheight = bounds.size.height
 let deviceWidth = bounds.size.width

然后你计算并给出宽度大小

另一种方法可以通过在加载视图后添加图层而不进行计算来完成,这可以通过以下方式完成:

 override func viewDidAppear(_ animated: Bool) {
    Your gradient code //you can create a method for adding a gradient layer 
}

现在在 Tableview 或集合视图中存在同样的问题,我们没有任何视图确实出现在单元格中的方法。 我们有两种情况。

  1. 数据是静态的。
  2. 数据来自服务器

当数据是静态的时,第一个场景你都必须这样做,因为创建一个布尔类型的变量并使其为假,直到加载视图。 然后使它在视图中确实出现了索引方法中的行方法并再次重新加载单元格。

class VC: UIViewController {


var isCellLoaded : Bool = false

override func viewDidAppear(_ animated: Bool) {

    isCellLoaded = true
    self.aTable.reloadData()
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



    let cell = tableView.dequeueReusableCell(withIdentifier: "youcellidentifier", for: indexPath) as! youcell 
    if isCellLoaded {
        cell.gradientView.setGradient(cornerRadius: 5, gradientLeftColor: .notificationViewLeftColor, gradientRightColor: .notificationViewRightColor)
        if let gradient = cell.gradientView.layer.sublayers?[0] as? CAGradientLayer {
            gradient.frame = cell.gradientView.bounds
        }
    }

    return cell
}

当数据来自 API 时,进入第二种场景

欢呼!! 你不需要做任何事情,因为第一次没有数据,直到 api 没有给出任何响应,当响应到来时,你必须重新加载数据。 事情会很顺利。 块引用

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM