my table has 03 sections, 1) has no row, 2) has no row 3) has 04 segcons.
when segcon changed then the data changes then reload the section 03. the issue is when the data is not fill the screen then the table moves down automatically. what i want is, the table will not move down automatically eventhough the data is not enough to fill the screen.
i try to use the footer but no help
self.tableView.tableFooterView = UIView()
see here for more detail
https://youtu.be/40IqAh42nxM
media segcon
let mediaCell: MediaCell = tableView.dequeueReusableCell(withIdentifier: "mediaCell", for: indexPath) as! MediaCell
mediaCell.showImage(url: self.photoNsurlArray[indexPath.row]!)
mediaCell.reportButtonProgram.addTarget(self, action: #selector(self.funcToHandleReportButton), for: .touchUpInside)
let timestampe = funcConvertEpocTimeToDate(timeData: self.timestampsGlobal, atIndex: indexPath.row)
mediaCell.timestampLabel.text = "\(timestampe)"
let uid = self.uidkeys[indexPath.row]!
Utils.getUserDetail(uid: uid) { (user) in
let displayName = user?[Constants.User.display_name] as? String
if let name = displayName,!(displayName?.isEmpty)! {
mediaCell.timestampLabel.text = "by " + "\(name) on " + "\(timestampe)"
}
print("getUserDetail display name: ", displayName)
}
returnCell = mediaCell
near segcon
let locationcell: LocationCellDesign = tableView.dequeueReusableCell(withIdentifier: "locationCellDesign", for: indexPath) as! LocationCellDesign
let elementOfLocations = self.nearlocations[indexPath.row]!
print("***elementOfLocations \(String(describing: elementOfLocations))")
let locationDescriptionText = "\(String(describing: elementOfLocations["description"]!))"
if locationDescriptionText.characters.count != 0 {
locationcell.descriptionLabel.text = locationDescriptionText
} else {
locationcell.descriptionLabel.text = "No Description"
}
locationcell.address.text = "\(String(describing: elementOfLocations["address"]!))"
let ownerID = "\(String(describing: elementOfLocations["owner"]!))"
if ownerID == "ApperSystem" {
locationcell.owner.text = "Owner: " + "ApperSystem"
} else {
Utils.getOwnerDetail(uid: ownerID) { (user) -> Void in
let userProperties = user!
let userDisplayName = userProperties["displayName"] as! String
locationcell.owner.text = "Owner: " + userDisplayName
}
}
let userArray = elementOfLocations["users"]! as! [String]
locationcell.users.text = "Users: " + "\(String(describing: userArray.count))"
locationcell.nearLocationAvatarImageView.image = UIImage(named: "no-image")
if elementOfLocations[Constants.LocationDataFields.media_urls] != nil {
let avatarForLocation = elementOfLocations[Constants.LocationDataFields.media_urls] as! NSDictionary
let numberOfPitureInLocation = avatarForLocation.allKeys(for: 1).sorted { ($0 as! String) < ($1 as! String) }
if numberOfPitureInLocation.count > 0 {
Utils.loadImageFromFireBase(key: numberOfPitureInLocation.last! as! String) { (string) -> Void in
print("***loadImageFromFireBase string: \(String(describing: string))")
if let imageUrlString = string, !(string?.isEmpty)! {
let imageUrl:NSURL = NSURL(string: imageUrlString)!
locationcell.nearLocationAvatarImageView.sd_setImage(with: imageUrl as URL)
} else {
print("***loadImageFromFireBase mediaKey has no mediaUrl")
}
}
}
}
returnCell = locationcell
Related
I have tableview in which there is list item and every cell possess a button, I want to fix the text and color of the button based on a boolean value retrieved from firestore, every cell's button have certain text and color based on that value only, I know the syntax to set the text and color for the button in swift, I am just not able to do on the basis of the value from the firestore, below is the code
code for retrieving the list, concerned value is checkl1value
func getComments() {
//print(postId + "received")
let commentsRef = Firestore.firestore().collection("posts").document(postId).collection("comments")
commentsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
let data = document.data()
let username = data["comment_author_username"] as? String ?? ""
let comment = data["comment_author_comment"] as? String ?? ""
let spinnerC = data["comment_author_spinnerC"] as? String ?? ""
let fullname = data["comment_author_fullname"] as? String ?? ""
let email = data["comment_author_email"] as? String ?? ""
let commentUserImageUrl = data["comment_user_image"] as? String ?? ""
let commentuser_id = data["comment_author_id"] as? String ?? ""
self.checkl1value = data["l1"] as? DarwinBoolean
let newComment = Comment(_documentId: document.documentID, _commentAuthorUsername: username, _commentAuthorFullName: fullname, _commentAuthorComment: comment, _commentUserImage: commentUserImageUrl, _commentAuthorSpinnerC: spinnerC, _commentAuthorId:commentuser_id )
self.comments.append(newComment)
}
self.tableView.reloadData()
}
}
}
}
Code for cellForRowAt
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentCell
cell.commentLikebutton.tag = indexPath.row
cell.commentLikebutton.addTarget(self, action: #selector(likeaction1(_:)), for: .touchUpInside)
if checkl1value == true {
cell.commentLikebutton.setTitle("Text1", for: .normal)
// cell.commentLikebutton.backgroundColor = UIColor(red: 17.0/255.0, green: 119.0/255.0, blue: 151.0/255.0, alpha: 1.0)
cell.commentLikebutton.backgroundColor = UIColor.red
//cell.commentLikebutton.backgroundColor = UIColor?.red()
}
else{
cell.commentLikebutton.setTitle("Text2", for: .normal)
}
cell.set(comment: comments[indexPath.row])
return cell
}
Add something like this on the top of cellForRowAt
let thisComment = self.comments[indexPath.row]
let checkl1value = thisComment.checkl1value
I think the error is that your checkl1Value always get changed with the value of the last item in the array. You can do something like this:
var booleanValues = [DarwinBoolean]()
func getComments() {
let commentsRef = Firestore.firestore().collection("posts").document(postId).collection("comments")
commentsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
let data = document.data()
let username = data["comment_author_username"] as? String ?? ""
let comment = data["comment_author_comment"] as? String ?? ""
let spinnerC = data["comment_author_spinnerC"] as? String ?? ""
let fullname = data["comment_author_fullname"] as? String ?? ""
let email = data["comment_author_email"] as? String ?? ""
let commentUserImageUrl = data["comment_user_image"] as? String ?? ""
let commentuser_id = data["comment_author_id"] as? String ?? ""
// self.checkl1value = data["l1"] as? DarwinBoolean
booleanValues.append(data["l1"] as? DarwinBoolean ?? false)
let newComment = Comment(_documentId: document.documentID, _commentAuthorUsername: username, _commentAuthorFullName: fullname, _commentAuthorComment: comment, _commentUserImage: commentUserImageUrl, _commentAuthorSpinnerC: spinnerC, _commentAuthorId:commentuser_id )
self.comments.append(newComment)
}
self.tableView.reloadData()
}
}
}
}
CellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CommentCell", for: indexPath) as! CommentCell
cell.commentLikebutton.tag = indexPath.row
cell.commentLikebutton.addTarget(self, action: #selector(likeaction1(_:)), for: .touchUpInside)
if booleanValues[indexPath.row] {
cell.commentLikebutton.setTitle("Text1", for: .normal)
// cell.commentLikebutton.backgroundColor = UIColor(red: 17.0/255.0, green: 119.0/255.0, blue: 151.0/255.0, alpha: 1.0)
cell.commentLikebutton.backgroundColor = UIColor.red
//cell.commentLikebutton.backgroundColor = UIColor?.red()
} else {
cell.commentLikebutton.setTitle("Text2", for: .normal)
}
cell.set(comment: comments[indexPath.row])
return cell
}
“I’m using segment control and I have two segments, one segment(Recipes) and second segment(Restaurant) click i should click first segment and data show first-array and second segment click second segment and data show secondary”
var dataArray = [FollowedData]()
var restdataArray = [RestaurantFollowed]()
#IBAction func btnActionSegmnet(_ sender: UISegmentedControl) {
switch (segmentSelect.selectedSegmentIndex) {
case 0:
dataArray.removeAll()
ShowPostRecipesData()
tableView.reloadData()
break
case 1:
restdataArray.removeAll()
ShowPostRestaurantsData()
tableView.reloadData()
break
default:
break
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch (segmentSelect.selectedSegmentIndex) {
case 0:
return dataArray.count
case 1:
return restdataArray.count
default:
return 0
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 430
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "FollowedCell")as! FollowedCell
switch (segmentSelect.selectedSegmentIndex)
case 0:
cell.tittleLbl.text = dataArray[indexPath.row].postDetailsData.title
cell.descriptionLbl.text = dataArray[indexPath.row].postDetailsData.descriptions
let date = getDateFromTime(timeStanp: dataArray[indexPath.row].mbersdata.created)
cell.showDateLbl.text = date + "/ " + dataArray[indexPath.row].postDetailsData.viewscount + "views "
let urlString = "https://myfoodtalk.com:3001/storage/posts/\(dataArray[indexPath.row].postDetailsData.image1)"
let escapedString1 = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedString1!)
if let imgurls = URL(string: escapedString1!) {
print(imgurls)
cell.recipesImage.sd_setImage(with:imgurls, placeholderImage: UIImage(named:"placeholder"))
}
let urlStrings = "https://myfoodtalk.com:3001/storage/members/\(dataArray[indexPath.row].mbersdata.photo)"
let escapedStrings = urlStrings.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedStrings!)
if let imgurl = URL(string: escapedStrings!) {
print(imgurl)
cell.userImage.sd_setImage(with:imgurl, placeholderImage: UIImage(named:"placeholder"))
}
break
case 1:
cell.tittleLbl.text = restdataArray[indexPath.row].restaurantDetailsData.title
cell.descriptionLbl.text = restdataArray[indexPath.row].restaurantDetailsData.descriptions
let dates = getDateFromTime(timeStanp: restdataArray[indexPath.row].created)
cell.showDateLbl.text = dates + "/ " + restdataArray[indexPath.row].restaurantDetailsData.viewscount + "views "
let urls = "https://myfoodtalk.com:3001/storage/members/\(restdataArray[indexPath.row].mbersdata.photo)"
let escapedString2 = urls.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedString2!)
if let imgurls = URL(string: escapedString2!) {
print(imgurls)
cell.userImage.sd_setImage(with:imgurls, placeholderImage: UIImage(named:"placeholder"))
}
let url = "https://myfoodtalk.com:3001/storage/restaurants/\(restdataArray[indexPath.row].restaurantDetailsData.image1)"
let escapedStrings3 = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedStrings3!)
if let imgurl = URL(string: escapedStrings3!) {
print(imgurl)
cell.recipesImage.sd_setImage(with:imgurl, placeholderImage: UIImage(named:"placeholder"))
}
break
default:
break
}
return cell
}
func ShowPostRecipesData(){
let accessToken = UserDefaults.standard.value(forKey: "access_token")as! String
let userid = UserDefaults.standard.value(forKey: "userId")as! String
var mainString = ""
var url = ""
mainString = """
{"where":{"m_id":"\(userid)"},"include":[{"relation":"posts"},{"relation":"members"}]}
"""
url = "follow-posts?filter=\(mainString)&access_token=\(accessToken)"
let escapedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedString!)
FTHelper.requestGETURLArray(escapedString!, isShowHud: true, headers: nil, success:
{ (response) in
let dataArray = response
if dataArray.isEmpty{
_ = presentAlertWithOptions("", message: "You have no recipes data ", controller: self, buttons: ["OK"], tapBlock:
{
(UIAlertAction, position) in
if position == 0{
}
})
}else{
let followObj = FollowedData()
self.dataArray = followObj.getfollowData(dataArray: dataArray)
self.tableView.reloadData()
}
})
{ (error) in
print(error)
}
}
func ShowPostRestaurantsData(){
let accessToken = UserDefaults.standard.value(forKey: "access_token")as! String
let mid = UserDefaults.standard.value(forKey: "userId")as! String
var mainString = ""
var url = ""
mainString = """
{"where":{"m_id": "\(mid)"},"include":[{"relation":"restaurants"},{"relation":"members"}]}
"""
url = "follow-restaurants?filter=\(mainString)&access_token=\(accessToken)"
let escapedString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
print(escapedString!)
FTHelper.requestGETURLArray(escapedString!, isShowHud: true, headers: nil, success:
{ (response) in
let dataArray = response
if dataArray.isEmpty{
_ = presentAlertWithOptions("", message: "You have no recipes data ", controller: self, buttons: ["OK"], tapBlock:
{
(UIAlertAction, position) in
if position == 0{
}
})
}else{
let followObj = RestaurantFollowed()
self.restdataArray = followObj.getfollowData(dataArray: dataArray)
self.tableView.reloadData()
}
})
{ (error) in
print(error)
}
}
I am click first segment data show on tableview but I am click on second segment but data not show in tableview I can not understand what I can do
I tried to update TableView cell when click cell from CollectionView with key word of class.
For example, when I click "all", it should perform all data.
When I click "a", it should perform class with "a".
It looks like all perfect until I scroll down TableView.
All data display which is not my intension, it should only show specify data even scroll up/down TableView.
Is it related to dequeueReusableCell issue?
I use FMDB to query data when click CollectionView cell.
I attach gif
and hope it could be better to understand my problem.
Can someone help me out with this please? Thanks.
add cellForRow function here.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath) as! ListTableViewCell
if navigationItem.searchController?.isActive == true{
cell.itemImage.image = searchArray[indexPath.row].thumbnailImage()
cell.nameLBL.text = "name:\(searchArray[indexPath.row].name ?? "")"
cell.quantityLBL.text = "Qty:\(searchArray[indexPath.row].quantity ?? 0)pcs"
cell.amountLBL.text = "amount:\(searchArray[indexPath.row].amount ?? 0)"
cell.dateLBL.text = "date:\(searchArray[indexPath.row].date ?? "")"
cell.storeLBL.text = "store:\(searchArray[indexPath.row].store ?? "")"
cell.classLBL.text = "class:\(searchArray[indexPath.row].itemClass ?? "")"
if let reminder = searchArray[indexPath.row].reminder {
let reminderText = ""
cell.reminderLBL.text = "\(reminder)" + reminderText
reminderStatus = true
}else{
cell.reminderLBL.text = "reminder:NO"
if self.array[indexPath.row].reminder == nil{
cell.reminderLBL.text = "reminder:NO"
}
reminderStatus = false
}
}else{
cell.itemImage.image = array[indexPath.row].thumbnailImage()
cell.nameLBL.text = "name:\(array[indexPath.row].name ?? "")"
cell.quantityLBL.text = "Qty:\(array[indexPath.row].quantity ?? 0)pcs"
cell.amountLBL.text = "amount:\(array[indexPath.row].amount ?? 0)"
cell.dateLBL.text = "date:\(array[indexPath.row].date ?? "")"
cell.storeLBL.text = "store:\(array[indexPath.row].store ?? "")"
cell.classLBL.text = "class:\(array[indexPath.row].itemClass ?? "")"
if let reminder = array[indexPath.row].reminder {
let reminderText = ""
cell.reminderLBL.text = "\(reminder)" + reminderText
reminderStatus = true
}else{
cell.reminderLBL.text = "reminder:NO"
if self.array[indexPath.row].reminder == nil{
cell.reminderLBL.text = "reminder:NO"
}
reminderStatus = false
}
print(array.count)
}
return cell
}
add didSelectItemAt function here.
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
switch indexPath.row {
case 0:
reloadTableViewAndDatabase()
case 1:
reloadTableViewAndDatabase(itemClass: searchStringOfDaily)
case 2:
reloadTableViewAndDatabase(itemClass: searchStringOfCare)
case 3:
reloadTableViewAndDatabase(itemClass: searchStringOfCosmetic)
default:
reloadTableViewAndDatabase()
}
}
And function which may be factor.
let searchStringOfDaily = "SELECT * FROM Data where itemClass = 'a';"
let searchStringOfCare = "SELECT * FROM Data where itemClass = 'b';"
let searchStringOfCosmetic = "SELECT * FROM Data where itemClass = 'c';"
func reloadTableViewAndDatabase()
{
self.dbHelper.searchAllDataFromDatabase { (dataArray) in
self.array = dataArray
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
func reloadTableViewAndDatabase(itemClass:String)
{
self.dbHelper.searchDataFromDatabase(completionHandler: { (dataArray) in
self.array = dataArray
DispatchQueue.main.async {
self.tableView.reloadData()
}
}, search: itemClass)
}
public func searchDataFromDatabase(completionHandler:([Data]) -> (),search:String) {
var searchResultArray:[Data] = []
if self.database == nil{
self.database = FMDatabase(path: self.databasePath)
}
if self.database.open(){
let searchString = search
do{
let resultNext = try self.database.executeQuery(searchString, values: nil)
while resultNext.next(){
let dataName = resultNext.string(forColumn: "name")
let dataQuantity = resultNext.int(forColumn: "quantity")
let dataAmount = resultNext.int(forColumn: "amount")
let dataDate = resultNext.string(forColumn: "date")
let dataStore = resultNext.string(forColumn: "store")
let dataImageName = resultNext.string(forColumn: "imageName")
let dataItemClass = resultNext.string(forColumn: "itemClass")
let dataReminder = resultNext.string(forColumn: "reminder")
let data = Data(name: dataName!, quantity: Int(dataQuantity), amount: Int(dataAmount), date: dataDate!, store: dataStore!, imageName: dataImageName ?? "", reminder: Int(dataReminder!), itemClass: dataItemClass!)
searchResultArray.append(data)
}
print("query success")
}catch{
print(error.localizedDescription)
}
self.database.close()
}
completionHandler(searchResultArray)
}
I have a segmented control with 2 segments ONC and OFC, if I change color of row1 under ONC, it is changing color of row1 in OFC as well. I like to change text color to green for an event, if eventStatus = 1, and red if the eventStatus = 2. This is what I have done so far
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
let eventDesc = NSEntityDescription.insertNewObject(forEntityName: "EventDec", into: context) as! EventDec
var eventSchOnc: EventScheduleOnc?
var eventSchOfc: EventScheduleOfc?
do {
switch (eventSegCtrl.selectedSegmentIndex)
{
case 0:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EventScheduleOnc")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "eventNameOnc == %#", self.oncEvents[indexPath.row] as String)
var objects: [EventScheduleOnc]
try objects = context.fetch(fetchRequest) as! [EventScheduleOnc]
eventSchOnc = objects[0] as EventScheduleOnc
break
case 1:
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "EventScheduleOfc")
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: "eventNameOfc == %#", self.ofcEvents[indexPath.row] as String)
var objects: [EventScheduleOfc]
try objects = context.fetch(fetchRequest) as! [EventScheduleOfc]
eventSchOfc = objects[0] as EventScheduleOfc
break
default:break
}
}
catch {
print("Try Again")
}
eventDesc.setValue(eventSchOnc, forKey: "eventScheduleOnc")
eventDesc.setValue(eventSchOfc, forKey: "eventScheduleOfc")
let alert = UIAlertController(title: "title", message: "msg", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "yes", style: .default) { _ in
eventDesc.setValue(1, forKey: "eventStatus")
do {
try context.save()
} catch{
print("Try again")
}
})
alert.addAction(UIAlertAction(title: "no", style: .default) { _ in
eventDesc.setValue(2, forKey: "eventStatus")
do {
try context.save()
} catch {
print("Try again")
}
})
present(alert, animated: true, completion: nil)
let myEventCell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! EventTableViewCell
let eventDescOnc = self.eventScheduleOnc[indexPath.row].eventDecOnc
let eventOnc = eventDescOnc?.eventStatus
if (eventOnc == 1) {
myEventCell.eventLabel.textColor = UIColor.green
}
else if (eventOnc == 2){
myEventCell.eventLabel.textColor = UIColor.red
}
let eventDescOfc = self.eventScheduleOfc[indexPath.row].eventDecOfc
let eventOfc = eventDescOfc?.eventStatus
if (eventOfc == 1) {
myEventCell.eventLabel.textColor = UIColor.green
}
else if (eventOfc == 2) {
myEventCell.eventLabel.textColor = UIColor.red
}
}
How do I display right text colors according to eventStatus under each segment?
Instead of using String array used array of EventScheduleOfc and EventScheduleONc and after you set eventStatus of EventDesc in didSelectRowAt simply reload the tableView.
private func eventDataOnc(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "EventScheduleOnc")
request.returnsObjectsAsFaults = false
do
{
self.eventScheduleOnc = try context.fetch(request) as! [EventScheduleOnc]
}
catch{}
}
private func eventDataOfc(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "EventScheduleOfc")
request.returnsObjectsAsFaults = false
do
{
self.eventScheduleOfc = try context.fetch(request) as! [EventScheduleOfc]
}
catch{}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
let myEventCell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! EventTableViewCell
if eventSegCtrl.selectedSegmentIndex == 0 {
myEventCell.eventLabel.text = self.eventScheduleOnc[indexPath.row].eventNameOnc
if let eventDesc = self.eventScheduleOnc[indexPath.row].eventDec,
let eventStatus = eventDesc.eventStatus {
if eventStatus == 1 {
myEventCell.eventLabel.textColor = UIColor.green
}
else {
myEventCell.eventLabel.textColor = UIColor.red
}
}
else {
myEventCell.eventLabel.textColor = UIColor.black
}
}
else {
myEventCell.eventLabel.text = self.eventScheduleOfc[indexPath.row].eventNameOfc
if let eventDesc = self.eventScheduleOfc[indexPath.row].eventDec,
let eventStatus = eventDesc.eventStatus {
if eventStatus == 1 {
myEventCell.eventLabel.textColor = UIColor.green
}
else {
myEventCell.eventLabel.textColor = UIColor.red
}
}
else {
myEventCell.eventLabel.textColor = UIColor.black
}
}
return myEventCell
}
Now in didSelect simply set the value in core data and then instead of setting textColor of label simply reload the tableView.
I'm making an social media apps.
user
- displayname
- username
- profileImg
- password
- email
comments
- username
- comment
- to
friends
- follower
- following
hashtags
- hashtag
- to
- by
- comment
likes
- to
- by
posts
- postImg
- username
- title
- uuid
My question is when USERS post the image with title text then
I want retrieve username, profileImg, title, comment, commentby, postImg, count of likes
My approach is redesign the posts db
posts
- postImg
- username
- title
- uuid
- comment
- commentby
- profileImg
- count of likes
But I think it is poor design of db.
func loadPosts() {
//STEP 1. Find posts related to people who we are following
let followQuery = PFQuery(className: “friends")
followQuery.whereKey(“following", equalTo: PFUser.current()!.username!)
followQuery.findObjectsInBackground (block: { (objects:[PFObject]?, error:Error?) -> Void in
if error == nil {
//clean up
self.followArray.removeAll(keepingCapacity: false)
//Appending where people following..
//find related objects
for object in objects! {
self.followArray.append(object.object(forKey: “following") as! String)
}
//append current user to see own posts in feed
self.followArray.append(PFUser.current()!.username!)
//STEP 2. Find posts made by people appended to followArray
let query = PFQuery(className: "posts")
query.whereKey("username", containedIn: self.followArray)
query.limit = self.page
query.addDescendingOrder("createdAt")
query.findObjectsInBackground(block: { (objects:[PFObject]?, error:Error?) -> Void in
if error == nil {
//clean up
self.usernameArray.removeAll(keepingCapacity: false)
// self.profileArray.removeAll(keepCapacity: false)
self.dateArray.removeAll(keepingCapacity: false)
self.postArray.removeAll(keepingCapacity: false)
self.descriptionArray.removeAll(keepingCapacity: false)
self.uuidArray.removeAll(keepingCapacity: false)
self.commentsArray.removeAll(keepingCapacity: false)
self.commentsByArray.removeAll(keepingCapacity: false)
//find related objects
for object in objects! {
self.usernameArray.append(object.object(forKey: "username") as! String)
// self.profileArray.append(object.objectForKey("profileImg") as! PFFile)
self.dateArray.append(object.createdAt)
self.postArray.append(object.object(forKey: "postImg") as! PFFile)
self.descriptionArray.append(object.object(forKey: "title") as! String)
self.uuidArray.append(object.object(forKey: "uuid") as! String)
//set Comments
let comment = object.object(forKey: "comment") as! String
let by = object.object(forKey: "commentby") as! String
let commentString = " " + comment
self.commentsByArray.append(by)
self.commentsArray.append(commentString)
}
//reload tableView & end spinning of refresher
self.tableView.reloadData()
self.refresher.endRefreshing()
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
})
}
defined cell
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//define cell
let cell = tableView.dequeueReusableCell(withIdentifier: "ShopDetailCell", for: indexPath) as! ShopDetailCell
cell.userNameLabel.text = usernameArray[(indexPath as NSIndexPath).row - 1]
cell.userNameLabel.sizeToFit()
cell.uuidLabel.text = uuidArray[(indexPath as NSIndexPath).row - 1]
cell.descriptionLabel.text = descriptionArray[indexPath.row - 1]
cell.descriptionLabel.sizeToFit()
cell.commentLabel.sizeToFit()
//Load ProfileImage
let profileImgQuery = PFQuery(className: "_User")
profileImgQuery.whereKey("username", equalTo: usernameArray[(indexPath as NSIndexPath).row - 1])
profileImgQuery.findObjectsInBackground(block: {(objects:[PFObject]?, error:Error?) -> Void in
if error == nil {
//shown wrong user
if objects!.isEmpty {
print("Wrong User")
}
//find related to user information
for object in objects! {
//Set Image
let profilePictureObject = object.object(forKey: "profileImg") as? PFFile
profilePictureObject?.getDataInBackground { (imageData:Data?, error:Error?) -> Void in
if(imageData != nil)
{
let profileURL : URL = URL(string: profilePictureObject!.url!)!
cell.userImg.sd_setImage(with: profileURL, placeholderImage: UIImage(named: "holderImg"))
}
}
}
} else {
print(error?.localizedDescription)
}
})
//Clip to circle
cell.userImg.layoutIfNeeded()
cell.userImg.layer.cornerRadius = cell.userImg.frame.size.width/2
cell.userImg.clipsToBounds = true
// place post picture using the sdwebimage
let postURL : URL = URL(string: postArray[(indexPath as NSIndexPath).row - 1].url!)!
cell.postImg.sd_setImage(with: postURL, placeholderImage: UIImage(named: "holderImg"))
//Calculate post date
let from = dateArray[(indexPath as NSIndexPath).row - 1]
let now = Date()
let components : NSCalendar.Unit = [.second, .minute, .hour, .day, .weekOfMonth]
let difference = (Calendar.current as NSCalendar).components(components, from: from!, to: now, options: [])
// logic what to show : Seconds, minutes, hours, days, or weeks
if difference.second! <= 0 {
cell.dateLabel.text = "NOW"
}
if difference.second! > 0 && difference.minute! == 0 {
cell.dateLabel.text = "\(difference.second!) SEC AGO"
}
if difference.minute! > 0 && difference.hour! == 0 {
cell.dateLabel.text = "\(difference.minute!) MIN AGO"
}
if difference.hour! > 0 && difference.day! == 0 {
cell.dateLabel.text = "\(difference.hour!) HR AGO"
}
if difference.day! > 0 && difference.weekOfMonth! == 0 {
cell.dateLabel.text = "\(difference.day!) DAY AGO"
}
if difference.weekOfMonth! > 0 {
cell.dateLabel.text = "\(difference.weekOfMonth!) WEEK AGO"
}
cell.dateLabel.sizeToFit()
//Set Text Label
if cell.descriptionLabel.text!.isEmpty == true || cell.descriptionLabel.text == " "{
if cell.commentLabel.text!.isEmpty == true || cell.commentLabel.text == " "{
cell.dateTop.constant = 7
}else {
cell.dateTop.constant = cell.commentTop.constant + cell.commentLabel.frame.height + 8
}
}else {
if cell.commentLabel.text!.isEmpty == true || cell.commentLabel.text == " "{
cell.dateTop.constant = cell.descriptionTop.constant + cell.descriptionLabel.frame.height + 8
}else {
cell.commentTop.constant = cell.descriptionTop.constant + cell.descriptionLabel.frame.height + 8
cell.dateTop.constant = cell.commentTop.constant + cell.commentLabel.frame.height + 8
}
}
// manipulate like button depending on did user like it or not
let didLike = PFQuery(className: "likes")
didLike.whereKey("by", equalTo: PFUser.current()!.username!)
didLike.whereKey("to", equalTo: cell.uuidLabel.text!)
didLike.countObjectsInBackground(block: {(count:Int32, error:Error?) -> Void in
//if no any likes are found, else found likes
if count==0 {
cell.likeBtn.setTitle("unlike", for: UIControlState())
cell.likeBtn.setImage(UIImage(named:"heartBtn"), for: UIControlState())
}else{
cell.likeBtn.setTitle("like", for: UIControlState())
cell.likeBtn.setImage(UIImage(named: "heartTapBtn"), for: UIControlState())
}
})
//count total likes of shown post
let countLikes = PFQuery(className: "likes")
countLikes.whereKey("to", equalTo: cell.uuidLabel.text!)
countLikes.countObjectsInBackground(block: {(count:Int32, error:Error?) -> Void in
cell.likesLabel.text="\(count) likes"
})
cell.userNameLabel.layer.setValue(indexPath, forKey: "index")
cell.commentBtn.layer.setValue(indexPath, forKey: "index")
cell.moreBtn.layer.setValue(indexPath, forKey: "index")
return cell
}
Could you anyone advising me?
I had read this tutorial "https://parse.com/tutorials/anypic" but I can't decided which data model is better for me
I wish to uses join or pointer method.
You can save the currentUser as a pointer in your Posts class whenever a user makes a post.
note: I will demonstrate in Objective-C but it's very easy for you to translate into Swift. But if you have trouble reading objc code, I will edit my answer to Swift version.
func post { //make a post
var post = PFObject(className:"Posts")
post["user"] = PFUser.current()//save the current user as a pointer pointing to the User class. You can add a column of type pointer in your parse dashboard inside your Posts class.
//set up other attributes here...
post.saveInBackground()
}
Then when we do the query, we can use includeKey to include the user pointer.
let query = PFQuery(className: "posts")
query.whereKey("username", containedIn: self.followArray)
query.includeKey("user")// THIS IS IMPORTANT
query.limit = self.page
query.addDescendingOrder("createdAt")
query.findObjectsInBackground(block: { (objects:[PFObject]?, error:Error?) -> Void in
if !error {
//we can access the user pointer by doing:
for object in objects {
var user = object["user"]
var username = user.username
var profileImage = user["profileImg"] //a PFFile
//...
}
}
Besides, you can always use a PFQueryTableViewController to load the objects for you, so you don't need to store the query results manually.