2016-06-17 6 views
0

別のカスタムでは、ネストされたカスタムのUIViewの変数を変更しますビュー自体。唯一の円の中に画像を使用してビューを作成するためにオーバーライドされたのdrawRectた設定/私は現在、ネストされたカスタムUIViewのの変数を変更し、したがってに反映することができないと、他のカスタムUIViewsにネストされたカスタムUIViewsの問題に実行しているのUIView

TokenView、:

現在、私は3つのカスタムUIViewsを持っています。サブビューとしてTokenViewを()があり、私は私の変数を変更TokenView言ったとき、同様に意図したとおりに機能

@IBDesignable class TokenView: UIView { 

@IBInspectable var tokenOutlineColor: UIColor = UIColor.blackColor() 
@IBInspectable var tokenBackgroundColor: UIColor = UIColor.lightGrayColor() 
@IBInspectable var tokenImage: UIImage! 

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

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

override func drawRect(rect: CGRect) { 

    var context = UIGraphicsGetCurrentContext() 

    var thickness: CGFloat = 3 
    var path = UIBezierPath(ovalInRect: CGRect(origin: CGPointMake(thickness/2, thickness/2), size: CGSize(width: rect.width - thickness, height: rect.height - thickness))) 

    CGContextSaveGState(context) 
    path.addClip() 

    tokenOutlineColor.setStroke() 
    tokenBackgroundColor.setFill() 
    path.fill() 
    if let image = tokenImage { 
     tokenImage.drawInRect(rect) 
    } 
    path.stroke() 

    } 
} 

PersonView、。

