【问题标题】:Gradient not applying to full view on larger screen渐变不适用于大屏幕上的全视图
【发布时间】:2022-01-05 05:06:41
【问题描述】:

我实现了一个代码以将对角渐变应用于不同的视图。它适用于所有小视图和小屏幕上的所有视图,但在 iPhone 13 Pro Max 模拟器上,它不适用于全视图,并在右侧留下一些部分。我只注意到即使在其他一些更宽的视图中,这个渐变也只适用于大约 80% 的宽度。 这是它在一个视图中显示的屏幕截图:

它不适用于视图的右侧,并且右角半径是不可见的。 这是渐变的代码:

func applyGradientDiagonal(isVertical: Bool, colorArray: [UIColor]) {
        layer.sublayers?.filter({ $0 is CAGradientLayer }).forEach({ $0.removeFromSuperlayer() })

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = colorArray.map({ $0.cgColor })
        if isVertical {
            //top to bottom
            gradientLayer.locations = [0.0, 1.0]
        } else {
            //left to right
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
            gradientLayer.endPoint = CGPoint(x: 1.0, y: 1.0)
        }

        backgroundColor = .clear
        gradientLayer.frame = bounds
        layer.insertSublayer(gradientLayer, at: 0)
    }

我在viewDidLoad() 中这样称呼它:

self.viewTAGradient.applyGradientDiagonal(isVertical: false, colorArray: [UIColor.init(named: "gradient1")!, UIColor.init(named: "gradient2")!, UIColor.init(named: "gradient3")!])

我寻找了一些解决方案,甚至尝试这样称呼它,但这也没有用:

override func viewDidLayoutSubviews() {
        
        self.viewTAGradient.applyGradientDiagonal(isVertical: false, colorArray: [UIColor.init(named: "gradient1")!, UIColor.init(named: "gradient2")!, UIColor.init(named: "gradient3")!])
        
    }

编辑:新更新: 问题在于 iPhone 13 pro max 上的所有渐变。我从互联网上复制了一些用于渐变的代码,并创建了新的视图控制器,只有一个固定高度的视图粘在顶部,并且在 13 pro max 上全部移到左侧。虽然在其他设备上工作正常。这是屏幕截图:

谁能帮助我为什么在一个特定的设备上它的行为是这样的?

【问题讨论】:

  • 你对viewTAGradient的约束设置是否正确?
  • 当您在 viewDidLayoutSubviews() 中调用 applyGradientDiagonal(isVertical:colorArray:) 时,它应该可以工作。它可以在我的机器上运行。您能否展示更多代码示例,例如如何设置“viewTAGradient”?
  • @kyaw.monkey 我添加了更多细节。
  • @Sweeper 我只是在一个固定高度 = 180 的水平堆栈中调用它们。在 20 的距离处均匀填充它们应该自动创建。编辑后见上文,bgColor 已正确应用,但渐变不会
  • 检查你的布局约束......假设你的viewTAGradient是标准UIView,如果你给它一个背景颜色而不是调用applyGradientDiagonal(),它的大小是否合适?

标签: ios swift xcode uiview uikit


【解决方案1】:

没有理由让渐变在 iPhone 13 Pro Max 上表现不同,所以我的猜测(没有看到您的完整布局)可能与约束或您实际调用 applyGradientDiagonal() 的时间有关。

您可能会发现通过继承 UIView 并将渐变代码放入 layoutSubview() 中更容易获得可靠的结果。

这是一个简单的例子:

class MyGradientView: UIView {
    
    var colorArray: [UIColor] = [] {
        didSet {
            setNeedsLayout()
        }
    }
    var vertical: Bool = true {
        didSet {
            setNeedsLayout()
        }
    }
    
    static override var layerClass: AnyClass {
        return CAGradientLayer.self
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        guard let layer = layer as? CAGradientLayer else { return }
        layer.colors = colorArray.map({ $0.cgColor })
        if vertical {
            // top-down gradient
            layer.startPoint = CGPoint(x: 0.5, y: 0.0)
            layer.endPoint = CGPoint(x: 0.5, y: 1.0)
        } else {
            // diagonal gradient
            layer.startPoint = CGPoint(x: 0.0, y: 0.0)
            layer.endPoint = CGPoint(x: 1.0, y: 1.0)
        }
    }

}

和一个示例视图控制器来演示:

class GradientTestViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let stack = UIStackView()
        stack.axis = .vertical
        stack.spacing = 8
        stack.distribution = .fillEqually
        
        let colorPairs: [[UIColor]] = [
            [.blue, .cyan],
            [.red, .yellow],
            [.blue, .yellow, .red],
        ]
        
        // 3 pairs of gradient views
        colorPairs.forEach { colors in
            let hstack = UIStackView()
            hstack.spacing = 8
            hstack.distribution = .fillEqually

            var v = MyGradientView()
            v.colorArray = colors
            v.vertical = true
            hstack.addArrangedSubview(v)
            
            v = MyGradientView()
            v.colorArray = colors
            v.vertical = false
            hstack.addArrangedSubview(v)
            
            stack.addArrangedSubview(hstack)
        }
        
        // a pair of plain, solid color views for comparison
        let hstack = UIStackView()
        hstack.spacing = 8
        hstack.distribution = .fillEqually
        
        var v = UIView()
        v.backgroundColor = .systemRed
        hstack.addArrangedSubview(v)
        v = UIView()
        v.backgroundColor = .systemBlue
        hstack.addArrangedSubview(v)
        
        stack.addArrangedSubview(hstack)
        
        stack.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(stack)
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 20.0),
            stack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            stack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            stack.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
        ])
        
        // outline the stack view
        //  so we can see its frame
        let outlineView = UIView()
        outlineView.backgroundColor = .clear
        outlineView.layer.borderColor = UIColor.black.cgColor
        outlineView.layer.borderWidth = 3
        outlineView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(outlineView)
        NSLayoutConstraint.activate([
            outlineView.topAnchor.constraint(equalTo: stack.topAnchor, constant: -2.0),
            outlineView.leadingAnchor.constraint(equalTo: stack.leadingAnchor, constant: -2.0),
            outlineView.trailingAnchor.constraint(equalTo: stack.trailingAnchor, constant: 2.0),
            outlineView.bottomAnchor.constraint(equalTo: stack.bottomAnchor, constant: 2.0),
        ])
    }
    
}

运行该代码的结果:

【讨论】:

    猜你喜欢
    • 2019-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2016-12-08
    • 2016-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多