2016-12-26 48 views
2

我使用了很多的梯度繪圖使用此功能:layoutIfNeeded功能行爲

func drawGradient(colors: [CGColor], locations: [NSNumber]) { 
    let gradientLayer = CAGradientLayer() 
    gradientLayer.frame.size = self.frame.size 
    gradientLayer.frame.origin = CGPoint(x: 0.0,y: 0.0) 
    gradientLayer.colors = colors 
    gradientLayer.locations = locations 
    print(self.frame.size) 
    self.layer.insertSublayer(gradientLayer, at: 0) 
} 

的問題是,如果我沒有在UIViewControllerviewDidLoad()self.view.layoutIfNeeded()我的梯度不包括在iPhone整個屏幕X +。但是,如果我撥打self.view.layoutIfNeeded(),它會讓我的應用在iOS 9.x上崩潰,並在iPhone 5/5s上出現怪異現象。我真的不知道任何解決方法,並需要幫助瞭解它是如何工作的。

+0

當你調用'drawGradient',你必須確保觀點有正確的幀。 –

+0

是的,我得到的,但我需要調用這裏面單元格的設置等,我不得不強制我的看法佈局,但它使我的應用程序崩潰在iOS 9.x – JuicyFruit

+0

你在哪裏調用'drawGradient'? – vacawama

回答

2

您在viewDidLoad打電話給drawGradient。這太早了。您需要等到自動佈局確定了框架的大小。 將viewDidLoad中的呼叫轉移到viewDidLayoutSubviews的覆蓋。要小心,因爲viewDidLayoutSubviews被稱爲不止一次,因此請確保您只呼叫drawGradient一次。您可以將屬性添加到您的viewController,名爲var appliedGradient = false,然後在應用漸變並將其翻轉到true之前檢查它。

對於UITableViewCellUICollectionViewCell您的自定義子類,覆蓋layoutSubviewssuper.layoutSubviews()後打電話drawGradient。再次確保您只調用一次。


注:如果frame可以調整(由於手機的旋轉)或不同的小區大小,你應該保持以前的梯度層的跟蹤和替換它用新的viewDidLayoutSubviews您的viewController並在layoutSubviews爲您的單元格。

在這裏,我修改了您的drawGradient以創建一個名爲applyGradient的全局函數,該函數爲視圖添加了漸變。它取代了,如果有一個以前的梯度層:

func applyGradient(colors: [CGColor], locations: [NSNumber], to view: UIView, replacing prior: CALayer?) -> CALayer { 
    let gradientLayer = CAGradientLayer() 
    gradientLayer.frame.size = view.frame.size 
    gradientLayer.frame.origin = CGPoint(x: 0.0,y: 0.0) 
    gradientLayer.colors = colors 
    gradientLayer.locations = locations 
    print(view.frame.size) 
    if let prior = prior { 
     view.layer.replaceSublayer(prior, with: gradientLayer) 
    } else { 
     view.layer.insertSublayer(gradientLayer, at: 0) 
    } 
    return gradientLayer 
} 

而且它使用的是這樣的:

class ViewController: UIViewController { 
    // property to keep track of the gradient layer 
    var gradient: CALayer? 

    override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     gradient = applyGradient(colors: [UIColor.red.cgColor, UIColor.yellow.cgColor], 
      locations: [0.0, 1.0], to: self.view, replacing: gradient) 
    } 
}