添加到 viewDidLayoutSubviews 时,按钮渐变不起作用

Posted

技术标签:

【中文标题】添加到 viewDidLayoutSubviews 时,按钮渐变不起作用【英文标题】:Button gradient not working when added to viewDidLayoutSubviews 【发布时间】:2019-05-25 11:27:50 【问题描述】:

我正在使用以下代码添加按钮渐变

extension UIView 
    func applyGradient(colors: [UIColor]) 
        self.applyGradient(colors: colors, locations: nil)
    

    func applyGradient(colors: [UIColor], locations: [NSNumber]?) 
        let gradient = CAGradientLayer()
        gradient.frame = self.bounds
        gradient.colors = colors.map  $0.cgColor 
        gradient.locations = locations
        gradient.startPoint = CGPoint(x: 0, y: 0)
        gradient.endPoint = CGPoint(x: 1, y: 0)
        self.layer.insertSublayer(gradient, at: 0)
    

viewDidLayoutSubviews() 中调用initStyle() 不起作用。

func initStyle() 
    submitBtn.applyGradient(colors: [#colorLiteral(red: 0.1176470588, green: 0.3882352941, blue: 0.5254901961, alpha: 1), #colorLiteral(red: 0.2941176471, green: 0.9098039216, blue: 0.9529411765, alpha: 1)])
    submitBtn.layer.cornerRadius = 15.0
    submitBtn.layer.masksToBounds = true

我正在以编程方式创建所有 UI 元素。我已经正确设置了约束并且正在工作。

lazy var submitBtn: UIButton = 
    let btn = UIButton(type: .system)
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.setTitle("SUBMIT", for: .normal)
    return btn
()

如何使它工作?


仅当我将 initStyle() 放置在 viewDidAppear() 而不是 viewDidLayoutSubviews() 时才会显示渐变,这会导致按钮渐变的显示延迟。我想避免这种延迟。所以我在viewDidLayoutSubviews中添加了,但是后来渐变没有出现。

【问题讨论】:

您正在传递位置 nil 并且 x,y 位置为零并检查框架 ..检查渐变代码 仅当我将initStyle() 放置在viewDidAppear() 而不是viewDidLayoutSubviews() 时才会显示渐变,这会延迟显示按钮渐变。 【参考方案1】:

我认为这里的问题是 self.bounds 在您调用渐变函数时为 0。稍后尝试调用它,例如 viewWillAppear 或调用 view.layoutSubViews 来触发 iewDidLayoutSubviews()

【讨论】:

通过打印 self.bounds 来测试一下 我手动设置了按钮框架CGRect(x: 0, y: 0, width: 100, height: 40),尽管添加了布局约束并将translatesAutoresizingMaskIntoConstraints 设置为false 使这项工作正常进行。 我不确定为什么设置约束时边界为 0。【参考方案2】:
lazy var submitBtn: UIButton = 
    let btn = UIButton(type: .custom) //Set custom instead of system
    btn.translatesAutoresizingMaskIntoConstraints = false
    btn.setTitle("SUBMIT", for: .normal)
    return btn
()

【讨论】:

【参考方案3】:

尝试使用里面的函数 viewWillAppeare()

另外,为什么不从一开始就将渐变应用到按钮中而不使用单独的函数呢?这将使按钮出现w\已经内置的渐变。

如果你想设置渐变 w\ a 条件,你可以使用以下

func displayButton(condition: Bool)


lazy var submitBtn: UIButton = 
let btn = UIButton(type: .system)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("SUBMIT", for: .normal)

if condition == true 
//set the gradient here
return btn
 else if condition == false
return btn


()



override func viewDidLoad()
super.viewDidLoad()
 //here you can set the condition to show the gradient or not depending on what you want
displayButton(true) //will show the gradient
displayButton(false) // will show without gradient


我目前无法测试此代码,所以我不确定,试一试。

【讨论】:

以上是关于添加到 viewDidLayoutSubviews 时,按钮渐变不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥 viewDidLayoutSubviews 会干扰动画?

Swift:viewDidLayoutSubviews 是啥意思?

viewDidLayoutSubviews 中的 UIImageView 宽度是 1000?

需要有关 viewDidLayoutSubviews 的帮助

谁负责在自定义 UIViewController 容器中调用 viewWillLayoutSubviews()/viewDidLayoutSubviews()?

在 viewDidLayoutSubviews() 中调用地图视图函数时,地图视图显示两次?