PersonViewインスタンスが作成され、その変数がそこから変更されている、との問題が約出番つまりそれによって
class PersonView: UIView { 

var name: String? 
var group: PersonGroup? 

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

override init(frame: CGRect) { 
    super.init(frame: frame) 
    makePersonView() 
} 

func makePersonView(){ 

    if name == nil { 
     self.name = "Bob" 
    } 
    if group == nil { 
     self.group = PersonGroup.Good 
    } 

    let token = TokenView() 
    token.translatesAutoresizingMaskIntoConstraints = false 

    switch group! { 
    case .Good: 
     token.tokenOutlineColor = UIColor.greenColor() 
    case .Bad: 
     token.tokenOutlineColor = UIColor.redColor() 
    default: 
     token.tokenOutlineColor = UIColor.blueColor() 
    } 
    token.tokenImage = UIImage(named: name!) 
    token.tokenBackgroundColor = UIColor.clearColor() 
    token.backgroundColor = UIColor.clearColor()   
    addSubview(token) 

    let label = UILabel() 
    label.text = name 
    label.translatesAutoresizingMaskIntoConstraints = false 
    label.textAlignment = NSTextAlignment.Center 
    addSubview(label) 

    NSLayoutConstraint.activateConstraints([ 
     token.topAnchor.constraintEqualToAnchor(topAnchor), 
     token.leadingAnchor.constraintEqualToAnchor(leadingAnchor), 
     token.trailingAnchor.constraintEqualToAnchor(trailingAnchor), 
     token.heightAnchor.constraintEqualToConstant(frame.size.height*0.70), 
     token.bottomAnchor.constraintEqualToAnchor(label.topAnchor), 
     label.leadingAnchor.constraintEqualToAnchor(leadingAnchor), 
     label.trailingAnchor.constraintEqualToAnchor(trailingAnchor), 
     label.bottomAnchor.constraintEqualToAnchor(bottomAnchor) 
     ]) 
} 

とDetailedPersonViewクラス、。他の追加された「詳細」は、クラス内の関数で変更されたときに、ネストされたPersonViewのものではなく、うまく動作します。

class DetailedPersonView: UIView { 

var name: String = "Marley" 
var group: PersonGroup = PersonGroup.Bad 

var quantity: Float = 0.00 
var stat: String? = "Strength" 

required init?(coder aDecoder: NSCoder){ 
    super.init(coder: aDecoder) 
    makeDetailedPersonView() 

} 

override init(frame: CGRect) { 
    super.init(frame: frame) 
    makeDetailedPersonView() 
} 

func makeDetailedPersonView(){ 
    let personView = PersonView() 
    personView.translatesAutoresizingMaskIntoConstraints = false 
    personView.name = name 
    personView.group = group 
    personView.type = type 
    addSubview(personView) 

    let label = UILabel() 
    let quantityString = String(format: quantity == floor(quantity) ? "%.0f":"%.1f", quantity) 
    if unit != nil { 
     label.text = quantityString + " " + stat! 
    } else { 
     label.text = quantityString 
    } 
    label.translatesAutoresizingMaskIntoConstraints = false 
    label.textAlignment = NSTextAlignment.Center 

    addSubview(label) 

    NSLayoutConstraint.activateConstraints([ 
     personView.topAnchor.constraintEqualToAnchor(topAnchor), 
     personView.leadingAnchor.constraintEqualToAnchor(leadingAnchor), 
     personView.trailingAnchor.constraintEqualToAnchor(trailingAnchor), 
     personView.bottomAnchor.constraintEqualToAnchor(label.topAnchor), 
     label.leadingAnchor.constraintEqualToAnchor(leadingAnchor), 
     label.trailingAnchor.constraintEqualToAnchor(trailingAnchor), 
     label.heightAnchor.constraintEqualToConstant(frame.size.height*0.25), 
     label.bottomAnchor.constraintEqualToAnchor(bottomAnchor) 
     ]) 

} 


} 

だから、現在、私のDetailedPersonViewはPersonViewのデフォルトTOKENNAMEとtokenImageを示すそのTokenView(PersonView内にネスト)は、「ボブ」で、同じことがPersonGroup.Badを反映して、円のアウトラインのために行くしています。

私は限られた成功へ、DetailedPersonViewの変数でDetailedPersonViewでPersonViewを初期化しようとする、PersonViewのカスタムのinitメソッドを使用して試してみました。

理想的には、このカスタムサブビューはどこUILabel()、UILabelが行うのと同じように動作するはずですそれが理にかなっている場合。テキストは、その変数の変化に応じてビューにそのテキストを変更します。

は、これまでのところ、まだこの問題に明確な解決策を見つけていない:

は、この質問を読んでいただきありがとうございます\! :

EDIT: 私がうまくいくと思った回避策の1つは、カスタムのUIViewにクラスメソッドを実装して、各サブビューの内容をリセットし、変数が変更されるたびに呼び出すことです。または、同じ結果を得ることができるデリゲート内の関数が既に存在し、ビューが変更されたときに呼び出されます。

答えて

2

あなたはサブビューのプロパティを変更することなく、それらの特性に依存サブビューにそれらの変更を伝播されていません。迅速に、これは通常、プロパティの観察で行われます。詳細については、プロパティオブザーバーのセクションhereを参照してください。しかし、didSetオブザーバーを使って変更を伝播することができます。たとえば、あなたのPersonViewクラスでは、まず、それへの参照を維持する必要がありTokenViewサブビューvar tokenView:TokenView?だし、UILabel subviewするvar nameLabelます:UILabel? and set them equal to the TokenView and UILabel you create in makePersonView`。そして、名前に観察プロパティを追加します。

var name: String?{ 
     didSet{ 
      if let image = UIImage(named: name!) 
      { 
       self.tokenView?.tokenImage = image 
       self.nameLabel?.text = name 
       self.tokenView?.setNeedsDisplay() 
      } 
     } 
    } 

この方法DetailPersonViewによって名称への変更は自動的にTokenView's画像を変更します。

同様にtokenImagetokenOutlineColorと設定するたびに、表示を再描画する必要があります。

@IBInspectable var tokenOutlineColor: UIColor = UIColor.blackColor(){ 
     didSet{ 
      self.setNeedsDisplay() 
     } 
    } 
    @IBInspectable var tokenImage: UIImage!{ 
     didSet{ 
      self.setNeedsDisplay() 
     } 
    } 
関連する問題