我是新手。我使用LTBA components来构建swift应用程序。我按照一些教程来开发像twitter这样的社交应用程序。我开始实现按钮功能。它调用另一个API调用,但相同的响应带有微小的修改(例如,跟随者属性的数量增加一个)。打电话也很完美。但是集合视图没有重新加载。我的代码是。
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)
}
}
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)
}
}
它使用LBTA components.i尝试了self.collectionView?.reloadData()但它没有重新加载。请帮我解决这个问题。请帮我解决这个问题
请注意,您在follow()方法中使用了闭包,因此您需要在主队列中编写用于重新加载的代码。
像这样写下你的重载代码
DispatchQueue.main.async{
self.collectionView.reloadData()
}
尝试为completion handler
方法添加follow
:
func follow(completionHandler: @escaping (Any, NSError?) -> ()){
Service.sharedInstance.fetchfollowHomeFeed { (homeDatasource, err) in
do {
// handle the response from the api call
completionHandler(homeDatasource, nil)
} catch let 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"
}
}
}
}
}
并调用您的方法,如:
self.follow() {homeDatasource,error in
self.collectionView.reloadData()
}