2016-06-19 26 views
9

Tôi không biết làm thế nào để thiết lập gradient nền trên một nút (mà không làm cho nền gradient một hình ảnh). Điều này rất khác với Android.Đặt Background Gradient trên nút trong Swift

Dưới đây là một lớp học tôi phải xác định một kế hoạch dốc trả lại:

import UIKit 

extension CAGradientLayer { 

    func backgroundGradientColor() -> CAGradientLayer { 
     let topColor = UIColor(red: (0/255.0), green: (153/255.0), blue:(51/255.0), alpha: 1) 
     let bottomColor = UIColor(red: (0/255.0), green: (153/255.0), blue:(255/255.0), alpha: 1) 

     let gradientColors: [CGColor] = [topColor.CGColor, bottomColor.CGColor] 
     let gradientLocations: [Float] = [0.0, 1.0] 

     let gradientLayer: CAGradientLayer = CAGradientLayer() 
     gradientLayer.colors = gradientColors 
     gradientLayer.locations = gradientLocations 

     return gradientLayer 

    } 
} 

Tôi có thể sử dụng để thiết lập nền tảng của toàn bộ quan điểm của tôi như sau:

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let background = CAGradientLayer().backgroundGradientColor() 
     background.frame = self.view.bounds 
     self.view.layer.insertSublayer(background, atIndex: 0) 
    } 
    //... 
} 

Nhưng làm thế nào tôi có thể truy cập vào giao diện của nút và chèn lớp con hoặc thứ gì đó tương tự? Tôi đã Googled trong một vài giờ và không thể tìm thấy bất cứ điều gì hữu ích. Tôi khá mất mát với điều này.

Trả lời

24

Mã của bạn hoạt động tốt. Bạn chỉ cần nhớ để thiết lập khung của gradient mỗi lần. Tốt hơn là chỉ cần tạo danh mục gradient cũng đặt khung của chế độ xem cho bạn.

Bằng cách đó bạn không quên và nó được áp dụng tốt.

extension UIView { 
    func applyGradient(colours: [UIColor]) -> Void { 
     self.applyGradient(colours, locations: nil) 
    } 

    func applyGradient(colours: [UIColor], locations: [NSNumber]?) -> Void { 
     let gradient: CAGradientLayer = CAGradientLayer() 
     gradient.frame = self.bounds 
     gradient.colors = colours.map { $0.CGColor } 
     gradient.locations = locations 
     self.layer.insertSublayer(gradient, atIndex: 0) 
    } 
} 

class ViewController: UIViewController { 

    @IBOutlet weak var btn: UIButton! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     self.btn.titleLabel?.textColor = UIColor.whiteColor() 

     self.btn.applyGradient([UIColor.yellowColor(), UIColor.blueColor()]) 
     self.view.applyGradient([UIColor.yellowColor(), UIColor.blueColor(), UIColor.redColor()], locations: [0.0, 0.5, 1.0]) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
    } 
} 

Nút là chế độ xem. Bạn áp dụng gradient cho nó giống như cách bạn áp dụng nó cho bất kỳ chế độ xem nào khác.

+3

Tôi không đồng ý với câu cuối cùng. Trong khi các nút là chế độ xem, nền của nút không giống với chế độ xem. Nền nút có thể thay đổi tùy thuộc vào trạng thái nút. Khi thêm gradient dưới dạng lớp, chúng tôi sẽ mất hiệu ứng đó. Giải pháp lý tưởng là chụp lớp gradient thành một hình ảnh để đặt hình ảnh làm hình nền của nút. Một vấn đề khác là lớp giới hạn phải luôn được cập nhật khi khung nút thay đổi, nghĩa là từ 'layoutSubviews'. – Sulthan

8

đây bên dưới, bạn có thể tìm ra giải pháp cho Swift3 và một chút mở rộng (định hướng helper):

typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint) 

enum GradientOrientation { 
    case topRightBottomLeft 
    case topLeftBottomRight 
    case horizontal 
    case vertical 

    var startPoint : CGPoint { 
    return points.startPoint 
    } 

    var endPoint : CGPoint { 
    return points.endPoint 
    } 

    var points : GradientPoints { 
    get { 
     switch(self) { 
     case .topRightBottomLeft: 
     return (CGPoint(x: 0.0,y: 1.0), CGPoint(x: 1.0,y: 0.0)) 
     case .topLeftBottomRight: 
     return (CGPoint(x: 0.0,y: 0.0), CGPoint(x: 1,y: 1)) 
     case .horizontal: 
     return (CGPoint(x: 0.0,y: 0.5), CGPoint(x: 1.0,y: 0.5)) 
     case .vertical: 
     return (CGPoint(x: 0.0,y: 0.0), CGPoint(x: 0.0,y: 1.0)) 
     } 
    } 
    } 
} 

