質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

237閲覧

お世話になります。 Swift初心者です。 お忙しい中大変申し訳ございませんが、 CollectionViewの実装で悩んでおります 長文となりまして、ご面倒をお掛け致しますが、どうぞよろしくお願

sw07

総合スコア22

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/11/05 09:18

お世話になります。
Swift初心者です。

お忙しい中大変申し訳ございませんが、
CollectionViewの実装で悩んでおります

長文となりまして、ご面倒をお掛け致しますが、どうぞよろしくお願い致します

現在、1列目と1行目にヘッダ情報が含まれる表形式のビュー(CollectionView利用)を表示させ
左右にスクロールする場合は、表の1列目が固定され
上下にスクロールする場合は、表の1行目が固定されるような画面を構築中です
こちらの回答を参考

1つのセルは、4つのアイテムで構築しておりまして、上から
1段目に「タイトル」文言(UILabel)
2段目にイメージ画像(UIImageView)
3段目に「詳細」文言(UILabel)
そして、中央にチェックボックスのイメージ画像(UIImageView)を配置しセル位置により表示切り替えをします
最左上のセルは何も表示せず
そこを除いた1列目と1行目のセルには、1〜3段目のアイテム、その他のセルにはチェックボックス画像のみを表示する構成となります

構築にあたり、UICollectionViewLayoutを使用しておりまして
スクロールは行えており、各セルに想定したアイテムは配置はされておりますが
可変となるセルのサイズ指定(受け渡し)方法がわからず
また、制約がうまく動作せずで、行き詰まっております

前提・実現したいこと

1.下記のUIViewController内の★1の計算結果をUICollectionViewLayoutへ渡す方法を知りたいです

2.制約について、タイトルと詳細(UILabel)は折り返しで表示、イメージ画像がある場合はタイトルと詳細の間に差し込みたく、ない場合は上に詰めて表示。チェックボックスは、画面の中央に画像を配置する表示動作を想定しております

該当のソースコード

