teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

ソースコードを追加しました

2021/08/10 06:12

投稿

yuka0128
yuka0128

スコア4

title CHANGED
File without changes
body CHANGED
@@ -13,7 +13,247 @@
13
13
  バックはしっかりと実装できていてViewだけが更新されません。
14
14
  そのためControllerを再表示するとしっかりとそのcellは削除されます。
15
15
 
16
+ ソースコードを添付しますがprotocolを使っているので見にくいかもしれません。申し訳ありません。
16
17
 
18
+
19
+ controller側のソースコード
20
+ ```Swift
21
+ import UIKit
22
+
23
+ private let reuseIdentifier = "UserCell"
24
+ private let headerIdentifier = "HeaderView"
25
+
26
+ class BlockedListController: UICollectionViewController {
27
+
28
+ //MARK: - Properties
29
+
30
+ private var users = [User]() {
31
+ didSet { collectionView.reloadData() }
32
+ }
33
+
34
+ private var ifNoOneLabel: UILabel = {
35
+ let label = UILabel()
36
+ label.isHidden = true
37
+ label.text = "現在ブロック中のアカウントはいません????"
38
+ label.textAlignment = .center
39
+ label.textColor = .white
40
+ label.font = UIFont.boldSystemFont(ofSize: 14)
41
+ return label
42
+ }()
43
+
44
+ private var ifNoOneLabel2: UILabel = {
45
+ let label = UILabel()
46
+ label.isHidden = true
47
+ label.text = "ブロックしたアカウントはここに表示されます"
48
+ label.textAlignment = .center
49
+ label.textColor = .white
50
+ label.font = UIFont.systemFont(ofSize: 12)
51
+ return label
52
+ }()
53
+
54
+ //MARK: - Lifecycle
55
+
56
+ override func viewDidLoad() {
57
+ super.viewDidLoad()
58
+ configureUI()
59
+ blockedUsersAreExist()
60
+ fetchBlockedUsers()
61
+ }
62
+
63
+ override func viewDidLayoutSubviews() {
64
+ super.viewDidLayoutSubviews()
65
+ fetchBlockedUsers()
66
+ }
67
+
68
+ //MARK: - API
69
+
70
+ private func fetchBlockedUsers() {
71
+ UserService.fetchBlockedUsers { users in
72
+ self.users = users
73
+ }
74
+ }
75
+
76
+ private func blockedUsersAreExist() {
77
+ UserService.blockedUsersAreExist { bool in
78
+ self.ifNoOneLabel.isHidden = !bool
79
+ self.ifNoOneLabel2.isHidden = !bool
80
+ }
81
+ }
82
+
83
+ //MARK: - Helpers
84
+
85
+ private func configureUI() {
86
+ collectionView.backgroundColor = .backgroundColor
87
+ collectionView.register(BlockedListCell.self, forCellWithReuseIdentifier: reuseIdentifier)
88
+ collectionView.register(BlockedListHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier)
89
+
90
+ let stack = UIStackView(arrangedSubviews: [ifNoOneLabel, ifNoOneLabel2])
91
+ stack.axis = .vertical
92
+ stack.spacing = 4
93
+
94
+ collectionView.addSubview(stack)
95
+ stack.centerX(inView: collectionView)
96
+ stack.anchor(top: collectionView.topAnchor, paddingTop: 240)
97
+ }
98
+ }
99
+
100
+ //MARK: - UICollectionViewDataSource
101
+
102
+ extension BlockedListController {
103
+ override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
104
+ return users.count
105
+ }
106
+
107
+ override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
108
+ let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! BlockedListCell
109
+ cell.delegate = self
110
+ cell.viewModel = UserCellViewModel(user: users[indexPath.row])
111
+ return cell
112
+ }
113
+ }
114
+
115
+ //MARK: - UICollectionViewDelegate
116
+
117
+ extension BlockedListController {
118
+ override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
119
+ let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerIdentifier, for: indexPath) as! BlockedListHeader
120
+ header.delegate = self
121
+ return header
122
+ }
123
+ }
124
+
125
+ //MARK: - UICollectionViewDelegateFlowLayout
126
+
127
+ extension BlockedListController: UICollectionViewDelegateFlowLayout {
128
+ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
129
+ return 1
130
+ }
131
+
132
+ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
133
+ return 1
134
+ }
135
+
136
+ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
137
+ let width = (view.frame.width - 2) / 3
138
+ return CGSize(width: width, height: width)
139
+ }
140
+
141
+ func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
142
+ return CGSize(width: view.frame.width, height: 60)
143
+ }
144
+ }
145
+
146
+ //MARK: - BlockedListHeaderDelegate
147
+
148
+ extension BlockedListController: BlockedListHeaderDelegate {
149
+ func handleDismissal() {
150
+ navigationController?.popViewController(animated: true)
151
+ }
152
+ }
153
+
154
+ //MARK: - BlockedListCellDelegate
155
+
156
+ extension BlockedListController: BlockedListCellDelegate {
157
+ func unblockUser(withUid uid: String) {
158
+ UserService.unblockUser(withUid: uid) { _ in
159
+ self.fetchBlockedUsers()
160
+ self.collectionView.reloadData()
161
+ }
162
+ }
163
+ }
164
+ ```
165
+
166
+
167
+ cell側のソースコード
168
+ ```Swift
169
+ import UIKit
170
+ import SDWebImage
171
+
172
+ protocol BlockedListCellDelegate: AnyObject {
173
+ func unblockUser(withUid uid: String)
174
+ }
175
+
176
+ class BlockedListCell: UICollectionViewCell {
177
+
178
+ //MARK: - Properties
179
+
180
+ weak var delegate: BlockedListCellDelegate?
181
+
182
+ var viewModel: UserCellViewModel? {
183
+ didSet { populateUserData() }
184
+ }
185
+
186
+ private let profileImageView: UIImageView = {
187
+ let iv = UIImageView()
188
+ iv.contentMode = .scaleAspectFill
189
+ iv.backgroundColor = .lightGray
190
+ iv.clipsToBounds = true
191
+ return iv
192
+ }()
193
+
194
+ private let fullnameLabel: UILabel = {
195
+ let label = UILabel()
196
+ label.textColor = .white
197
+ label.font = UIFont.boldSystemFont(ofSize: 14)
198
+ return label
199
+ }()
200
+
201
+ private lazy var unblockButton: UIButton = {
202
+ let button = UIButton(type: .system)
203
+ button.setImage(UIImage(systemName: "xmark.circle.fill"), for: .normal)
204
+ button.setDimensions(height: 30, width: 30)
205
+ button.tintColor = .lightGray
206
+ button.addTarget(self, action: #selector(handleUnblock), for: .touchUpInside)
207
+ return button
208
+ }()
209
+
210
+ //MARK: - Lifecycle
211
+
212
+ override init(frame: CGRect) {
213
+ super.init(frame: frame)
214
+ configureUI()
215
+ }
216
+
217
+ required init?(coder: NSCoder) {
218
+ fatalError("init(coder:) has not been implemented")
219
+ }
220
+
221
+ //MARK: - Actions
222
+
223
+ @objc func handleUnblock() {
224
+ guard let uid = viewModel?.user.uid else { return }
225
+ delegate?.unblockUser(withUid: uid)
226
+ }
227
+
228
+ //MARK: - Helpers
229
+
230
+ private func configureUI() {
231
+ addSubview(profileImageView)
232
+ profileImageView.setDimensions(height: 80, width: 80)
233
+ profileImageView.layer.cornerRadius = 80 / 2
234
+ profileImageView.centerX(inView: self)
235
+ profileImageView.centerY(inView: self)
236
+
237
+ addSubview(fullnameLabel)
238
+ fullnameLabel.centerX(inView: profileImageView)
239
+ fullnameLabel.anchor(top: profileImageView.bottomAnchor, paddingTop: 8)
240
+
241
+ addSubview(unblockButton)
242
+ unblockButton.anchor(top: topAnchor, right: rightAnchor, paddingTop: 6, paddingRight: 6)
243
+ }
244
+
245
+ private func populateUserData() {
246
+ guard let viewModel = viewModel else { return }
247
+ fullnameLabel.text = viewModel.fullname
248
+ profileImageView.sd_setImage(with: viewModel.profileImageUrl, completed: nil)
249
+ }
250
+ }
251
+
252
+
253
+ ```
254
+
255
+
256
+ ビルドするとこんな感じです。
17
257
  このイメージ右上の✖︎を押下したらそのcellを削除したい
18
258
  ![イメージ説明](4f2e4dc78cbf845c145d91852edc0feb.png)
19
259