extension UIView { 

    func applyGradient(withColours colours: [UIColor], locations: [NSNumber]? = nil) -> Void { 
    let gradient = CAGradientLayer() 
    gradient.frame = self.bounds 
    gradient.colors = colours.map { $0.cgColor } 
    gradient.locations = locations 
    self.layer.insertSublayer(gradient, at: 0) 
    } 

    func applyGradient(withColours colours: [UIColor], gradientOrientation orientation: GradientOrientation) -> Void { 
    let gradient = CAGradientLayer() 
    gradient.frame = self.bounds 
    gradient.colors = colours.map { $0.cgColor } 
    gradient.startPoint = orientation.startPoint 
    gradient.endPoint = orientation.endPoint 
    self.layer.insertSublayer(gradient, at: 0) 
    } 
} 
3

@Zeb câu trả lời là rất tốt nhưng chỉ để làm sạch nó lên và làm cho nó Swifty nhiều hơn một chút . Điện Toán thuộc tính read-only nên tránh sử dụng get và trở về Void là không cần thiết:

typealias GradientPoints = (startPoint: CGPoint, endPoint: CGPoint) 

enum GradientOrientation { 
    case topRightBottomLeft 
    case topLeftBottomRight 
    case horizontal 
    case vertical 

var startPoint: CGPoint { 
    return points.startPoint 
} 

var endPoint: CGPoint { 
    return points.endPoint 
} 

var points: GradientPoints { 
    switch self { 
    case .topRightBottomLeft: 
     return (CGPoint.init(x: 0.0, y: 1.0), CGPoint.init(x: 1.0, y: 0.0)) 
    case .topLeftBottomRight: 
     return (CGPoint.init(x: 0.0, y: 0.0), CGPoint.init(x: 1, y: 1)) 
    case .horizontal: 
     return (CGPoint.init(x: 0.0, y: 0.5), CGPoint.init(x: 1.0, y: 0.5)) 
    case .vertical: 
     return (CGPoint.init(x: 0.0, y: 0.0), CGPoint.init(x: 0.0, y: 1.0)) 
    } 
    } 
} 

extension UIView { 

func applyGradient(withColours colours: [UIColor], locations: [NSNumber]? = nil) { 
    let gradient: CAGradientLayer = CAGradientLayer() 
    gradient.frame = self.bounds 
    gradient.colors = colours.map { $0.cgColor } 
    gradient.locations = locations 
    self.layer.insertSublayer(gradient, at: 0) 
} 

func applyGradient(withColours colours: [UIColor], gradientOrientation orientation: GradientOrientation) { 
    let gradient: CAGradientLayer = CAGradientLayer() 
    gradient.frame = self.bounds 
    gradient.colors = colours.map { $0.cgColor } 
    gradient.startPoint = orientation.startPoint 
    gradient.endPoint = orientation.endPoint 
    self.layer.insertSublayer(gradient, at: 0) 
    } 
} 
+0

Điều này hoạt động tốt, tôi đã cố gắng để thiết lập UIButton angleRadius, nhưng nó không dùng bất kỳ tác dụng trừ khi tôi loại bỏ gradient, là có một cách để giải quyết này? – SimpiMind

+0

Bạn đã thử đặt masksToBounds = false – brl214

1

Tôi đã thử tất cả trong số họ đây là nút init của tôi bên trong viewDidLoad

let button = UIButton() 
    button.setTitle("Alper", for: .normal) 
    button.layer.borderColor = UIColor.white.cgColor 
    button.layer.borderWidth = 1 
    view.addSubview(button) 
    button.anchor(top: nil, left: nil, bottom: logo.topAnchor, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, height: 50, width: 100) 
    let gradientx = CAGradientLayer() 
    gradientx.colors = [UIColor.blue,UIColor.red] 
    gradientx.startPoint = CGPoint(x: 0.0, y: 0.5) 
    gradientx.endPoint = CGPoint(x: 1.0, y: 1.0) 
    gradientx.frame = button.bounds 
    button.layer.insertSublayer(gradientx, at: 0) 

neo là một phần mở rộng, vì vậy đây là gradient không liên quan.

Các vấn đề liên quan