▼▼UIViewController class SelectItemViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { @IBOutlet weak var selectView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() selectView.delegate = self selectView.dataSource = self } override func viewWillAppear(_ animated: Bool) { // タイトル情報 getTitles() // イメージ画像 getImages() } override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() // CoreDataから取得したタイトル長とイメージ画像を元に幅と高さ計算(★1) cellWidth = getWidth() cellHeight = getWidth() } // セルのサイズ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: cellWidth, height: cellHeight) } // セルの数を返す func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return columnTitles.count } func numberOfSections(in collectionView: UICollectionView) -> Int { return rowTitles.count } // セルの設定 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SelectItemCollectionViewCell // 1行目 if indexPath.section == 0 { // 1列目 if indexPath.row == 0 { cell.title.text = "" cell.image.image = UIImage(named: "") cell.detail.text = "" cell.chk.image = UIImage(named: "") // 2列目以降 } else { cell.title.text = rowTitles[indexPath.row] cell.image.image = UIImage(named: rowImages[indexPath.row]) cell.detail.text = rowDetails[indexPath.row] cell.chk.image = UIImage(named: "") cell.isRowImage = isRowImage // 制約 cell.configure(indexPath: indexPath) } // 2行目以降 } else { // 1列目 if indexPath.row == 0 { cell.title.text = columnTitles[indexPath.section] cell.image.image = UIImage(named: columnImages[indexPath.section]) cell.detail.text = columnDetails[indexPath.section] cell.chk.image = UIImage(named: "") cell.isColumnImage = isColumnImage // 制約 cell.configure(indexPath: indexPath) // 2列目以降 } else { cell.title.text = "" cell.image.image = UIImage(named: "") cell.detail.text = "" cell.chk.image = UIImage(named: "Check_off") // 制約 cell.configure(indexPath: indexPath) } } return cell } } ▼▼UICollectionViewCell class SelectItemCollectionViewCell: UICollectionViewCell { @IBOutlet weak var title: UILabel! @IBOutlet weak var image: UIImageView! @IBOutlet weak var detail: UILabel! @IBOutlet weak var chk: UIImageView! var isRowImage: Bool = false var isColumnImage: Bool = false // セルの制約 func configure(indexPath: IndexPath) { // 1行目 if indexPath.section == 0 { // 1列目 if indexPath.row == 0 { // 制約なし // 2列目以降 } else { // 行タイトル title.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ title.topAnchor.constraint(equalTo: self.topAnchor, constant: 5.0), title.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 2.0), title.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 2.0), title.bottomAnchor.constraint(greaterThanOrEqualTo: self.bottomAnchor, constant: -150.0) ]) // 画像イメージ image.translatesAutoresizingMaskIntoConstraints = false if isRowImage == true { image.heightAnchor.constraint(equalToConstant: 72.0).isActive = true image.widthAnchor.constraint(equalToConstant: 128.0).isActive = true } image.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 1.0).isActive = true image.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5.0).isActive = true // 行詳細 detail.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ detail.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 1.0), detail.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 5.0), detail.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 5.0), detail.bottomAnchor.constraint(greaterThanOrEqualTo: self.bottomAnchor, constant: -150.0) ]) } // 2行目以降 } else { // 1列目 if indexPath.row == 0 { // 列タイトル title.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ title.topAnchor.constraint(equalTo: self.topAnchor, constant: 5.0), title.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 2.0), title.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 2.0), title.bottomAnchor.constraint(greaterThanOrEqualTo: self.bottomAnchor, constant: -150.0) ]) // 画像イメージ image.translatesAutoresizingMaskIntoConstraints = false if isColumnImage == true { image.heightAnchor.constraint(equalToConstant: 72.0).isActive = true image.widthAnchor.constraint(equalToConstant: 128.0).isActive = true } image.topAnchor.constraint(equalTo: title.bottomAnchor, constant: 1.0).isActive = true image.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 2.0).isActive = true // 列詳細 detail.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ detail.topAnchor.constraint(equalTo: image.bottomAnchor, constant: 1.0), detail.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: 2.0), detail.trailingAnchor.constraint(equalTo: self.trailingAnchor, constant: 2.0), detail.bottomAnchor.constraint(greaterThanOrEqualTo: self.bottomAnchor, constant: -150.0) ]) // 2列目以降 } else { // 制約なし } } } } ▼▼UICollectionViewLayout class SelectItemUICollectionViewLayout: UICollectionViewLayout { var columns = 0 var shouldPinFirstColumn = true var shouldPinFirstRow = true var itemAttributes = [[UICollectionViewLayoutAttributes]]() var itemsSize = [CGSize]() var contentSize: CGSize = .zero override func prepare() { (省略) if itemAttributes.count != collectionView.numberOfSections { generateItemAttributes(collectionView: collectionView) return } for section in 0..<collectionView.numberOfSections { for item in 0..<collectionView.numberOfItems(inSection: section) { (省略) } } } override var collectionViewContentSize: CGSize { return contentSize } override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { return itemAttributes[indexPath.section][indexPath.row] } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { (省略) return attributes } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true } } // MARK: - Helpers extension SelectItemUICollectionViewLayout { func generateItemAttributes(collectionView: UICollectionView) { if itemsSize.count != columns { calculateItemSizes() } var column = 0 var xOffset: CGFloat = 0 var yOffset: CGFloat = 0 var contentWidth: CGFloat = 0 itemAttributes = [] for section in 0..<collectionView.numberOfSections { var sectionAttributes: [UICollectionViewLayoutAttributes] = [] for index in 0..<columns { let itemSize = itemsSize[index] let indexPath = IndexPath(item: index, section: section) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) attributes.frame = CGRect(x: xOffset, y: yOffset, width: itemSize.width, height: itemSize.height).integral (省略) } itemAttributes.append(sectionAttributes) } if let attributes = itemAttributes.last?.last { contentSize = CGSize(width: contentWidth, height: attributes.frame.maxY) } } func calculateItemSizes() { itemsSize = [] for index in 0..<columns { itemsSize.append(sizeForItemWithColumnIndex(index)) } } func sizeForItemWithColumnIndex(_ columnIndex: Int) -> CGSize { var text: NSString // ここでUIViewController内で計算したwidthとheightを利用したい return CGSize(width: 250, height: 200) } }

試したこと

1.について
UIViewControllerの「セルのサイズ」で計算した高さと幅を返すようにしておりますが、
この処理自体が呼び出されておらず、他にUICollectionViewLayout側へ計算値を渡す方法がないか模索中です。

補足情報(FW/ツールのバージョンなど)

swift4
xCode10.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dice142

2018/11/06 06:01

質問は修正できますので、間違えた場合や修正依頼があった場合は随時修正して対応した方が良いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問