Swift reload collection view not working
Swift reload collection view not working
I am new to swift. I follow some tutorial to develop social application like twitter application to follow the tutorial. I start implement to follow button functions. its call the the another API call but same response come with minor modification(e.g - number of follower property increase by one). call also perfectly working. but collection view did not reload.my code is.
ViewConroller
import LBTAComponents
import TRON
import SwiftyJSON
class HomeDatasourceController: DatasourceController
let errorMessageLabel: UILabel =
let label = UILabel()
label.text = "Apologies something went wrong. Please try again later..."
label.textAlignment = .center
label.numberOfLines = 0
label.isHidden = true
return label
()
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator)
collectionViewLayout.invalidateLayout()
func follow()
print("inside controller")
Service.sharedInstance.fetchfollowHomeFeed (homeDatasource, err) in
if let err = err
self.errorMessageLabel.isHidden = false
if let apiError = err as? APIError<Service.JSONError>
if apiError.response?.statusCode != 200
self.errorMessageLabel.text = "Status code was not 200"
return
self.datasource = homeDatasource
self.collectionView?.reloadData()
override func viewDidLoad()
super.viewDidLoad()
view.addSubview(errorMessageLabel)
errorMessageLabel.fillSuperview() //LBTA method call
collectionView?.backgroundColor = UIColor(r: 232, g: 236, b: 241)
setupNavigationBarItems()
Service.sharedInstance.fetchHomeFeed (homeDatasource, err) in
if let err = err
self.errorMessageLabel.isHidden = false
if let apiError = err as? APIError<Service.JSONError>
if apiError.response?.statusCode != 200
self.errorMessageLabel.text = "Status code was not 200"
return
self.datasource = homeDatasource
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat
return 0
override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize
//first section of users
if indexPath.section == 0
guard let user = self.datasource?.item(indexPath) as? User else return .zero
let estimatedHeight = estimatedHeightForText(user.bioText)
return CGSize(width: view.frame.width, height: estimatedHeight + 66)
else if indexPath.section == 1
//our tweets size estimation
guard let tweet = datasource?.item(indexPath) as? Tweet else return .zero
let estimatedHeight = estimatedHeightForText(tweet.message)
return CGSize(width: view.frame.width, height: estimatedHeight + 74)
return CGSize(width: view.frame.width, height: 200)
private func estimatedHeightForText(_ text: String) -> CGFloat
let approximateWidthOfBioTextView = view.frame.width - 12 - 50 - 12 - 2
let size = CGSize(width: approximateWidthOfBioTextView, height: 1000)
let attributes = [NSFontAttributeName: UIFont.systemFont(ofSize: 15)]
let estimatedFrame = NSString(string: text).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil)
return estimatedFrame.height
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
if section == 1
return .zero
return CGSize(width: view.frame.width, height: 50)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize
if section == 1
return .zero
return CGSize(width: view.frame.width, height: 64)
DataSource
import LBTAComponents
import TRON
import SwiftyJSON
extension Collection where Iterator.Element == JSON
func decode<T: JSONDecodable>() throws -> [T]
return try maptry T(json: $0)
class HomeDatasource: Datasource, JSONDecodable
let users: [User]
required init(json: JSON) throws
guard let usersJsonArray = json["users"].array, let tweetsJsonArray = json["tweets"].array else
throw NSError(domain: "com.letsbuildthatapp", code: 1, userInfo: [NSLocalizedDescriptionKey: "Parsing JSON was not valid."])
// self.users = usersJsonArray.mapUser(json: $0)
// self.tweets = tweetsJsonArray.mapTweet(json: $0)
self.users = try usersJsonArray.decode()
self.tweets = try tweetsJsonArray.decode()
let tweets: [Tweet]
override func footerClasses() -> [DatasourceCell.Type]?
return [UserFooter.self]
override func headerClasses() -> [DatasourceCell.Type]?
return [UserHeader.self]
override func cellClasses() -> [DatasourceCell.Type]
return [UserCell.self, TweetCell.self]
override func item(_ indexPath: IndexPath) -> Any?
if indexPath.section == 1
return tweets[indexPath.item]
return users[indexPath.item]
override func numberOfSections() -> Int
return 2
override func numberOfItems(_ section: Int) -> Int
if section == 1
return tweets.count
return users.count
DataCell
import LBTAComponents
class UserCell: DatasourceCell
override var datasourceItem: Any?
didSet
guard let user = datasourceItem as? User else return
followButton.addTarget(self, action: #selector(follow), for: .touchUpInside)
nameLabel.text = user.name
usernameLabel.text = user.username
bioTextView.text = user.bioText
profileImageView.loadImage(urlString: user.profileImageUrl)
let profileImageView: CachedImageView =
let imageView = CachedImageView()
imageView.image = #imageLiteral(resourceName: "profile_image")
imageView.layer.cornerRadius = 5
imageView.clipsToBounds = true
return imageView
()
let nameLabel: UILabel =
let label = UILabel()
label.text = "Brian Voong"
label.font = UIFont.boldSystemFont(ofSize: 16)
return label
()
let usernameLabel: UILabel =
let label = UILabel()
label.text = "@buildthatapp"
label.font = UIFont.systemFont(ofSize: 14)
label.textColor = UIColor(r: 130, g: 130, b: 130)
return label
()
let bioTextView: UITextView =
let textView = UITextView()
textView.text = "iPhone, iPad, iOS Programming Community. Join us to learn Swift, Objective-C and build iOS apps!"
textView.font = UIFont.systemFont(ofSize: 15)
textView.backgroundColor = .clear
return textView
()
let followButton: UIButton =
let button = UIButton()
button.layer.cornerRadius = 5
button.layer.borderColor = twitterBlue.cgColor
button.layer.borderWidth = 1
button.setTitle("Follow", for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
button.setTitleColor(twitterBlue, for: .normal)
button.setImage(#imageLiteral(resourceName: "follow"), for: .normal)
button.imageView?.contentMode = .scaleAspectFit
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 0)
// button.titleEdgeInsets = UIEdgeInsets
return button
()
func follow()
print("inside source")
var link = HomeDatasourceController()
link.follow()
override func setupViews()
super.setupViews()
backgroundColor = .white
separatorLineView.isHidden = false
separatorLineView.backgroundColor = UIColor(r: 230, g: 230, b: 230)
addSubview(profileImageView)
addSubview(nameLabel)
addSubview(usernameLabel)
addSubview(bioTextView)
addSubview(followButton)
profileImageView.anchor(self.topAnchor, left: self.leftAnchor, bottom: nil, right: nil, topConstant: 12, leftConstant: 12, bottomConstant: 0, rightConstant: 0, widthConstant: 50, heightConstant: 50)
nameLabel.anchor(profileImageView.topAnchor, left: profileImageView.rightAnchor, bottom: nil, right: followButton.leftAnchor, topConstant: 0, leftConstant: 8, bottomConstant: 0, rightConstant: 12, widthConstant: 0, heightConstant: 20)
usernameLabel.anchor(nameLabel.bottomAnchor, left: nameLabel.leftAnchor, bottom: nil, right: nameLabel.rightAnchor, topConstant: 0, leftConstant: 0, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 20)
bioTextView.anchor(usernameLabel.bottomAnchor, left: usernameLabel.leftAnchor, bottom: self.bottomAnchor, right: self.rightAnchor, topConstant: -4, leftConstant: -4, bottomConstant: 0, rightConstant: 0, widthConstant: 0, heightConstant: 0)
followButton.anchor(topAnchor, left: nil, bottom: nil, right: self.rightAnchor, topConstant: 12, leftConstant: 0, bottomConstant: 0, rightConstant: 12, widthConstant: 120, heightConstant: 34)
It using LBTA components.i tried self.collectionView?.reloadData()
but its not reloaded. Please help me to fix this problem.download my full source code here Please help me
self.collectionView?.reloadData()
@rmaddy after
self.datasource = homeDatasource
but it not reload see my complete code.– Gamsh
Mar 2 '18 at 18:04
self.datasource = homeDatasource
You need to post relevant code in your question.
– rmaddy
Mar 2 '18 at 18:04
I share the full source code. yo can find with this link "drive.google.com/file/d/1Mt4McHSy1naotrYg6G1axaz6nCEzqyY-/…"
– Gamsh
Mar 2 '18 at 18:09
The preview link isn't working properly, but I'm assuming your reloadData code is outside your async block thus the failure to reload. As rmaddy said, you really need to post all the relevant code here.
– Lyndsey Scott
Mar 2 '18 at 18:26
1 Answer
1
I have seen your project and found issue which you did.
In class UserCell.swift, you should use next code:
func follow()
print("inside source")
guard let link = controller as? HomeDatasourceController else return
link.follow()
Explain issue
This's your code that was in project
func follow()
print("inside source")
var link = HomeDatasourceController() // in this place you create a new local instance of class 'HomeDatasourceController'
link.follow()
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy
Where's your attempt to reload the collection view?
– rmaddy
Mar 2 '18 at 17:55