在 UIImageView 上添加渐变
Add a gradient on UIImageView
我想在我的 UIImageView
上添加一个子层,但它不起作用。
- 我有一组从
photo0
到 photo9
命名的 10 张图像,我显示
它的定时器为 5 秒。
- 风口
shanghaiImage
是我的后台
我想在这个 marty 的顶部添加渐变,例如:透明(顶部)到黑色(底部)。
感谢您的帮助:)
这是我在 Swift 3.
中的代码
这部分很好:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var shanghaiImage: UIImageView!
// beginning index
var _curentImageIndex:Int = 0
// number of images
let NUMBER_OF_IMAGES:Int = 10
// creation of the Timer
var _uiTimer:Timer?
override func viewDidLoad() {
super.viewDidLoad()
showPhoto(atIndex: _curentImageIndex)
}
// MARK TIMER ---------
func selectNewTimer(){
if let existingTimer:Timer = _uiTimer{
existingTimer.invalidate()
}
_uiTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(ViewController.showNextImage), userInfo: nil, repeats: true)
}
问题就出在这里。我不知道为什么它不起作用。
// MARK PHOTO ---------
func showPhoto(atIndex index:Int){
let photoName:String = "photo\(index)"
shanghaiImage.image = UIImage(named: photoName)
let gradient = CAGradientLayer()
gradient.frame = shanghaiImage.bounds
let startColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 1)
let endColor = UIColor.black
gradient.colors = [startColor, endColor]
shanghaiImage.layer.insertSublayer(gradient, at: 0)
_curentImageIndex = index
selectNewTimer()
}
func showNextImage() {
var nextPhotoIndex:Int = _curentImageIndex + 1
if nextPhotoIndex >= NUMBER_OF_IMAGES {
nextPhotoIndex = 0
}
showPhoto(atIndex: nextPhotoIndex)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我建议在 UIImageView
:
之上放置一个带有渐变的 UIView
@IBOutlet weak var shanghaiImage: UIImageView!
let view = UIView(frame: profileImageView.frame)
let gradient = CAGradientLayer()
gradient.frame = view.frame
gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradient.locations = [0.0, 1.0]
view.layer.insertSublayer(gradient, at: 0)
shanghaiImage.addSubview(view)
shanghaiImage.bringSubview(toFront: view)
Objective-C:
UIView *view = [[UIView alloc] initWithFrame: profileImageView.frame];
CAGradientLayer *gradient = [[CAGradientLayer alloc] init];
gradient.frame = view.frame;
gradient.colors = @[ (id)[[UIColor clearColor] CGColor], (id)[[UIColor blackColor] CGColor] ];
gradient.locations = @[@0.0, @1.0];
[view.layer insertSublayer: gradient atIndex: 0];
[shanghaiImage addSubview: view];
[shanghaiImage bringSubviewToFront: view];
您可以为 swift 3、swift 4 和 swift 5 使用 扩展名
为您的 UIImageView 扩展创建一个新文件 UIImageView_extension.swift 并设置到此代码中:
UIImageView 是对 UIView 的扩展,因此如果您将 UIImageView 更改为 UIView,那么它会变得更加动态,即可以由扩展 UIView 的所有组件使用。所以我使用了 UIView 而不是 UIImageView。
import UIKit
extension UIView{
// For insert layer in Foreground
func addBlackGradientLayerInForeground(frame: CGRect, colors:[UIColor]){
let gradient = CAGradientLayer()
gradient.frame = frame
gradient.colors = colors.map{[=10=].cgColor}
self.layer.addSublayer(gradient)
}
// For insert layer in background
func addBlackGradientLayerInBackground(frame: CGRect, colors:[UIColor]){
let gradient = CAGradientLayer()
gradient.frame = frame
gradient.colors = colors.map{[=10=].cgColor}
self.layer.insertSublayer(gradient, at: 0)
}
}
并且在您的 ViewController.swift 中您可以使用它:
class myViewController: UIViewController{
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.addBlackGradientLayerInBackground(frame: view.bounds, colors:[.clear, .black])
//Alternative
//imageView.addBlackGradientLayerInBackground(frame: imageView.frame, colors: [.clear, .black])
}
}
这个函数需要一个frame,所以你只需要一个frame from view或者你自己的imageView。始终像通用函数一样思考,然后您以后可以在其他视图中轻松更改渐变颜色。
在Swift 5.1中,我创建了一个自定义的class,它继承自UIImageView并支持多种渐变配置。
import UIKit
import SnapKit
class GradientImageView: UIImageView {
//MARK: - View model
enum GradientDirection {
case upDown
case downUp
case leftRight
case rightLeft
case topLeftBottomRight
case topRightBottomLeft
case bottomLeftTopRight
case bottomRightTopLeft
}
//MARK: - Properties
var colors: [UIColor] = [] {
didSet {
updateGradient()
}
}
private var cgColors: [CGColor] {
return colors.map({ [=10=].cgColor })
}
var gradientDirection: GradientDirection = .downUp {
didSet {
updateGradient()
}
}
private lazy var gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.shouldRasterize = true
return layer
}()
//MARK: UI
private lazy var overlayView: UIView = { return UIView() }()
//MARK: - Constructor
init(colors: [UIColor], gradientDirection: GradientDirection) {
super.init(frame: .zero)
self.colors = colors
self.gradientDirection = gradientDirection
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: - Lifecycle methods methods
extension GradientImageView {
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview != nil {
setupUI()
updateGradient()
}
}
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = overlayView.frame
}
}
//MARK: - Private methods
private extension GradientImageView {
func setupUI() {
addSubview(overlayView)
//With Snapkit
overlayView.snp.makeConstraints { (maker) in
maker.edges.equalToSuperview()
}
//Without Snapkit
//overlayView.translatesAutoresizingMaskIntoConstraints = false
//overlayView.topAnchor.constraint(equalTo: overlayView.superview!.topAnchor).isActive = true
//overlayView.leftAnchor.constraint(equalTo: overlayView.superview!.leftAnchor).isActive = true
//overlayView.bottomAnchor.constraint(equalTo: overlayView.superview!.bottomAnchor).isActive = true
//overlayView.rightAnchor.constraint(equalTo: overlayView.superview!.rightAnchor).isActive = true
overlayView.layer.addSublayer(gradientLayer)
}
func updateGradient() {
gradientLayer.colors = cgColors
switch gradientDirection {
case .upDown:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
case .downUp:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
case .leftRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
case .rightLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0, y: 0.5)
case .topLeftBottomRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
case .topRightBottomLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 0)
gradientLayer.endPoint = CGPoint(x: 0, y: 1)
case .bottomLeftTopRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 1)
gradientLayer.endPoint = CGPoint(x: 1, y: 0)
case .bottomRightTopLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 1)
gradientLayer.endPoint = CGPoint(x: 0, y: 0)
}
}
}
用法
let gradientImageView = GradientImageView(colors: [YOUR COLORS], gradientDirection: .upDown)
gradientImageView.image = //YOUR Image
extension UIView {
func addGradient(frame: CGRect) {
let gradientView = UIView(frame: self.frame)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = frame
gradientLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientView.layer.insertSublayer(gradientLayer, at: 0)
addSubview(gradientView)
}
}
如何使用
let headerView = UIImageView(frame: viewFrame)
// Setup frame
let gradientViewFrame = yourGradientFrame;
headerView.addGradient(frame: gradientViewFrame)
这些解决方案对我来说效果不佳。这个答案的灵感来自 this。
我有 IBOutlet,就像,
@IBOutlet weak var imageView: UIImageView!
然后我加了这段代码
let gradient = CAGradientLayer()
gradient.frame = imageView.bounds
gradient.contents = imageView.image?.cgImage
gradient.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 1)
imageView.layer.addSublayer(gradient)
如我所愿。最重要的一点是给渐变图层添加内容
这应该是正确答案
扩展 UIImageView {
func makeGradient() {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.contents = self.image?.cgImage
gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradient.startPoint = CGPoint(x: 0.5, y: 0.5)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradient)
}
}
我想在我的 UIImageView
上添加一个子层,但它不起作用。
- 我有一组从
photo0
到photo9
命名的 10 张图像,我显示 它的定时器为 5 秒。 - 风口
shanghaiImage
是我的后台
我想在这个 marty 的顶部添加渐变,例如:透明(顶部)到黑色(底部)。
感谢您的帮助:)
这是我在 Swift 3.
中的代码这部分很好:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var shanghaiImage: UIImageView!
// beginning index
var _curentImageIndex:Int = 0
// number of images
let NUMBER_OF_IMAGES:Int = 10
// creation of the Timer
var _uiTimer:Timer?
override func viewDidLoad() {
super.viewDidLoad()
showPhoto(atIndex: _curentImageIndex)
}
// MARK TIMER ---------
func selectNewTimer(){
if let existingTimer:Timer = _uiTimer{
existingTimer.invalidate()
}
_uiTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(ViewController.showNextImage), userInfo: nil, repeats: true)
}
问题就出在这里。我不知道为什么它不起作用。
// MARK PHOTO ---------
func showPhoto(atIndex index:Int){
let photoName:String = "photo\(index)"
shanghaiImage.image = UIImage(named: photoName)
let gradient = CAGradientLayer()
gradient.frame = shanghaiImage.bounds
let startColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 1)
let endColor = UIColor.black
gradient.colors = [startColor, endColor]
shanghaiImage.layer.insertSublayer(gradient, at: 0)
_curentImageIndex = index
selectNewTimer()
}
func showNextImage() {
var nextPhotoIndex:Int = _curentImageIndex + 1
if nextPhotoIndex >= NUMBER_OF_IMAGES {
nextPhotoIndex = 0
}
showPhoto(atIndex: nextPhotoIndex)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我建议在 UIImageView
:
UIView
@IBOutlet weak var shanghaiImage: UIImageView!
let view = UIView(frame: profileImageView.frame)
let gradient = CAGradientLayer()
gradient.frame = view.frame
gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradient.locations = [0.0, 1.0]
view.layer.insertSublayer(gradient, at: 0)
shanghaiImage.addSubview(view)
shanghaiImage.bringSubview(toFront: view)
Objective-C:
UIView *view = [[UIView alloc] initWithFrame: profileImageView.frame];
CAGradientLayer *gradient = [[CAGradientLayer alloc] init];
gradient.frame = view.frame;
gradient.colors = @[ (id)[[UIColor clearColor] CGColor], (id)[[UIColor blackColor] CGColor] ];
gradient.locations = @[@0.0, @1.0];
[view.layer insertSublayer: gradient atIndex: 0];
[shanghaiImage addSubview: view];
[shanghaiImage bringSubviewToFront: view];
您可以为 swift 3、swift 4 和 swift 5 使用 扩展名
为您的 UIImageView 扩展创建一个新文件 UIImageView_extension.swift 并设置到此代码中:
UIImageView 是对 UIView 的扩展,因此如果您将 UIImageView 更改为 UIView,那么它会变得更加动态,即可以由扩展 UIView 的所有组件使用。所以我使用了 UIView 而不是 UIImageView。
import UIKit
extension UIView{
// For insert layer in Foreground
func addBlackGradientLayerInForeground(frame: CGRect, colors:[UIColor]){
let gradient = CAGradientLayer()
gradient.frame = frame
gradient.colors = colors.map{[=10=].cgColor}
self.layer.addSublayer(gradient)
}
// For insert layer in background
func addBlackGradientLayerInBackground(frame: CGRect, colors:[UIColor]){
let gradient = CAGradientLayer()
gradient.frame = frame
gradient.colors = colors.map{[=10=].cgColor}
self.layer.insertSublayer(gradient, at: 0)
}
}
并且在您的 ViewController.swift 中您可以使用它:
class myViewController: UIViewController{
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
imageView.addBlackGradientLayerInBackground(frame: view.bounds, colors:[.clear, .black])
//Alternative
//imageView.addBlackGradientLayerInBackground(frame: imageView.frame, colors: [.clear, .black])
}
}
这个函数需要一个frame,所以你只需要一个frame from view或者你自己的imageView。始终像通用函数一样思考,然后您以后可以在其他视图中轻松更改渐变颜色。
在Swift 5.1中,我创建了一个自定义的class,它继承自UIImageView并支持多种渐变配置。
import UIKit
import SnapKit
class GradientImageView: UIImageView {
//MARK: - View model
enum GradientDirection {
case upDown
case downUp
case leftRight
case rightLeft
case topLeftBottomRight
case topRightBottomLeft
case bottomLeftTopRight
case bottomRightTopLeft
}
//MARK: - Properties
var colors: [UIColor] = [] {
didSet {
updateGradient()
}
}
private var cgColors: [CGColor] {
return colors.map({ [=10=].cgColor })
}
var gradientDirection: GradientDirection = .downUp {
didSet {
updateGradient()
}
}
private lazy var gradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.shouldRasterize = true
return layer
}()
//MARK: UI
private lazy var overlayView: UIView = { return UIView() }()
//MARK: - Constructor
init(colors: [UIColor], gradientDirection: GradientDirection) {
super.init(frame: .zero)
self.colors = colors
self.gradientDirection = gradientDirection
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//MARK: - Lifecycle methods methods
extension GradientImageView {
override func didMoveToSuperview() {
super.didMoveToSuperview()
if superview != nil {
setupUI()
updateGradient()
}
}
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = overlayView.frame
}
}
//MARK: - Private methods
private extension GradientImageView {
func setupUI() {
addSubview(overlayView)
//With Snapkit
overlayView.snp.makeConstraints { (maker) in
maker.edges.equalToSuperview()
}
//Without Snapkit
//overlayView.translatesAutoresizingMaskIntoConstraints = false
//overlayView.topAnchor.constraint(equalTo: overlayView.superview!.topAnchor).isActive = true
//overlayView.leftAnchor.constraint(equalTo: overlayView.superview!.leftAnchor).isActive = true
//overlayView.bottomAnchor.constraint(equalTo: overlayView.superview!.bottomAnchor).isActive = true
//overlayView.rightAnchor.constraint(equalTo: overlayView.superview!.rightAnchor).isActive = true
overlayView.layer.addSublayer(gradientLayer)
}
func updateGradient() {
gradientLayer.colors = cgColors
switch gradientDirection {
case .upDown:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
case .downUp:
gradientLayer.startPoint = CGPoint(x: 0.5, y: 1)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
case .leftRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
case .rightLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 0, y: 0.5)
case .topLeftBottomRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1)
case .topRightBottomLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 0)
gradientLayer.endPoint = CGPoint(x: 0, y: 1)
case .bottomLeftTopRight:
gradientLayer.startPoint = CGPoint(x: 0, y: 1)
gradientLayer.endPoint = CGPoint(x: 1, y: 0)
case .bottomRightTopLeft:
gradientLayer.startPoint = CGPoint(x: 1, y: 1)
gradientLayer.endPoint = CGPoint(x: 0, y: 0)
}
}
}
用法
let gradientImageView = GradientImageView(colors: [YOUR COLORS], gradientDirection: .upDown)
gradientImageView.image = //YOUR Image
extension UIView {
func addGradient(frame: CGRect) {
let gradientView = UIView(frame: self.frame)
let gradientLayer = CAGradientLayer()
gradientLayer.frame = frame
gradientLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradientLayer.locations = [0.0, 1.0]
gradientView.layer.insertSublayer(gradientLayer, at: 0)
addSubview(gradientView)
}
}
如何使用
let headerView = UIImageView(frame: viewFrame)
// Setup frame
let gradientViewFrame = yourGradientFrame;
headerView.addGradient(frame: gradientViewFrame)
这些解决方案对我来说效果不佳。这个答案的灵感来自 this。 我有 IBOutlet,就像,
@IBOutlet weak var imageView: UIImageView!
然后我加了这段代码
let gradient = CAGradientLayer()
gradient.frame = imageView.bounds
gradient.contents = imageView.image?.cgImage
gradient.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 1)
imageView.layer.addSublayer(gradient)
如我所愿。最重要的一点是给渐变图层添加内容
这应该是正确答案
扩展 UIImageView {
func makeGradient() {
let gradient = CAGradientLayer()
gradient.frame = self.bounds
gradient.contents = self.image?.cgImage
gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
gradient.startPoint = CGPoint(x: 0.5, y: 0.5)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
self.layer.addSublayer(gradient)
}
}