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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

Q&A

解決済

1回答

1853閲覧

[Swift] UICollectionViewのレイアウトが崩れてしまう

RyuS08

総合スコア3

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

UI

UIはUser Interfaceの略であり、人間がコンピュータとやりとりをするためのシステムです。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

0グッド

0クリップ

投稿2021/06/27 09:48

内容

ブラウザを作成していて、新しいページのところに表示するViewController内のUICollectionViewのレイアウトが崩れてしまいます。
UICollectionViewを最初に表示しているときはLayoutが崩れないが、上にスクロールして戻るとレイアウトが崩れています。

レイアウトが崩れる前↓
崩れる前
レイアウトが崩れた後↓
イメージ説明

エラーログ

イメージ説明

該当のソースコード

ソースコードがとても長いので、UICollectionViewの実装部分と表示するUICollectionViewCellのサブクラスだけ載っけます。

collectionViewの実装部分↓

swift

1 let layout = UICollectionViewFlowLayout() 2 layout.itemSize = CGSize(width:76, height:85) 3 layout.sectionInset = UIEdgeInsets(top: 13, left: 13, bottom: 13, right: 13) 4 layout.headerReferenceSize = CGSize(width:view.bounds.size.width,height:48) 5 layout.estimatedItemSize = .zero 6 layout.minimumLineSpacing = 0 7 layout.minimumInteritemSpacing = 0 8 9 collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) 10 collectionView.translatesAutoresizingMaskIntoConstraints = false 11 collectionView.register(NewPageIconCell.self, forCellWithReuseIdentifier: "MyCell") 12 collectionView.register(UICollectionReusableView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "Section") 13 collectionView.backgroundColor = .clear 14 collectionView.delegate = self 15 collectionView.dataSource = self 16 if isEditingCell { 17 let tapGesture = UITapGestureRecognizer(target: self, action: #selector(screenTapped)) 18 collectionView.addGestureRecognizer(tapGesture) 19 } 20 self.view.addSubview(collectionView) 21 NSLayoutConstraint.activate([ 22 collectionView.topAnchor.constraint(equalTo: view.topAnchor), 23 collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor), 24 collectionView.leftAnchor.constraint(equalTo: view.leftAnchor), 25 collectionView.rightAnchor.constraint(equalTo: view.rightAnchor) 26 ])

NewPageIconCell.swift

Swift

1import Foundation 2import UIKit 3 4protocol NewPageIconCellDelegate : AnyObject { 5 func removeCell(cell:NewPageIconCell) 6} 7 8class NewPageIconCell : UICollectionViewCell, Crop, FaviconOptimizer { 9 10 weak var delegate:NewPageIconCellDelegate! 11 var url = "" 12 var icon = UIImageView() 13 var removeIcon = UIButton() 14 var stack = UIStackView().then { 15 $0.alignment = .center 16 $0.axis = .vertical 17 $0.distribution = .equalSpacing 18 $0.translatesAutoresizingMaskIntoConstraints = false 19 } 20 var title:String = "" 21 var isEditingCell:Bool = false 22 23 override init(frame: CGRect) { 24 super.init(frame: .zero) 25 } 26 required init?(coder: NSCoder) { 27 fatalError("init(coder:) has not been implemented") 28 } 29 public func setIconAndUrl(url:String,title:String,size:Int,isEditing:Bool) { 30 self.isEditingCell = isEditing 31 let data = optimizeFaviconData(url: url) 32 if !data.0 { 33 FavIconFetcher.download(url:url) { result in 34 if case let .success(image) = result { 35 DispatchQueue.main.async { 36 self.iconSet(image: image, url: url, size: size, title: title, crop: true) 37 } 38 } 39 } 40 }else{ 41 self.iconSet(image: data.1!, url: url, size: size, title: title, crop: false) 42 } 43 } 44 func urlToHostName(urlString:String) -> String { 45 if let component: NSURLComponents = NSURLComponents(string: urlString) { 46 return component.host ?? "about:blank" 47 }else{ 48 return "about:blank" 49 } 50 } 51 private func iconSet(image:UIImage,url:String,size:Int,title:String,crop:Bool) { 52 self.title = title 53 self.icon = crop ? UIImageView(image: cropThumbnailImage(image: image, w: size, h: size)).then { 54 $0.translatesAutoresizingMaskIntoConstraints = false 55 $0.clipsToBounds = true 56 $0.layer.cornerRadius = 5 57 }:UIImageView(image: image).then { 58 $0.translatesAutoresizingMaskIntoConstraints = false 59 $0.clipsToBounds = true 60 $0.layer.cornerRadius = 7 61 if image == UIImage(systemName: "plus") { 62 $0.tintColor = .white 63 $0.backgroundColor = .lightGray 64 $0.layer.cornerRadius = 5 65 $0.clipsToBounds = true 66 } 67 } 68 if isEditingCell { 69 self.removeIcon = UIButton().then { 70 $0.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal) 71 $0.addTarget(self, action: #selector(removeCell), for: .touchUpInside) 72 $0.translatesAutoresizingMaskIntoConstraints = false 73 $0.tintColor = .lightGray 74 } 75 } 76 self.url = url 77 self.setupIcon() 78 } 79 @objc func removeCell() { 80 self.delegate.removeCell(cell: self) 81 } 82 private func setupIcon() { 83 self.addSubview(stack) 84 let titleLabel = UILabel().then { 85 $0.text = title 86 $0.textColor = .blackWhite 87 $0.translatesAutoresizingMaskIntoConstraints = false 88 $0.textAlignment = .center 89 $0.font = UIFont.systemFont(ofSize: 13) 90 } 91 stack.addArrangedSubViews([icon,titleLabel]) 92 NSLayoutConstraint.activate([ 93 titleLabel.widthAnchor.constraint(lessThanOrEqualTo: widthAnchor), 94 icon.widthAnchor.constraint(equalToConstant: 60), 95 icon.heightAnchor.constraint(equalToConstant: 60), 96 stack.topAnchor.constraint(equalTo: topAnchor,constant: 6), 97 stack.bottomAnchor.constraint(equalTo: bottomAnchor), 98 stack.leftAnchor.constraint(equalTo: leftAnchor,constant: 6), 99 stack.rightAnchor.constraint(equalTo: rightAnchor,constant:-6) 100 ]) 101 if isEditingCell { 102 self.addSubview(removeIcon) 103 NSLayoutConstraint.activate([ 104 removeIcon.topAnchor.constraint(equalTo: self.topAnchor), 105 removeIcon.rightAnchor.constraint(equalTo: self.rightAnchor) 106 ]) 107 } 108 } 109}

試したこと

とりあえずネットに書いてあることは全て試しました。例えば、estimatedSizeをnoneにしたり、spacingを変えてみたりしました。
エラーログ的にAuto Layout関係でクラッシュしているようなのですが、いつもとは違う制約のエラーなので、自分にはさっぱりわかりません。
有識者の方ご教授いただけると幸いです。

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

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

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

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

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

guest

回答1

0

自己解決

なぜかCellを再描画する際にstackView内に2つUIImageViewが入ってたみたいなので、一度stackViewをリセットすることで解決しました。
stack.removeAllArrangedSubviews()

Swift

1func removeAllArrangedSubviews() { 2 let removedSubviews = arrangedSubviews.reduce([]) { (allSubviews, subview) -> [UIView] in 3 self.removeArrangedSubview(subview) 4 return allSubviews + [subview] 5 } 6 NSLayoutConstraint.deactivate(removedSubviews.flatMap({$0.constraints })) 7 removedSubviews.forEach({ $0.removeFromSuperview() }) 8 } 9}

投稿2021/06/27 11:11

RyuS08

総合スコア3

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問