2017-06-03 12 views
0

@IBDesignable UIViewにグラデーションを追加しようとしています。 Simulatorではすべてがうまくいっていましたが、物理的なデバイス上で実行すると、グラデーションは画面に表示されません。私は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から私の勾配中心コード:MyViewControllerオン

@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)) 
    } 
} 

が、私はUIViewのは、MyCustomViewにそのサブクラスを設定追加します。インターフェイスビルダが表示されますが、物理デバイス上で実行すると、MyCustomViewのグラデーションが画面全体に表示されません。

私はそれらのどれも仕事を得るように見えるん、MyViewControllerさんviewDidLoadviewDidLayoutSubviewsviewDidAppearからapplyBackgroundGradientを実行してみました。

どのような提案を再:どのようにこれを解決するために大変感謝しています。読んでくれてありがとう。

+0

は、それが画面いっぱいになるように、あなたはMyCustomView上の制約を設定しましたか? – vacawama

+0

はい。私はシミュレータで望ましい結果を得ました。私は物理的なデバイスでこの問題に遭遇しています。 – Adrian

+0

すべてのデバイスサイズに対して、シミュレータで必要な結果が得られますか? – vacawama

答えて

1

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

gradient.frame = self.bounds 

を交換しようとすると、あなたは間違いなく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

ありがとうございます!私の問題の一部はフレームでした。他の部分は、私がグラデーションを適用する方法でした。私はグラデーションカラーのdidSetであまりにも多くの作業をしていました。代わりに、私は配列の人口コードを 'applyBackgroundGradient()'に移動しました。あなたの答えの一番下に追加します。 – Adrian

+1

@Adrian、 'gradientColors = [gradientColor0、gradientColor1]'で十分です。 – vacawama

+0

viewDidLayoutSubviewsにグラデーションを追加することは私のための修正でした!ありがとう! – Phil

関連する問題