2017-06-03 128 views
0

我正在嘗試在@IBDesignable UIView上添加漸變。在模擬器中一切都很好,但是當我在物理設備上運行它時,漸變不會填滿屏幕。我有我的梯度代碼在一個UIView擴展:漸變不填充IBDesignable UIView

extension UIView { 
    func gradientFrom(_ colors: [UIColor]) { 
     let cgColors = colors.map({return $0.cgColor}) 
     let gradient = CAGradientLayer() 
     gradient.frame = self.bounds 
     gradient.locations = [0.0, 1.0] 
     gradient.colors = cgColors 
     self.layer.insertSublayer(gradient, at: 0) 
    } 
} 

接下來,我UIView我的梯度爲中心的代碼:

@IBDesignable class MyCustomView: UIView { 

    var view = UIView() 

    // MARK: - IBOutlets 
    @IBOutlet weak var label: UILabel! 
    @IBOutlet weak var textView: UITextView! 

    fileprivate var gradientColors: [UIColor] = [] 

    @IBInspectable var gradientColor0: UIColor = UIColor.flatWhite { 
     didSet { 
      gradientColors.remove(at: 0) 
      gradientColors.insert(gradientColor0, at: 0) 
     } 
    } 

    @IBInspectable var gradientColor1: UIColor = UIColor.flatWhiteDark { 
     didSet { 
      gradientColors.remove(at: 1) 
      gradientColors.insert(gradientColor1, at: 1) 
     } 
    } 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     xibSetup() 
     setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     xibSetup() 
     setup() 
    } 

    override func prepareForInterfaceBuilder() { 
     super.prepareForInterfaceBuilder() 
     setup() 
    } 

    func setup() { 
     textView.scrollRangeToVisible(NSMakeRange(0, 0)) 
     [gradientColor0, gradientColor1].forEach({gradientColors.append($0)}) 
     view.gradientFrom(gradientColors) 
     label.textColor = labelFontColor 
     label.backgroundColor = UIColor.clear 
     textView.backgroundColor = UIColor.clear 
     textView.textColor = textViewFontColor 
    } 

    // MARK: - Nib handlers 

    fileprivate func xibSetup() { 
     view = loadViewFromNib() 
     view.frame = bounds 
     view.autoresizingMask = [.flexibleWidth, .flexibleHeight] 
     addSubview(view) 
    } 

    fileprivate func loadViewFromNib() -> UIView { 
     let bundle = Bundle(for: type(of: self)) 
     let nib = UINib(nibName: "AttributionView", bundle: bundle) 
     let view = nib.instantiate(withOwner: self, options: nil).first as! UIView 
     return view 
    } 

    public func applyBackgroundGradient() {   
     view.gradientFrom(gradientColors) 
    } 

    func resizeView() { 
     textView.sizeToFit() 
     textView.scrollRangeToVisible(NSMakeRange(0, 0)) 
    } 
} 

在MyViewController,我添加了一個UIView,它的子類設置爲MyCustomView 。界面構建器填充,但是當我在物理設備上運行它時,MyCustomView中的漸變不會填滿整個屏幕。

我試圖運行從MyViewControllerviewDidLoadviewDidLayoutSubviewsviewDidAppearapplyBackgroundGradient這些都不似乎把工作做好。

任何建議重新:如何解決這一問題,非常感謝。謝謝你的閱讀。

+0

是否設置制約MyCustomView,這樣它會填滿屏幕? – vacawama

+0

是的。我在模擬器中獲得了期望的結果。我在物理設備上遇到此問題。 – Adrian

+0

您可以在模擬器上獲得所有設備尺寸的預期結果嗎? – vacawama

回答

1

嘗試更換

gradient.frame = self.bounds 

gradient.frame.size = self.frame.size 
gradient.frame.origin = CGPoint(x: 0.0, y: 0.0) 

,你絕對應該從OP稱呼它

var didLayoutSubviews = false 

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 
    if !self.didLayoutSubviews { 
     self.didLayoutSubviews = true 
     //apply gradient 
     //you can also try to execute drawing inside `DispatchQueue.main.async {}` 
    } 
} 

附錄:

我的問題的一部分源自我的didSet,它調用漸變的顏色。我沒有在didSet中設置數組,而是將代碼移動到applyBackgroundGradient方法。

@IBInspectable var gradientColor0: UIColor = UIColor.flatWhite { 
    didSet { 
     applyBackgroundGradient() 
    } 
} 

@IBInspectable var gradientColor1: UIColor = UIColor.flatWhiteDark { 
    didSet { 
     applyBackgroundGradient() 
    } 
} 

...和MyCustomView梯度代碼如下所示:

public func applyBackgroundGradient() { 
    gradientColors = [gradientColor0, gradientColor1] 
    self.view.gradientFrom(gradientColors) 
} 
+0

謝謝!我的問題的一部分是框架。另一部分是我應用漸變的方式。我在漸變色的didSets中做了太多工作。相反,我將數組人口代碼移動到'applyBackgroundGradient()'。我會添加到你的答案的底部。 – Adrian

+1

@Adrian,'gradientColors = [gradientColor0,gradientColor1]'應該就夠了。 – vacawama

+0

在viewDidLayoutSubviews中添加漸變是我的修補程序!謝謝! – Phil