*Swift5, Xcode ver 12.1
SwiftでグラデーションのButton、TextやViewの作り方を書きました。iPhone12 Pro Maxでグラデーションをかけたら途中で切れる時の対策も書いてます。
グラデーションを適用する
let background1 = UIColor.blue
let background2 = UIColor.yellow
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.colors = [background1.withAlphaComponent(1.0).cgColor,
background2.withAlphaComponent(1.0).cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
基本的にこのコードを使ってViewとかButtonとかtextをグラデーションにするのが良さそう。それではさっそく!!
グラデーションのボタンを作る
グラデーションのボタンをさっそく作ってみましょう!下記のコードを書いてみます。
カラーコードで色を指定しているのでこのままのコードを使う場合は下の記事より『カラーコードで色を指定する』に進んでswiftファイルを作ってください。
そんなことめんどくせぇって方はコードを書き換えてください(>人<)
import UIKit
class GradientViewController: UIViewController {
@IBOutlet weak var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
//書き換え用
// background1 = UIColor.blue
// background2 = UIColor.yellow
let buttonTextColor = UIColor(hex: "7B61F8", alpha: 1.0)
let background1 = UIColor(hex: "00FECA", alpha: 1.0)
let background2 = UIColor(hex: "FDF200", alpha: 1.0)
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.cornerRadius = 13
gradientLayer.frame.size = button.frame.size
gradientLayer.colors = [background1.withAlphaComponent(1.0).cgColor,
background2.withAlphaComponent(1.0).cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
button.layer.addSublayer(gradientLayer)
button.titleLabel?.font = UIFont(name: "HelveticaNeue-Bold", size: 25)
button.setTitle("Button", for: .normal)
button.setTitleColor(buttonTextColor, for: .normal)
}
}
もし、下の画像のようにグラデーションにくすんだ?黒が入った?グラデーションの時はこんなコードになっていませんか?

gradientLayer.colors = [background1,background2.cgColor]
もしも上記のコードや上記のコードじゃなくても黒くなる場合は下記のコードを試してみてください。
gradientLayer.colors = [background1.withAlphaComponent(1.0).cgColor,
background2.withAlphaComponent(1.0).cgColor]
すると、下の画像のように目的の色のグラデーションが出来るはずです

画像にグラデーションを被せる
ビーチの画像の上から黒のグラデーションを被せてLabelを読みやすくしてみました。今はわかりませんがAirbnbとかTinderがこんな感じの見せ方をしていた時がありましたね。また、textViewで紹介文も数行入れたい場合は黒のグラデーションの領域を広げてやれば出来るはずです。
左:グラデーション無し、右:グラデーション有り
やり方はボタンのグラデーションの時と同じ感じで下のコードでも出来るのですが、iphone12 Pro MaxでBuildすると下の画像のように右側が途中で切れてしまいます。
printでグラデーションのviewとimageViewの縦横のサイズを比べても同じ数値だったのでかなり???でした。
let gradientLayer1 = CAGradientLayer()
let imageGradient1 = UIColor(hex: "333333", alpha: 1.0)
let imageGradient2 = UIColor(hex: "333333", alpha: 1.0)
imageView.image = UIImage(named: "maarten-van-den-heuvel-Siuwr3uCir0-unsplash.jpg")
gradientLayer1.colors = [imageGradient1.withAlphaComponent(0.0).cgColor,
imageGradient2.withAlphaComponent(1.0).cgColor]
gradientLayer1.startPoint = CGPoint(x: 0.0, y: 0.6)
gradientLayer1.endPoint = CGPoint(x: 0.0, y: 1.0)
imageView.layer.addSublayer(gradientLayer1)
gradientLayer1.frame = imageView.frame
label.text = "Beach"
左: iPhone12 Pro Max 右: iPhone11
今回はAuto Layoutを使ってimageViewの上と左右をConstraintsで0にして、アスペクトレシオを3:4にし、画像を配置しました。調べるとどうもAuto Layoutの問題で、本来ならAuto Layoutで設定したら機種ごとによってサイズが自動変更されるはずがCALayerはそのままみたいなのでこんなことが起きるみたいです。これを回避するのに3つの方法があるみたいです。そのうちの一つを試します。イメージはグラデーションを一度呼び出して、もう一度呼び出す感じなのかな?
*理解が間違ってたらごめんなさい!
まずはこのコード
let gradientLayer1: CAGradientLayer = {
let gradientLayer1 = CAGradientLayer()
return gradientLayer1
}()
そしてこのコードを追加
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
gradientLayer1.frame = imageView.frame
}
全体
import UIKit
class GradientViewController: UIViewController {
let gradientLayer1: CAGradientLayer = {
let gradientLayer1 = CAGradientLayer()
return gradientLayer1
}()
@IBOutlet weak var label: UILabel!
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
let imageGradient1 = UIColor(hex: "333333", alpha: 1.0)
let imageGradient2 = UIColor(hex: "333333", alpha: 1.0)
imageView.image = UIImage(named: "maarten-van-den-heuvel-Siuwr3uCir0-unsplash.jpg")
// Apply Gradient Color
gradientLayer1.colors = [imageGradient1.withAlphaComponent(0.0).cgColor,
imageGradient2.withAlphaComponent(1.0).cgColor]
gradientLayer1.startPoint = CGPoint(x: 0.0, y: 0.6)
gradientLayer1.endPoint = CGPoint(x: 0.0, y: 1.0)
imageView.layer.addSublayer(gradientLayer1)
gradientLayer1.frame = imageView.frame
label.text = "Beach"
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
gradientLayer1.frame = imageView.frame
}
}
すると、iPhone12 Pro Maxでもめでたく隅まで表示されました( ´∀`)Yeah

参考にしたサイトはこちら
グラデーションのテキストを作る
基本的にはやることはグラデーションボタンの時と同じです。違いはグラデーションのviewの上にLabelを配置してmaskをする
import UIKit
class GradientViewController: UIViewController {
@IBOutlet weak var labelView: UIView!
@IBOutlet weak var gradientLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
gradientLabel.text = "foo bar baz"
let background3 = UIColor(hex: "FF85EA", alpha: 1.0)
let background4 = UIColor(hex: "7B61F8", alpha: 1.0)
let gradientLayer3:CAGradientLayer = CAGradientLayer()
gradientLayer3.frame = labelView.bounds
gradientLayer3.colors = [background3.withAlphaComponent(1.0).cgColor,
background4.withAlphaComponent(1.0).cgColor]
gradientLayer3.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer3.endPoint = CGPoint(x: 1.0, y: 0.0)
labelView.layer.addSublayer(gradientLayer3)
labelView.mask = gradientLabel
}
}
完成形

コード全体
import UIKit
class GradientViewController: UIViewController {
let gradientLayer1: CAGradientLayer = {
let gradientLayer1 = CAGradientLayer()
return gradientLayer1
}()
@IBOutlet weak var label: UILabel!
@IBOutlet weak var button: UIButton!
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var labelView: UIView!
@IBOutlet weak var gradientLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
/// Image
let imageGradient1 = UIColor(hex: "333333", alpha: 1.0)
let imageGradient2 = UIColor(hex: "333333", alpha: 1.0)
imageView.image = UIImage(named: "Beach")
gradientLayer1.colors = [imageGradient1.withAlphaComponent(0.0).cgColor,
imageGradient2.withAlphaComponent(1.0).cgColor]
gradientLayer1.startPoint = CGPoint(x: 0.0, y: 0.6)
gradientLayer1.endPoint = CGPoint(x: 0.0, y: 1.0)
imageView.layer.addSublayer(gradientLayer1)
gradientLayer1.frame = imageView.frame
label.text = "Beach"
///Button
let buttonTextColor = UIColor(hex: "7B61F8", alpha: 1.0)
let background1 = UIColor(hex: "00FECA", alpha: 1.0)
let background2 = UIColor(hex: "FDF200", alpha: 1.0)
// Apply Gradient Color
let gradientLayer:CAGradientLayer = CAGradientLayer()
gradientLayer.cornerRadius = 13
gradientLayer.frame.size = button.frame.size
gradientLayer.colors = [background1.withAlphaComponent(1.0).cgColor,
background2.withAlphaComponent(1.0).cgColor]
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
button.layer.addSublayer(gradientLayer)
button.titleLabel?.font = UIFont(name: "HelveticaNeue-Bold", size: 25)
button.setTitle("Button", for: .normal)
button.setTitleColor(buttonTextColor, for: .normal)
///Label
gradientLabel.text = "foo bar baz"
let background3 = UIColor(hex: "FF85EA", alpha: 1.0)
let background4 = UIColor(hex: "7B61F8", alpha: 1.0)
let gradientLayer3:CAGradientLayer = CAGradientLayer()
gradientLayer3.frame = labelView.bounds
gradientLayer3.colors = [background3.withAlphaComponent(1.0).cgColor,
background4.withAlphaComponent(1.0).cgColor]
gradientLayer3.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientLayer3.endPoint = CGPoint(x: 1.0, y: 0.0)
labelView.layer.addSublayer(gradientLayer3)
labelView.mask = gradientLabel
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
gradientLayer1.frame = imageView.frame
}
}
どうやってアプリを作っていくのかがとても分かりやすいので初めてアプリを作る方はこちらの書籍ががおすすめです!
もし参考になったらボタンひとつ”いいね”をお願いします!!😉
コメント