【问题标题】:Place gradient color inside UIView in tableViewCell在uitableViewCell中的UIView内放置渐变颜色
【发布时间】:2020-10-29 07:10:41
【问题描述】:

我在堆栈视图中添加了两个视图。我的 tableViewCell 中有那个堆栈视图。现在我的 stackView 被放置在内容视图的中心,具有宽度和高度。我想在我的 stackView 内的视图内应用渐变颜色。

看看下面的视图 在这种情况下,我给视图设置了我不想要的红色和绿色的背景颜色。我想将四种颜色的渐变应用于此视图。 enter image description here

【问题讨论】:

    标签: swift xcode uitableview tableview gradient


    【解决方案1】:

    这是我用 Swift 编写的一个简单进度条的代码:

    import Foundation
    import Cocoa
    
    public class GradientProgressView : NSView
    {
        // MARK: - Fields
        private let bgLayer = CAShapeLayer()
        private var progressLayer = CAShapeLayer()
        private var gradientLayer = CAGradientLayer()
        private var blockLayer = CAShapeLayer()
        private var mValue: CGFloat = 0.0
        
        // MARK: - Properties
        public var colors: [NSColor] = [NSColor.systemGreen, NSColor.systemYellow, NSColor.sytemRed]
        
        public var value: CGFloat
        {
            set
            {
                self.mValue = newValue
                
                if self.mValue > 1.0
                {
                    self.mValue = 1.0
                }
                if self.mValue < 0.0 || self.mValue.isNaN || self.mValue.isInfinite
                {
                    self.mValue = 0.0
                }
                
                self.progressLayer.strokeEnd = self.mValue
            }
            get
            {
                return self.mValue
            }
        }
        
        // MARK: - Overrides
        public override func layout()
        {
            super.layout()
            
            self.initialize()
        }
        
        // MARK: - Helper
        fileprivate func initialize()
        {
            self.wantsLayer = true
            
            self.layer?.masksToBounds = true // Optional
            self.layer?.cornerRadius = self.bounds.height / 2.0 // Optional
            
            self.bgLayer.removeFromSuperlayer()
            self.bgLayer.contentsScale = NSScreen.scale
            self.bgLayer.fillColor = NSColor.separatorColor.cgColor
            self.bgLayer.path = NSBezierPath(rect: self.bounds).cgPath
            self.layer?.addSublayer(self.bgLayer)
            
            self.blockLayer.removeAllAnimations()
            self.blockLayer.removeFromSuperlayer()
            
            let path = NSBezierPath()
            path.move(to: CGPoint(x: self.bounds.height / 2.0, y: self.bounds.height / 2.0))
            path.line(to: CGPoint(x: self.bounds.width - self.bounds.height / 2.0, y: self.bounds.height / 2.0))
            
            self.progressLayer.path = path.cgPath
            self.progressLayer.strokeColor = NSColor.black.cgColor
            self.progressLayer.fillColor = nil
            self.progressLayer.lineWidth = self.bounds.height
            self.progressLayer.lineCap = .round
            self.progressLayer.strokeStart = 0.0
            self.progressLayer.strokeEnd = 0.0
            self.progressLayer.contentsScale = NSScreen.scale
            
            self.gradientLayer.removeAllAnimations()
            self.gradientLayer.removeFromSuperlayer()
            self.gradientLayer.contentsScale = NSScreen.scale
            self.gradientLayer.colors = self.colors.map({ $0.cgColor })
            self.gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
            self.gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
            self.gradientLayer.mask = self.progressLayer
            self.gradientLayer.frame = self.bounds
            self.gradientLayer.contentsScale = NSScreen.scale
            
            self.layer?.addSublayer(self.gradientLayer)
        }
    }
    

    此进度条支持多种颜色。 只需将您的进度条逻辑替换为我在上面发布的逻辑(或添加进度条下方显示的三角形的逻辑)。

    预览:

    【讨论】:

      【解决方案2】:

      在 tableViewCell(collectionViewCell) 上创建 GradientLayer

      1。在您的 tableViewCell 上创建 CAGradientLayer 实例

      class MyCell: UITableViewCell {
          let gradientLayer = CAGradientLayer()
      }
      

      2。将图层框架设置为layoutSublayers(of:) 的视图边界

      如果您将图层的框架设置在其他位置,框架会变得很奇怪。

      class MyCell: UITableViewCell {
          let gradientLayer = CAGradientLayer()
          
          // Setting it from layoutSubViews also fine.
          override func layoutSublayers(of layer: CALayer) {
              super.layoutSublayers(of: self.layer)
              gradientLayer.frame = yourView.bounds
          }
      }
      

      3。在视图上添加 GradientLayer。

      这是我用于添加渐变层的 UIView 扩展。

      extension UIView {
          func addGradient(with layer: CAGradientLayer, gradientFrame: CGRect? = nil, colorSet: [UIColor],
                           locations: [Double], startEndPoints: (CGPoint, CGPoint)? = nil) {
              layer.frame = gradientFrame ?? self.bounds
              layer.frame.origin = .zero
      
              let layerColorSet = colorSet.map { $0.cgColor }
              let layerLocations = locations.map { $0 as NSNumber }
      
              layer.colors = layerColorSet
              layer.locations = layerLocations
      
              if let startEndPoints = startEndPoints {
                  layer.startPoint = startEndPoints.0
                  layer.endPoint = startEndPoints.1
              }
      
              self.layer.insertSublayer(layer, above: self.layer)
          }
      }
      
      * 选项 1 - 从 layoutSublayers(of:) 添加
      class MyCell: UITableViewCell {
          let gradientLayer = CAGradientLayer()
          
          override func layoutSublayers(of layer: CALayer) {
              super.layoutSublayers(of: self.layer)
              gradientLayer.frame = yourView.bounds
              
              let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
                              UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
              let location = [0.2, 1.0]
              
              yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
          }
      }
      
      * 选项 2 - 从cellForRowAt 添加

      例如,如果我们有 cellForRowAt 并且像这样,

      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellId", for: indexPath) as? MyCell {
            cell.configureCell(content: someItems[indexPath.row])
        }
        return UITableViewCell()
      }
      

      现在,我们可以处理来自configureCell(content:) 的gradientLayer。

      class MyCell: UITableViewCell {
          let gradientLayer = CAGradientLayer()
          
          func configureCell(content: YourType) {
              let colorSet = [UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0),
                              UIColor(red: 0/255, green: 0/255, blue: 0/255, alpha: 1.0)]
              let location = [0.2, 1.0]
              yourView.addGradient(with: gradientLayer, colorSet: colorSet, locations: location)
          }
          
          override func layoutSublayers(of layer: CALayer) {
              super.layoutSublayers(of: self.layer)
              gradientLayer.frame = yourView.bounds
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        相关资源
        最近更新 更多