2016-09-06 5 views
0

問題:インターフェイスビルダーの代わりに、実行時にビュー上のクラスを設定する方法

私はビューmyViewに添付以下のクラスmyShadowを持っています。

クラスは、インターフェイスビルダーのカスタムクラスとしてビューに関連付けられています。

ただし、アプリの実行中にクラスを設定したい場合があります。

enter image description here

質問:

ユーザーがボタンmyButtonをタップしたときにどのように私の代わりにプログラム的に、たとえば、実行時に表示 myViewにクラスmyShadowを設定することができますか? ViewControllerの中で、クラスを通常の関数として呼び出す方法はありますか?

コード:

import UIKit 

class ViewController: UIViewController { 

    @IBOutlet weak var myView: UIView! 

    @IBAction func myButton(sender: AnyObject) { 


     //// How to set `myShadow` class on `myView` here when tapping `myButton`? //// 


    } 

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

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

class myShadow: UIView { 

    var shadowLayer: CAShapeLayer! 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     if shadowLayer == nil { 
      shadowLayer = CAShapeLayer() 
      shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
      shadowLayer.fillColor = UIColor.yellowColor().CGColor 
      shadowLayer.shadowColor = UIColor.blackColor().CGColor 
      shadowLayer.shadowPath = shadowLayer.path 
      shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
      shadowLayer.shadowOpacity = 1 
      shadowLayer.shadowRadius = 5 
      layer.insertSublayer(shadowLayer, atIndex: 0) 
     } 
    } 
} 

答えて

1

スウィフトは強く型付けされた言語です。これはバグではなく機能です。変数を宣言すると、その変数はその型になります。 swizzlingやその他のテクニックはobjective-cのようにより動的な言語で動くが、swiftはタイプを強制する。

シャドウレイヤーの追加と削除には、UIViewの拡張子を使用することをお勧めします。たとえば:

extension UIView 
{ 
    func applyShadow() 
    { 
     let shadowLayer = CAShapeLayer() 
     shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
     shadowLayer.fillColor = UIColor.yellowColor().CGColor 
     shadowLayer.shadowColor = UIColor.blackColor().CGColor 
     shadowLayer.shadowPath = shadowLayer.path 
     shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
     shadowLayer.shadowOpacity = 1 
     shadowLayer.shadowRadius = 5 
     layer.insertSublayer(shadowLayer, atIndex: 0) 
    } 

    func removeShadow() 
    { 
     guard let sublayers = layer.sublayers where sublayers.count > 0 else { return } 
     let shadowLayer = sublayers[0] 
     if shadowLayer.shadowPath != nil 
     { 
      shadowLayer.removeFromSuperlayer() 
     } 
    } 

} 

次にあなたが言うことができる:

@IBAction func myButton(sender: AnyObject) { 
    if let button = sender as? UIButton 
    { 
     button.applyShadow() // if you want to apply it to the button 
     myView.applyShadow() // if you want to apply it to some other view 
    } 
} 

をこれは、任意のUIViewまたはUIViewの任意のサブクラスで動作しますが、ビューのレイヤー階層の構造についての仮定を作っています。

など何か言うその後MyShadow

shouldShowShadowよう
class MyShadow: UIView { 

    var shadowLayer: CAShapeLayer! 
    var shouldShowShadow = false 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     if shadowLayer == nil && shouldShowShadow 
     { 
      shadowLayer = CAShapeLayer() 
      shadowLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: 5).CGPath 
      shadowLayer.fillColor = UIColor.yellowColor().CGColor 
      shadowLayer.shadowColor = UIColor.blackColor().CGColor 
      shadowLayer.shadowPath = shadowLayer.path 
      shadowLayer.shadowOffset = CGSize(width: 0, height: 0) 
      shadowLayer.shadowOpacity = 1 
      shadowLayer.shadowRadius = 5 
      layer.insertSublayer(shadowLayer, atIndex: 0) 
     } 
     else if shadowLayer != nil && !shouldShowShadow 
     { 
      shadowLayer.removeFromSuperlayer() 
      shadowLayer = nil 
     } 
    } 
} 

にブール型プロパティを追加します。MyShadowのインスタンスでのみ動作

@IBAction func myButton(sender: AnyObject) { 
    self.shadowView.shouldShowShadow = true 
    self.shadowView.setNeedsLayout() 
} 

を。

+0

ありがとう、これらはいくつかの良いオプションです! – user4806509

1

私はその可能性はないと思います。プログラムでクラスオブジェクトを作成する必要がある場合は、オブジェクトを初期化する必要があります。

MyShadow *myShadow = [[MyShadow alloc] init]; 

また、変更する予定のクラスに特定の継承階層がある場合は、特定のオブジェクトをキャストすることができます。

MyShadow *myShadow = (MyShadow *)myShadow; 

それともいないクラスにメソッドに通常適用されるにObjC /ランタイムライブラリを使用して、いくつかの実行時のスウィズリングを行うことができます。

「MyView」を「MyShadow」のサブクラスにしてください。

+0

ありがとう、私はすぐに行く予定です。 – user4806509

関連する問題