2017-04-11 14 views
0

私はやや基本的なサブクラス化されたUICollectionViewセルを持っています。私はそれにUIImageViewを追加したいので、すべてのセルが画像を表示します。サブクラス化されたUICollectionViewCellでセル幅を調べようとしています

x:y:width:heightに明示的な値を追加するとイメージが正しく表示されますが、self.contentView.frame.widthを使用してコレクションビューのセルのサイズを決定することはできません

class SubclassedCell: UICollectionViewCell { 
    var myImageView: UIImageView! 
    required init?(coder aDecoder: NSCoder) { 
     super.init(coder:aDecoder) 
     myImageView = UIImageView(frame: CGRect(x: (self.frame.width - 10.0), y: 50.0, width: 20.0, height: 20.0)) 
     myImageView.image = UIImage(named: "JustinBieber") 
     self.contentView.addSubview(myImageView) 
    } 
} 

上記では、(self.contentView.frame.width - 10.0)はコレクションビューセルのサイズを取得していないため、画像はまったく表示されません。 xの値を明示的に入れると、0と表示されます。

サブクラス化されたコレクションビューセルのサイズ(幅)を確認するにはどうすればよいですか?

+0

達成しようとしていることについてさらに詳しく説明できますか?例えば。セルの右側から10ポイントの画像を配置しようとしていますか? – kevin

+0

修正。私は、セルの右側から10ポイントの画像を配置しようとしています。そのため、私はセルの幅を動的に決定する必要があります(それらはすべて同じサイズではありません)。 – Joe

答えて

1

イニシャライザは、ビューのライフサイクルの早い段階で呼び出され、ディメンションの値を正確に提供します。

さらに慣用的なアプローチは、イメージをlayoutSubviewsライフサイクルメソッドでレイアウトすることです。アプリケーションで自動レイアウトを使用している場合、簡単な例が

class SubclassedCell: UICollectionViewCell { 

    var myImageView: UIImageView! 
    var imageDisplayed = false 

    override func layoutSubviews() { 
     super.layoutSubviews() 
     if !imageDisplayed { 
      myImageView = UIImageView(frame: CGRect(x: (self.frame.width - 10.0), y: 50.0, width: 20.0, height: 20.0)) 
      myImageView.image = UIImage(named: "JustinBieber") 
      self.contentView.addSubview(myImageView) 
      imageDisplayed = true 
     } 
    } 
} 

下に例示されている、あなたはまた、画像を追加し、代わりに明示的に画像の枠を設定する制約を提供することを検討することをお勧めします。

このanswerに示されているように、ユースケースによっては、セルを設定する方が効果的かもしれません。

+1

「layoutSubviews」は、ビューのライフサイクル中に複数回呼び出すことができます。 – sooper

+0

助けてくれてありがとうございます。しかし、@sooperのように、layoutSubviewsは何度か呼び出されるため、セルは基本的にどこでもimageViewを吐き出します。 – Joe

+0

@joe - 私はこの例を変更して、 'layoutSubviews'の最初の呼び出しで一度だけビューに画像を追加しました。あなたが探していることを達成するための多くの方法があります。考慮すべき主なものは、ライフサイクルのどの時点で役に立つのですか? – syllabix

1

このレイアウトを実現する方法はたくさんありますが、幅を知る必要はありません。必要な関係を定義し、レイアウトシステムが残りの関係を管理します。

class SubclassedCell1: UICollectionViewCell { 
    var myImageView: UIImageView! 

    private func commonInit() { 
     myImageView = UIImageView() 
     myImageView.image = UIImage(named: "JustinBieber") 
     myImageView.translatesAutoresizingMaskIntoConstraints = false 
     self.contentView.addSubview(myImageView) 

     NSLayoutConstraint.activate([ 
      myImageView.widthAnchor.constraint(equalToConstant: 20), 
      myImageView.heightAnchor.constraint(equalToConstant: 20), 
      myImageView.topAnchor.constraint(equalTo: self.topAnchor, constant: 50), 
      myImageView.rightAnchor.constraint(equalTo: self.rightAnchor, constant: 10), 
      ]) 
    } 

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

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

@syllabixと同様に、layoutSubviewsを使用することもできます。これを行うときは、layoutSubviewsの呼び出しごとにフレームを更新する必要があります。そうしないと、ビューのサイズが変更されても正しく表示されません。子をレイアウトするときは、フレームではなく親ビューの境界を使用します。

class SubclassedCell2: UICollectionViewCell { 
    var myImageView: UIImageView! 

    private func commonInit() { 
     myImageView = UIImageView() 
     myImageView.image = UIImage(named: "JustinBieber") 
     self.contentView.addSubview(myImageView) 
    } 

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

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

    override func layoutSubviews() { 
     super.layoutSubviews() 
     myImageView.frame = CGRect(x: (self.bounds.maxX - 10.0), y: 50.0, width: 20.0, height: 20.0) 
    } 
} 
関連する問題