1

I'm having a bit of trouble figuring out how to make the UIButton title transparent such that it's color is the color of the superview's gradient background.

I've seen a thread about rendering the button as an image, but it was in objective-c with the old CG API and I'm wondering if anyone can give advice on a better way to solve this problem.

Any advice would be appreciated!

This is what I have so far:

import UIKit
import Foundation

class MainViewController: UIViewController {

    let headingLabel: UILabel = {
        let label = UILabel()
        label.text = "Hello, World"
        label.font = label.font.withSize(30)
        label.textColor = .white
        label.textAlignment = .center
        label.translatesAutoresizingMaskIntoConstraints = false
        return label
    }()

    let continueButton: UIButton = {
        let button = UIButton()
        button.setTitleColor(.black, for: .normal)
        button.setTitle("Continue", for: .normal)
        button.layer.cornerRadius = 10
        button.backgroundColor = .white
        button.translatesAutoresizingMaskIntoConstraints = false
        return button
    }()

    let gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
        layer.colors = [
            UIColor(red: 96/255, green: 165/255, blue: 238/255, alpha: 1.0).cgColor,
            UIColor(red: 233/255, green: 97/255, blue: 99/255, alpha: 1.0).cgColor,
        ]
        layer.startPoint = CGPoint(x: 0.0, y: 0.0)
        layer.endPoint = CGPoint(x: 1.0, y: 1.0)
        return layer
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

    override func viewDidAppear(_ animated: Bool) {
        navigationController?.navigationBar.isHidden = true
    }

    func setupView() {
        // root view
        gradientLayer.frame = view.frame
        view.layer.addSublayer(gradientLayer)
        view.addSubview(headingLabel)
        view.addSubview(continueButton)

        // constraints
        let views: [String: UIView] = [
            "headingLabel": headingLabel,
            "continueButton": continueButton,
            "superview": view
        ]

        var constraints: [NSLayoutConstraint] = []

        let verticalHeadingLabelConstraint = NSLayoutConstraint.constraints(withVisualFormat:
            "V:|-100-[headingLabel(30)]",
            options: [],
            metrics: nil,
            views: views)
        constraints += verticalHeadingLabelConstraint

        let horizontalHeadingLabelConstraint = NSLayoutConstraint.constraints(withVisualFormat:
            "H:|-[headingLabel]-|",
            options: .alignAllCenterX,
            metrics: nil,
            views: views)
        constraints += horizontalHeadingLabelConstraint

        let verticalContinueButtonConstraint = NSLayoutConstraint.constraints(withVisualFormat:
            "V:[continueButton(50)]-100-|",
            options: [],
            metrics: nil,
            views: views)
        constraints += verticalContinueButtonConstraint

        let horizontalContinueButtonConstraint = NSLayoutConstraint.constraints(withVisualFormat:
            "H:|-100-[continueButton]-100-|",
            options: [],
            metrics: nil,
            views: views)
        constraints += horizontalContinueButtonConstraint

        view.addConstraints(constraints)
    }

}

current look

Charles Kenney
  • 360
  • 3
  • 12

2 Answers2

0

If you want to do this is better that you think about a mask.
To do that you must write the text into a bitmap context and use it as a mask on a solid color.
If found something that can help you here.
In few steps:

  • You create an image context
  • You set white color text to be used as as a mask
  • You draw the text inside the context
  • You create the mask
  • You create another image based on the solid color
  • You clip them
Andrea
  • 26,120
  • 10
  • 85
  • 131
-2

If you are using the storyboard builder. There is a colored box next to text color. Press that and there is a slider called opacity.

enter image description here

Nusonic
  • 17
  • 5
  • Thanks for the initiative, but it should be easy to tell from my use of VFL constraints and lack of `@IBDesignable` that I am not using storyboard. Opacity would only make the `UIButton` layer more prevalent, which is not the goal of this question. – Charles Kenney Sep 10 '17 at 06:58
  • 1
    Ow my mistake I didn't read you code just the description. Make a custom UIColor of transparent and use it with your setTitleColour. let transparent = UIColor(red: 0, green: 0, blue: 0, alpha: 0.0) – Nusonic Sep 10 '17 at 07:21
  • Don’t you think if it were that easy I would’ve done it? Adding an alpha channel produces the same effect, because they are the same thing. I’m trying to expose the superviews layer not the UIButton... – Charles Kenney Sep 10 '17 at 13:39