質問編集履歴
5
追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -286,4 +286,4 @@
|
|
286
286
|
|
287
287
|

|
288
288
|
|
289
|
-
この状態でfollowボタンを押しても、
|
289
|
+
この状態でfollowボタンを押しても、Thread 1: breakpoint 2.1もコンソール上にも反応がありませんでした。
|
4
デバック
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
タイトルのことをしたかったのですが、その前のテストで詰まっています。
|
2
1
|
##現在詰まっているところ
|
3
2
|
followボタンをクリックし```print("タップ")```を出力したい
|
4
3
|
|
@@ -285,6 +284,6 @@
|
|
285
284
|
|
286
285
|
```
|
287
286
|
|
287
|
+

|
288
|
+
|
288
|
-
こ
|
289
|
+
この状態でfollowボタンを押しても、エラーもコンソール上にも反応がありませんでした。
|
289
|
-
原因に検討がつく方や似たような実装をした方、もしいらっしゃいましたら、お力添え頂きたいです。
|
290
|
-
よろしくお願いします。
|
3
追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -6,33 +6,116 @@
|
|
6
6
|
```ここに言語を入力
|
7
7
|
UserProfileHeader.swift
|
8
8
|
|
9
|
+
import UIKit
|
9
|
-
|
10
|
+
import Firebase
|
10
11
|
|
12
|
+
class UserProfileHeader: UICollectionViewCell {
|
13
|
+
|
14
|
+
// MARK: - Properties
|
15
|
+
var delegate: UserProfileHeaderDelegate?
|
16
|
+
|
17
|
+
var user: User? {
|
18
|
+
|
19
|
+
didSet {
|
20
|
+
|
21
|
+
// configure edit profile button
|
22
|
+
configureEditProfileFollowButton()
|
23
|
+
|
24
|
+
// set user stats
|
25
|
+
setUserStats(for: user)
|
26
|
+
|
27
|
+
let fullName = user?.name
|
28
|
+
nameLabel.text = fullName
|
29
|
+
|
30
|
+
profileImageView.loadImage(with: (user?.profileImageUrl)!)
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
let profileImageView: UIImageView = {
|
35
|
+
let iv = UIImageView()
|
36
|
+
iv.contentMode = .scaleAspectFill
|
37
|
+
iv.clipsToBounds = true
|
38
|
+
iv.backgroundColor = .red
|
39
|
+
return iv
|
40
|
+
}()
|
41
|
+
|
42
|
+
let nameLabel: UILabel = {
|
43
|
+
let label = UILabel()
|
44
|
+
label.font = UIFont.boldSystemFont(ofSize: 12)
|
45
|
+
return label
|
46
|
+
}()
|
47
|
+
|
48
|
+
|
49
|
+
|
11
|
-
let editProfileFollowButton: UIButton = {
|
50
|
+
let editProfileFollowButton: UIButton = {
|
12
51
|
let button = UIButton(type: .system)
|
13
52
|
button.layer.cornerRadius = 3
|
14
53
|
button.layer.borderColor = UIColor.lightGray.cgColor
|
15
|
-
button.addTarget(self, action: #selector(handleEditProfileFollow), for: .
|
54
|
+
button.addTarget(self, action: #selector(handleEditProfileFollow), for: .touchUpInside)
|
16
55
|
button.layer.borderWidth = 0.5
|
17
56
|
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
|
18
57
|
button.setTitleColor(.black, for: .normal)
|
19
58
|
return button
|
20
59
|
}()
|
60
|
+
|
21
|
-
|
61
|
+
// MARK: - Handlers
|
62
|
+
|
22
|
-
|
63
|
+
@objc func handleEditProfileFollow() {
|
23
64
|
delegate?.handleEditFollowTapped(for: self)
|
24
|
-
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
|
72
|
+
func setUserStats(for user: User?) {
|
73
|
+
|
74
|
+
guard let uid = user?.uid else { return }
|
75
|
+
|
76
|
+
var numberOfFollowers: Int!
|
77
|
+
var numberOfFollowing: Int!
|
78
|
+
|
79
|
+
// get number of followers
|
80
|
+
USER_FOLLOWER_REF.child(uid).observeSingleEvent(of: .value) { (snapshot) in
|
81
|
+
|
82
|
+
if let snapshot = snapshot.value as? Dictionary<String, AnyObject> {
|
83
|
+
numberOfFollowers = snapshot.count
|
84
|
+
} else {
|
85
|
+
numberOfFollowers = 0
|
86
|
+
}
|
87
|
+
|
88
|
+
let attributedText = NSMutableAttributedString(string: "(numberOfFollowers!) \n", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)])
|
89
|
+
attributedText.append(NSAttributedString(string: "followers", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14),
|
90
|
+
NSAttributedString.Key.foregroundColor: UIColor.lightGray]))
|
91
|
+
self.followersLabel.attributedText = attributedText
|
92
|
+
}
|
93
|
+
|
94
|
+
// get number of following
|
25
95
|
|
26
|
-
|
96
|
+
USER_FOLLOWING_REF.child(uid).observeSingleEvent(of: .value) { (snapshot) in
|
97
|
+
|
98
|
+
if let snapshot = snapshot.value as? Dictionary<String, AnyObject> {
|
99
|
+
numberOfFollowing = snapshot.count
|
100
|
+
} else {
|
101
|
+
numberOfFollowing = 0
|
102
|
+
}
|
103
|
+
|
104
|
+
let attributedText = NSMutableAttributedString(string: "(numberOfFollowing!) \n", attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)])
|
105
|
+
attributedText.append(NSAttributedString(string: "following", attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14),
|
106
|
+
NSAttributedString.Key.foregroundColor: UIColor.lightGray]))
|
107
|
+
self.followingLabel.attributedText = attributedText
|
108
|
+
}
|
109
|
+
}
|
110
|
+
|
27
|
-
func configureEditProfileFollowButton(){
|
111
|
+
func configureEditProfileFollowButton(){
|
28
112
|
|
29
113
|
guard let currentUid = Auth.auth().currentUser?.uid else { return }
|
30
114
|
guard let user = self.user else { return }
|
31
115
|
|
32
|
-
// ログインしてるユーザーIDと今、UserProfileHeaderにいるユーザーのIDが同じか 同じだったら、edit profileボタン
|
33
116
|
if currentUid == user.uid {
|
34
117
|
// configure button as edit profile
|
35
|
-
editProfileFollowButton.setTitle("プロフィールを編集", for: .normal)
|
118
|
+
editProfileFollowButton.setTitle("テストプロフィールを編集", for: .normal)
|
36
119
|
} else {
|
37
120
|
// configure button as follow button
|
38
121
|
editProfileFollowButton.setTitleColor(.white, for: .normal)
|
@@ -48,6 +131,32 @@
|
|
48
131
|
}
|
49
132
|
}
|
50
133
|
|
134
|
+
// MARK: - Init
|
135
|
+
|
136
|
+
override init(frame: CGRect) {
|
137
|
+
super.init(frame: frame)
|
138
|
+
|
139
|
+
addSubview(profileImageView)
|
140
|
+
profileImageView.anchor(top: self.topAnchor, left: self.leftAnchor, bottom: nil, right: nil, paddingTop: 16, paddingLeft: 12, paddingBottom: 0, paddingRight: 0, width: 80, height: 80)
|
141
|
+
profileImageView.layer.cornerRadius = 80 / 2
|
142
|
+
|
143
|
+
addSubview(nameLabel)
|
144
|
+
nameLabel.anchor(top: profileImageView.bottomAnchor, left: self.leftAnchor, bottom: nil, right: nil, paddingTop: 12, paddingLeft: 12, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
|
145
|
+
|
146
|
+
configureUserStats()
|
147
|
+
|
148
|
+
addSubview(editProfileFollowButton)
|
149
|
+
|
150
|
+
editProfileFollowButton.anchor(top: postsLabel.bottomAnchor, left: postsLabel.leftAnchor, bottom: nil, right: self.rightAnchor, paddingTop: 4, paddingLeft: 8, paddingBottom: 0, paddingRight: 12, width: 0, height: 30)
|
151
|
+
|
152
|
+
configureBottomToolBar()
|
153
|
+
}
|
154
|
+
|
155
|
+
required init?(coder aDecoder: NSCoder) {
|
156
|
+
fatalError("init(coder:) has not been implemented")
|
157
|
+
}
|
158
|
+
}
|
159
|
+
|
51
160
|
```
|
52
161
|
###### 後にUserProfile.swiftでフォロー・アンフォローを実装したいので、Protocolsファイルに設定
|
53
162
|
|
@@ -69,26 +178,113 @@
|
|
69
178
|
```
|
70
179
|
UserProfile.swift
|
71
180
|
|
181
|
+
import UIKit
|
72
|
-
|
182
|
+
import Firebase
|
73
183
|
|
74
184
|
private let reuseIdentifier = "Cell"
|
75
185
|
private let headerIdentifier = "UserProfileHeader"
|
76
186
|
|
77
|
-
|
187
|
+
class UserProfileVC: UICollectionViewController, UICollectionViewDelegateFlowLayout, UserProfileHeaderDelegate {
|
78
|
-
header.delegate = self
|
79
188
|
|
189
|
+
|
190
|
+
// MARK: - Properties
|
191
|
+
|
192
|
+
|
193
|
+
var currentUser: User?
|
194
|
+
|
195
|
+
var userToLoadFromSearchVC: User?
|
196
|
+
|
197
|
+
override func viewDidLoad() {
|
198
|
+
super.viewDidLoad()
|
199
|
+
|
200
|
+
// Uncomment the following line to preserve selection between presentations
|
201
|
+
// self.clearsSelectionOnViewWillAppear = false
|
202
|
+
|
203
|
+
// Register cell classes
|
80
|
-
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
|
204
|
+
self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: reuseIdentifier)
|
81
205
|
|
82
|
-
// profileページのためにセルにしたいファイルを登録
|
83
|
-
self.collectionView!.register(UserProfileHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier)
|
206
|
+
self.collectionView!.register(UserProfileHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerIdentifier)
|
207
|
+
|
208
|
+
self.collectionView.backgroundColor = .white
|
209
|
+
|
210
|
+
if userToLoadFromSearchVC == nil {
|
211
|
+
fetchCurrentUserData()
|
212
|
+
}
|
213
|
+
|
214
|
+
}
|
84
215
|
|
216
|
+
|
217
|
+
// MARK: - UICollectionView
|
218
|
+
|
219
|
+
override func numberOfSections(in collectionView: UICollectionView) -> Int {
|
220
|
+
// #warning Incomplete implementation, return the number of sections
|
221
|
+
return 1
|
222
|
+
}
|
223
|
+
|
224
|
+
|
225
|
+
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
226
|
+
// #warning Incomplete implementation, return the number of items
|
227
|
+
return 0
|
228
|
+
}
|
229
|
+
|
230
|
+
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
231
|
+
|
232
|
+
// declare header
|
233
|
+
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerIdentifier, for: indexPath) as! UserProfileHeader
|
234
|
+
|
235
|
+
// set delegate
|
236
|
+
header.delegate = self
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
if let user = self.currentUser {
|
241
|
+
// UserProfileHeader のuser
|
242
|
+
header.user = user
|
243
|
+
} else if let userToLoadFromSearchVC = self.userToLoadFromSearchVC {
|
244
|
+
header.user = userToLoadFromSearchVC
|
245
|
+
navigationItem.title = userToLoadFromSearchVC.username
|
246
|
+
}
|
247
|
+
|
248
|
+
// return header
|
249
|
+
return header
|
250
|
+
}
|
251
|
+
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
252
|
+
return CGSize(width: view.frame.width, height: 200)
|
253
|
+
}
|
254
|
+
|
255
|
+
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
256
|
+
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
|
257
|
+
|
258
|
+
// Configure the cell
|
259
|
+
|
260
|
+
return cell
|
261
|
+
}
|
262
|
+
|
85
|
-
// MARK: - UserProfileHeader Protocol
|
263
|
+
// MARK: - UserProfileHeader Protocol
|
86
|
-
func handleEditFollowTapped(for header: UserProfileHeader) {
|
264
|
+
func handleEditFollowTapped(for header: UserProfileHeader) {
|
87
265
|
print("タップ")
|
88
266
|
}
|
267
|
+
|
268
|
+
// MARK: - API
|
269
|
+
func fetchCurrentUserData() {
|
270
|
+
// set the user in header
|
271
|
+
guard let currentUid = Auth.auth().currentUser?.uid else { return }
|
272
|
+
|
273
|
+
Database.database().reference().child("users").child(currentUid).observeSingleEvent(of: .value) { (snapshot) in
|
274
|
+
|
275
|
+
guard let dictionary = snapshot.value as? Dictionary<String, AnyObject> else { return }
|
276
|
+
let uid = snapshot.key
|
277
|
+
|
278
|
+
let user = User(uid: uid, dictionary: dictionary)
|
279
|
+
self.currentUser = user
|
280
|
+
self.navigationItem.title = user.username
|
281
|
+
self.collectionView.reloadData()
|
282
|
+
}
|
283
|
+
}
|
284
|
+
}
|
285
|
+
|
89
286
|
```
|
90
287
|
|
91
|
-
今回の実装の為のコードを抜き出しました。
|
92
288
|
これでコンソールに「タップ」と出力されて欲しいのですが、出ません。
|
93
289
|
原因に検討がつく方や似たような実装をした方、もしいらっしゃいましたら、お力添え頂きたいです。
|
94
290
|
よろしくお願いします。
|
2
ツイあk
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
タイトルのことをしたかったのですが、その前のテストで詰まっています。
|
1
2
|
##現在詰まっているところ
|
2
3
|
followボタンをクリックし```print("タップ")```を出力したい
|
3
4
|
|
1
追加
title
CHANGED
File without changes
|
body
CHANGED
@@ -85,4 +85,9 @@
|
|
85
85
|
func handleEditFollowTapped(for header: UserProfileHeader) {
|
86
86
|
print("タップ")
|
87
87
|
}
|
88
|
-
```
|
88
|
+
```
|
89
|
+
|
90
|
+
今回の実装の為のコードを抜き出しました。
|
91
|
+
これでコンソールに「タップ」と出力されて欲しいのですが、出ません。
|
92
|
+
原因に検討がつく方や似たような実装をした方、もしいらっしゃいましたら、お力添え頂きたいです。
|
93
|
+
よろしくお願いします。
|