2017-04-06 13 views
1

サブクラス化されたNavigationControllerの背景にグラデーションを設定しようとしています。同じコードに色を追加するとうまくいきますが、グラデーションを表示させることができません。私はバックグラウンドビューとしてCAGradientLayerを返すUIViewのサブクラスを作成しました。ここでバックグラウンドのグラデーションビューが顧客にロードされない理由UINavigationControllerクラス

は私のサブクラスUIViewのである:(

@IBDesignable 
class GenericBackgrounView: UIView { 

override class var layerClass: AnyClass { 
    return CAGradientLayer.self 
} 


///The roundness for the corner 
@IBInspectable var cornerRadius: CGFloat = 0.0 { 
    didSet{ 
     setupGradient() 
    } 
} 

func setupGradient() { 
    //let gradientColors = [bgDarkColor.cgColor, bgDarkColor.blended(withFraction: 0.5, of: bgLightColor).cgColor, bgLightColor.cgColor] 
    let gradientColors = [UIColor.brown.cgColor, UIColor.red.blended(withFraction: 0.5, of: UIColor.cyan).cgColor, UIColor.yellow.cgColor] 
    gradientLayer.colors = gradientColors 
    gradientLayer.locations = ESDefault.backgroundGradientColorLocations 
    setNeedsDisplay() 
} 

var gradientLayer: CAGradientLayer { 
    return self.layer as! CAGradientLayer 
} 

override func awakeFromNib() { 
    super.awakeFromNib() 
    setupGradient() 
} 
override func prepareForInterfaceBuilder() { 
    setupGradient() 
} 

} 

奇妙されているので、私はその積載右グラデーション確信している色に注意してください。そして、ここに私UINavigationControllerです。 クラスGenericNavigationController:UINavigationController {

override func viewDidLoad() { 
    super.viewDidLoad() 
    let backView = GenericBackgrounView(frame: self.view.frame) 
    backView.bounds = self.view.bounds 
    self.view.backgroundColor = UIColor.clear 
    self.view.addSubview(backView) 
    self.view.sendSubview(toBack: backView) 

    // Do any additional setup after loading the view. 
} 
} 
は、

また、私がGenericBackgroundViewをインターフェイスビルダーに追加したビューに使用すると、正常に動作することに注意してください。

私はこれを長く続けてきました。私はAppleに、コードとInterface Builderの両方で何らかの種類のTheming APIをセットアップすることを提案していると思います...そしてInterface Builderに直接グラデーションを追加する機能...

ありがとうございました。

+0

ブレンドされた(withFraction:0.5、of:UIColor)関数を最小化しないでください。これは、UIColorの拡張であり、係数付きブレンドカラーを作成したものです。 –

+0

'viewDidLoad'は、viewControllerの' view'のランタイム 'frame'をキャプチャするには時期尚早です。ビューが画面上に表示された後に、デバッガでグラデーションビューのフレームを印刷しようとしましたか?それはおそらくそれがスクリーン上にない理由を伝えるでしょう。 – creeperspeak

+0

私はデバッガについて十分に分かっていないかもしれないと思います。 –

答えて

0

に設定する代わりに、viewDidLayoutSubviews()で呼び出してみてください。理由は、viewDidLayoutSubviews()には、ビューの正しいフレームを持っていますが、awakeFromNib()ではビューの右フレームを知りませんでした。Apple Documentation

+0

私はもう一度それを試しましたが、同じ問題があります。私は関数のGenericBackgrounView(frame:self.view.frame)を呼び出す前に、ビューの境界とフレームが初期化されていることを確認しました。私はUITableViewCellのような他のタイプのUIViewのサブクラスに同様の問題を追加しています。それらはすべてUIViewのサブクラスですが、グラデーションが好きではないようです。私はそれらのすべてで同じコードを適用することはできません。 Pfff .. –

0

申し訳ありませんが、私は少し微妙に変わってしまい、いくつかの作業コードを見つけました。私はまだこれがなぜ機能するのか、私が前にそれを持っていた方法ではない理由を理解するのが大好きです。 。(私の勾配がCAGradientLayerの形態であることを忘れないでください、私はデフォルト値を持っているいくつかの静的変数を作った

import UIKit 

class GenericNavigationController: UINavigationController { 
    let backViewGradient = Default.testGradientCALayer 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     setupBackground() 
    } 

    func setupBackground() { 
     backViewGradient.frame = self.view.frame 
     self.view.layer.insertSublayer(backViewGradient, at: 0) 
    } 

    override func prepareForInterfaceBuilder() { 
     setupBackground() 
    } 
} 

を私:私はそれが魔法で働く感じ...ここ

は、作業コードで嫌いUIViewからサブクラス化されたすべてのUIControlが同じように動作するわけではないので、どのようになっているのでしょうか?すべてが背景であるビューを持っていて、レイヤーまたはサブビューを追加することができます。私の前のコードを動作させるか、私の最新のコードをTableViewCellで動作しないようにしてください。

私はこの質問を残します私はこれの背後にある真実を知りたいので、開いている。私は、SwiftやXcodeがやや魔法や矛盾した動作をしていれば、それを完全に把握できるとは思えません。

+0

私はちょうど実現した、私はインターフェイスビルダーでビューのカスタム設定を表示する機能を失った... –

関連する問題