fatal error: Array index out of range. Swift when refresh - swift

Tried so many times to find out what causes the fatal error. But, still can't figure it out. The first table (result table) causes this error when I try to refresh the table with pull. The second table (favoriteProductTableView) works perfect, so I didn't put any code about the second one. Wondering why. Thank you for your help.
var followArray = [String]()
var resultsNameArray = [String]()
var resultsImageFiles = [PFFile?]()
var resultsDetailsArray = [String]()
var resultsDetailsImageFiles = [PFFile?]()
var resultsObjectID = [String]()
var resultsTitle = [String]()
var personPriceArray = [String]()
var personQuantityArray = [String]()
var personOrderTypeArray = [String]()
var refresher:UIRefreshControl!
override func viewDidLoad() {
super.viewDidLoad()
favoriteProductTableView.hidden = true
refresher = UIRefreshControl()
refresher.tintColor = UIColor.blackColor()
refresher.addTarget(self, action: "refresh", forControlEvents: UIControlEvents.ValueChanged)
self.resultsTable.addSubview(refresher)
}
override func viewDidAppear(animated: Bool) {
refreshResults()
}
func refresh(){
refreshResults()
}
func refreshResults(){
switch(segmentedControl.selectedSegmentIndex){
case 0:
followArray.removeAll(keepCapacity: false)
resultsNameArray.removeAll(keepCapacity: false)
resultsImageFiles.removeAll(keepCapacity: false)
resultsDetailsArray.removeAll(keepCapacity: false)
resultsDetailsImageFiles.removeAll(keepCapacity: false)
resultsObjectID.removeAll(keepCapacity: false)
resultsTitle.removeAll(keepCapacity: false)
personPriceArray.removeAll(keepCapacity: false)
personQuantityArray.removeAll(keepCapacity: false)
personOrderTypeArray.removeAll(keepCapacity: false)
let followQuery = PFQuery(className: "follow")
followQuery.whereKey("user", equalTo: (PFUser.currentUser()!.username)!)
followQuery.whereKey("userToFollow", notEqualTo: (PFUser.currentUser()!.username)!)
followQuery.findObjectsInBackgroundWithBlock { (objects:[PFObject]?, error: NSError?) -> Void in
if error != nil {
}
for object in objects! {
self.followArray.append(object.objectForKey("userToFollow") as! String)
}
let query = PFQuery(className: "products")
query.whereKey("userName", containedIn: self.followArray)
query.findObjectsInBackgroundWithBlock { (catchobjects:[PFObject]?, error:NSError?) -> Void in
if error != nil {
}
for catchobject in catchobjects! {
if catchobject.objectForKey("selling_price") != nil {
self.personPriceArray.append(catchobject.objectForKey("selling_price") as! String)
self.personOrderTypeArray.append("Selling")
} else {
self.personPriceArray.append(catchobject.objectForKey("buying_price") as! String)
self.personOrderTypeArray.append("Buying")
}
self.personQuantityArray.append(catchobject.objectForKey("quantity") as! String)
self.resultsNameArray.append(catchobject.objectForKey("unique_username") as! String)
self.resultsImageFiles.append(catchobject.objectForKey("profile_picture") as? PFFile)
self.resultsDetailsArray.append(catchobject.objectForKey("details") as! String)
self.resultsDetailsImageFiles.append(catchobject.objectForKey("detailsImage") as? PFFile)
self.resultsTitle.append(catchobject.objectForKey("title") as! String)
self.resultsObjectID.append(catchobject.objectId!)
}
dispatch_async(dispatch_get_main_queue()) {
self.resultsTable.reloadData()
}
self.loadEmptyLabel(self.resultsTable)
}
self.refresher.endRefreshing()
}
break
case 1:
...
break
default:
break
}
}
func loadEmptyLabel(tableView: UITableView) {
let emptyLabel = UILabel(frame: CGRectMake(0, 0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height))
emptyLabel.textAlignment = NSTextAlignment.Center
emptyLabel.textColor = UIColor.blackColor()
emptyLabel.text = "No matched result found."
tableView.backgroundView = emptyLabel
tableView.separatorStyle = UITableViewCellSeparatorStyle.None
var resultCount = Int()
if tableView == resultsTable {
resultCount = resultsNameArray.count
} else {
resultCount = resultsTitleArray.count
}
if resultCount == 0 {
tableView.reloadData()
emptyLabel.hidden = false
} else {
emptyLabel.hidden = true
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var numRow: Int = 0
switch(segmentedControl.selectedSegmentIndex){
case 0:
numRow = resultsNameArray.count
break
case 1:
numRow = resultsTitleArray.count
break
default:
break
}
return numRow
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if tableView == resultsTable {
let cell:favoritedTableViewCell = resultsTable.dequeueReusableCellWithIdentifier("Cell") as! favoritedTableViewCell
cell.profileLbl.text = self.resultsNameArray[indexPath.row]
cell.messageTxt.text = self.resultsDetailsArray[indexPath.row]
cell.priceLabel.text = "\(self.personOrderTypeArray[indexPath.row]) \(self.personQuantityArray[indexPath.row]) for $\(self.personPriceArray[indexPath.row])"
cell.titleLabel.text = self.resultsTitle[indexPath.row]
if resultsImageFiles[indexPath.row] != nil {
resultsImageFiles[indexPath.row]!.getDataInBackgroundWithBlock { (imageData:NSData?, error:NSError?) -> Void in
if error == nil{
let image = UIImage(data: imageData!)
cell.imgView.image = image
}
}
} else {
cell.imgView.image = UIImage(named: "Profile Picture")
}
if resultsDetailsImageFiles[indexPath.row] != nil{
resultsDetailsImageFiles[indexPath.row]?.getDataInBackgroundWithBlock({ (imageData:NSData?, error:NSError?) -> Void in
if error == nil{
let image = UIImage(data: imageData!)
cell.detailsImg.image = image
}
})
} else {
cell.detailsImg.image = UIImage(named: "Profile Picture")
}
return cell
} else {
....
}
}

Your numberOfRowsInSection function returns one of two array lengths based on segmentedControl.selectedSegmentIndex, whereas cellForRowAtIndexPath indexes the arrays based on the tableView being displayed. This doesn't look right, especially given your referencing `` which doesn't appear to be populated anywhere - should it just be resultsTitle?.
Also, you're calling self.resultsTable.reloadData() from a background thread. This is bad - it must be called from the main thread using:
dispatch_async(dispatch_get_main_queue()) {
self.resultsTable.reloadData()
}
Nevertheless, it's not clear why you've got this inside the loop either.

Related

Firestore chat application displaying messaged users error

I have added chatting/messaging to my application. I can go to a users profile, select message and message them.
I also added a tab that show all the users I messaged which is in a table view and you can click a user and see messages between you and them.
The issue happens when I open this tab to see the users Ive messaged when I've messaged more than 10 users. The simulator crashes and I get this error:
"Thread 1: Exception: "Invalid Query. 'in' filters support a maximum of 10 elements in the value array."
here is my code:
import UIKit
import FirebaseFirestore
class MessagingVC: UIViewController {
#IBOutlet weak var tableView: UITableView! { didSet {
tableView.tableFooterView = UIView()
tableView.contentInset.top = 10
}}
#IBOutlet weak var noDataLabel: UILabel!
private let db = Firestore.firestore()
var users = [AppUser]()
var user: AppUser {
return UserManager.currentUser!
}
private var lastMessageDict: [String: Date]?
private var unreadMessageDict: [String: Bool]?
var chatListener: ListenerRegistration?
override func viewDidLoad() {
super.viewDidLoad()
getChats()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
noDataLabel.isHidden = true
// remove any blocked users when entering the screen.
users.removeAll() { self.user.blockedUsers?.contains($0.uid) == true }
// filter hidden users
users = users.filter { $0.isHidden ?? false == false }
tableView.reloadData()
// getChats()
}
// Get all users id that the current user has been chating with.
func getChats() {
let chatCollection = db.collection("chat")
chatListener = chatCollection.whereField("participants", arrayContains: user.uid).addSnapshotListener { [unowned self] (querySnapshot, error) in
guard error == nil else {
print(error!.localizedDescription)
return
}
var userChatIds = [String]()
self.lastMessageDict = [String: Date]()
self.unreadMessageDict = [String: Bool]()
for chat in querySnapshot?.documents ?? [] {
let chatData = chat.data()
if let participants = chatData["participants"] as? [String] {
for particiant in participants {
if particiant != self.user.uid,
!(self.user.blockedUsers?.contains(particiant) == true),
!userChatIds.contains(particiant) {
userChatIds.append(particiant)
if let lastMessageDate = chatData["last message"] as? Timestamp {
self.lastMessageDict![particiant] = lastMessageDate.dateValue()
}
if let unreadMessageDict = chatData["unread message"] as? [String: Bool],
let unreadMesage = unreadMessageDict[self.user.uid] {
self.unreadMessageDict![particiant] = unreadMesage
}
}
}
}
}
if !userChatIds.isEmpty {
self.getChatsInfo(chatIds: userChatIds)
} else {
self.tableView.reloadData()
self.noDataLabel.isHidden = self.users.count > 0
}
}
}
func getChatsInfo(chatIds: [String]) {
getUsersForChat(chatIds) { (users, error) in
guard error == nil else {
print(error?.localizedDescription ?? "")
return
}
for user in users {
if let index = self.users.firstIndex(of: user) {
self.users[index] = user
} else {
self.users.append(user)
}
}
// self.users = users
self.users.sort { (first, second) -> Bool in
let firstDate = self.lastMessageDict?[first.uid]
let secondDate = self.lastMessageDict?[second.uid]
if firstDate == nil { return false }
else if secondDate == nil { return true }
else {
return firstDate! > secondDate!
}
}
self.users = self.users.filter { $0.isHidden ?? false == false }
self.tableView.reloadData()
self.noDataLabel.isHidden = self.users.count > 0
}
}
func getUsersForChat(_ ids: [String], completion:#escaping (_ users: [AppUser], _ error: Error?)->()) {
var allUsers = [AppUser]()
let allids = self.users.map { $0.uid }
let ids = ids.filter { !allids.contains($0) }
if ids.count == 0 {
completion(allUsers, nil)
return
}
var error: Error?
let userCollection = db.collection("users")
let dispatchGroup = DispatchGroup()
dispatchGroup.enter()
userCollection.whereField("uid", in: ids).getDocuments {querySnapshot,err in
error = err
var users = [AppUser]()
for document in querySnapshot?.documents ?? [] {
if let restaurant = Restaurant(snapshot: document) {
users.append(restaurant)
}
}
allUsers.append(contentsOf: users)
dispatchGroup.leave()
}
dispatchGroup.enter()
let userCollection2 = db.collection("users2")
userCollection2.whereField("uid", in: ids).getDocuments {querySnapshot,err in
error = err
var users = [AppUser]()
for document in querySnapshot?.documents ?? [] {
if let user = AppUser(snapshot: document) {
users.append(user)
}
}
allUsers.append(contentsOf: users)
dispatchGroup.leave()
}
dispatchGroup.notify(queue: DispatchQueue.main) {
completion(allUsers, error)
}
}
deinit {
chatListener?.remove()
}
}
extension MessagingVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessagingTableViewCell
let user = users[indexPath.row]
cell.nameLabel.text = user.firstName + " " + user.lastName
if let unreadMessage = unreadMessageDict?[user.uid],
unreadMessage == true {
cell.unreadMessageIndicatorLabel.isHidden = false
} else {
cell.unreadMessageIndicatorLabel.isHidden = true
}
cell.photoImageView.image = nil
user.getProfileImage { (image) in
DispatchQueue.main.async {
if let cell = tableView.cellForRow(at: indexPath) as? MessagingTableViewCell {
cell.photoImageView.image = image
}
}
}
if let rest = user as? Restaurant {
cell.categoryImageView.image = UIImage(named: rest.Categories1)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let user = users[indexPath.row]
// unreadMessageDict?[user.uid] = false
performSegue(withIdentifier: "messagingToChatSegue", sender: user)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "messagingToChatSegue" {
let chatVC = segue.destination as! ChatViewController
let otherUser = sender as! AppUser
chatVC.currentUser = user
chatVC.otherUser = otherUser
chatVC.channelId = ClickedResturantVC.generateIdForMessages(user1Id: user.uid, user2Id: otherUser.uid)
}
}
}
Here is a picture of the error I am getting
Here is a picture of my Firestore database
The error message is telling you that Firestore doesn't support more than 10 items in the ids array that you pass to this query filter:
userCollection.whereField("uid", in: ids)
According to the documentation for this sort of query:
Note the following limitations for in and array-contains-any:
in and array-contains-any support up to 10 comparison values.
If you need more than 10, you will need to batch them into multiple queries.

swift, Tableview is displayed incorrectly after saving new Data

at first sorry for my bad english.
My problem is that my tableview will be misrepresented as soon as I save a new file in Firebase.
When saving, a new AddViewController is called.
After saving is automatically returned to the TableviewController.
However, if I stop and restart the app so that the TableviewController is recreated, my tableview will be displayed correctly.
I create a header from an array.
Then I create the cell from another array.
I do not understand why my tableview is displayed incorrectly when I return after saving, but when I recreate the view after the app has finished everything is shown correctly.
My sample pictures:
that's right:
that's bad
My Code from TableViewController:
override func viewDidLoad() {
super.viewDidLoad()
refresher = UIRefreshControl()
refresher.attributedTitle = NSAttributedString(string: "Pull to refresh")
refresher.addTarget(self, action: #selector(TagebuchViewController.refresh), for: UIControlEvents.valueChanged)
tableView.addSubview(refresher)
loadTableview()
}
Load data from Firebase, loadTableView():
func loadTableview(){
let userID = Firebase.Auth.auth().currentUser?.uid
databaseRef = Database.database().reference().child("DiabetesIOS").child(userID!)
databaseRef.observe(.value, with: {(snapshot) in
var newItems = [Post]()
var newItemsDate = [String]()
var aNewTime = [String]()
var aNewBl = [String]()
var aNewK = [String]()
var aNewBo = [String]()
var aNewBa = [String]()
var aNewBlu = [String]()
var aNewP = [String]()
var aNewN = [String]()
var dimArrayNewTime = [[String]]()
var dimArrayNewBl = [[String]]()
var dimArrayNewK = [[String]]()
var dimArrayNewBo = [[String]]()
var dimArrayNewBa = [[String]]()
var dimArrayNewBlu = [[String]]()
var dimArrayNewP = [[String]]()
var dimArrayNewN = [[String]]()
for year in snapshot.children.allObjects as! [DataSnapshot] {
for month in year.children.allObjects as! [DataSnapshot] {
for day in month.children.allObjects as! [DataSnapshot] {
for date in day.children.allObjects as! [DataSnapshot] {
for time in date.children.allObjects as! [DataSnapshot] {
let newPost = Post(snapshot: time)
newItems.append(newPost)
let newDate = Post(snapshot: time)
newItemsDate.append(newDate.snap6Date!)
if self.snapshotCheck == 0{
self.snapshotCheckDate = newDate.snap6Date
self.snapshotCheck += 1
}
else{
}
if self.snapshotCheckDate == newDate.snap6Date{
aNewTime.append(newDate.time)
aNewBl.append(newDate.blutzucker)
aNewKe.append(newDate.ke)
aNewBo.append(newDate.bolusInsulin)
aNewBa.append(newDate.basalInsulin)
aNewBlu.append(newDate.blutdruck)
aNewP.append(newDate.puls)
aNewN.append(newDate.notiz)
}
else{
dimArrayNewTime.append(aNewTime)
dimArrayNewBl.append(aNewBlutzucker)
dimArrayNewK.append(aNewKe)
dimArrayNewBo.append(aNewBolusinsulin)
dimArrayNewBa.append(aNewBasalinsulin)
dimArrayNewBlu.append(aNewBlutdruck)
dimArrayNewP.append(aNewPuls)
dimArrayNewN.append(aNewNotiz)
aNewTime.removeAll()
aNewBl.removeAll()
aNewK.removeAll()
aNewBo.removeAll()
aNewBa.removeAll()
aNewBlu.removeAll()
aNewP.removeAll()
aNewN.removeAll()
aNewTime.append(newDate.time)
aNewBl.append(newDate.blutzucker)
aNewK.append(newDate.ke)
aNewBo.append(newDate.bolusInsulin)
aNewBa.append(newDate.basalInsulin)
aNewBlu.append(newDate.blutdruck)
aNewP.append(newDate.puls)
aNewN.append(newDate.notiz)
self.snapshotCheckDate = newDate.snap6Date
}
}
}
}
}
}
self.postArrayValue = newItems
self.aHeaderDate = newItemsDate
self.aHeaderDate = self.uniq(source: self.aHeaderDate)
dimArrayNewTime.append(aNewTime)
dimArrayNewBl.append(aNewBl)
dimArrayNewK.append(aNewK)
dimArrayNewBo.append(aNewBo)
dimArrayNewBa.append(aNewBa)
dimArrayNewBlu.append(aNewBlu)
dimArrayNewP.append(aNewP)
dimArrayNewN.append(aNewN)
self.dimArrayTime = dimArrayNewTime
self.dimArrayBl = dimArrayNewBl
self.dimArrayK = dimArrayNewK
self.dimArrayBo = dimArrayNewBo
self.dimArrayBa = dimArrayNewBa
self.dimArrayBlu = dimArrayNewBlu
self.dimArrayP = dimArrayNewP
self.dimArrayN = dimArrayNewN
newItems.removeAll()
newItemsDate.removeAll()
aNewTime.removeAll()
aNewBl.removeAll()
aNewK.removeAll()
aNewBo.removeAll()
aNewBa.removeAll()
aNewBlu.removeAll()
aNewP.removeAll()
aNewN.removeAll()
dimArrayNewTime.removeAll()
dimArrayNewBl.removeAll()
dimArrayNewK.removeAll()
dimArrayNewBo.removeAll()
dimArrayNewBa.removeAll()
dimArrayNewBlu.removeAll()
dimArrayNewP.removeAll()
dimArrayNewN.removeAll()
self.tableView.reloadData()
}){
(error) in
print(error.localizedDescription)
}
}
For my Header:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let headerView = Bundle.main.loadNibNamed("TableViewCell1", owner: self, options: nil)?.first as! TableViewCell1
headerView.date.text = aHeaderDate[section]
headerView.backgroundColor = UIColor.white
return headerView
}
NumberOfRows:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dimArrayTime[section].count
}
Number of Headers:
override func numberOfSections(in tableView: UITableView) -> Int {
return aHeaderDate.count
}
Number of Cells:
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dimArrayTime[section].count
}
Section:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell2 = Bundle.main.loadNibNamed("TableViewCell2", owner: self, options: nil)?.last as! TableViewCell2
let sectionTime = dimArrayTime[indexPath.section][indexPath.row]
let sectionBl = dimArrayBl[indexPath.section][indexPath.row]
let sectionK = dimArrayK[indexPath.section][indexPath.row]
let sectionBo = dimArrayBo[indexPath.section][indexPath.row]
let sectionBa = dimArrayBa[indexPath.section][indexPath.row]
let sectionBlu = dimArrayBlu[indexPath.section][indexPath.row]
let sectionP = dimArrayP[indexPath.section][indexPath.row]
let sectionN = dimArrayN[indexPath.section][indexPath.row]
cell2.time.text = sectionTime
cell2.bl.text = sectionBl
cell2.k.text = sectionK
cell2.bo.text = sectionBo
cell2.ba.text = sectionBa
cell2.blu.text = sectionBlu
cell2.p.text = sectionP
cell2.n.text = sectionN
return cell2
}
addViewController:
#IBAction func saveInDatabaseFirebase(_ sender: Any) {
let userID = Firebase.Auth.auth().currentUser?.uid
let postRef = dataRef.child("DIOS").child(userID!).child(stringForDbYear).child(stringForDbMonth).child(stringForDbDay).child(stringForDbDate).child(stringForDbTime)
sDate = tFDate.text!
if tFBl.text == "" {
sBl = "-"
}
else{
sBl = tFBl.text!
}
if tFK.text == "" {
sK = "-"
}
else{
sK = tFK.text!
}
if tFBo.text == "" {
sBo = "-"
}
else{
sBo = tFBo.text!
}
if tFBa.text == "" {
sBa = "-"
}
else{
sBa = tFBa.text!
}
if tfBlu.text == "" {
sBlu = "-"
}
else{
sBlu = tfBlu.text!
}
if tFP.text == "" {
sP = "-"
}
else{
sP = tFP.text!
}
if tFN.text == "" {
sN = "-"
}
else{
sN = tFN.text!
}
let post = Post (date: stringForDbDate, time: stringForDbTime, day: stringForDbDay, bl: sBl, k: sK, bo: sBo, ba: sBa, blu: sBlu, p: sP, n: sN, snap1DIOS: "DIOS", snap2UserID: userID!, snap3Year: stringForDbYear, snap4Month: stringForDbMonth, snap5Day: stringForDbDay, snap6Date: stringForDbDate, snap7Time: stringForDbTime)
postRef.setValue(post.toAnyObject())
self.dismiss(animated: true, completion: nil);
}
Thank you very much for help

UICollection View cell not removing at indexpath

I am using collection view for displaying result.I want to delete particular cell when that cell is selected. To keep record of selected cell, i am using struct.Everything is working perfectly. But when i click delete button selected cell are not getting deleted.Some other cell gets deleted. But when i go back to the previous screen and come back again ,the cell which i wanted to be deleted is actually removed. I don't know why and how this is happening?
import UIKit
import GRDBCipher
class AdvisoryViewController:
UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
#IBOutlet weak var new_advisory_label: UILabel!
var getname=String()
var array=[String]()
var date_array=[String]()
var crop_code:String=""
var dbQueue:DatabaseQueue? = nil
var ss = [Int]()
var struct_array :[myObject] = []
var msg_stat:[oldMsg] = []
var msg_count_array=[Int]()
var msg_array=[String]()
var selected_date_array=[String]()
var srno_array=[String]()
var selected_srno_array=[String]()
#IBOutlet weak var collection_view: UICollectionView!
struct myObject
{
var date: String
var advisory:String
var status: String
var srno: String
}
struct oldMsg
{
var is_checked: Bool
}
override func viewDidLoad() {
super.viewDidLoad()
do{
let longpress1=UILongPressGestureRecognizer(target: self, action: #selector(longpress))
// longpress1.minimumPressDuration=1
collection_view.addGestureRecognizer(longpress1)
let
path=NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,
true).first!
dbQueue = try DatabaseQueue(path: "\(path)/pest_messenger.sqlite")
try dbQueue?.inDatabase { db in
let crop_sursor = try Row.fetchCursor(db, "SELECT * FROM crop_master where crop_name='\(getname)'")
while let row = try crop_sursor.next() {
let title: String = row.value(named: "srno")
crop_code=title
}
let rows = try Row.fetchCursor(db, "SELECT distinct brief_advisory,advisory_date,srno FROM crop_insect_advisory_issued where crop_code='\(crop_code)'")
while let row = try rows.next() {
let title: String = row.value(named: "brief_advisory")
let da:String=row.value(named:"advisory_date")
let srno:Int = row.value(named:"srno")
let date_f=DateFormatter()
date_f.dateFormat="yyyy-MM-dd"
let d=date_f.date(from: da)
date_f.dateFormat="dd-MM-yyyy"
let dd=date_f.string(from: d!)
array.append(title)
date_array.append(dd)
srno_array.append("\(srno)")
}
}
for i in 0 ..< array.count
{
struct_array.append(myObject(date:date_array[i],advisory:array[i],
status:"N",srno:srno_array[i]))
}
for i in 0 ..< array.count
{
msg_stat.append(oldMsg(is_checked: false))
}
collection_view.delegate = self
collection_view.dataSource = self
}catch{
print(error)
}
}
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int {
return array.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt
indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
"AdvisoryCollectionViewCell", for: indexPath) as!
AdvisoryCollectionViewCell
cell.msg_label.text = struct_array[indexPath.item].advisory
cell.date_label.text = struct_array[indexPath.item].date
let imagee = UIImage.init(named: "rsz_tick")
cell.check_image.image = imagee
cell.check_image.isHidden = true
if( msg_stat[indexPath.row].is_checked == false){
cell.check_image.isHidden = true
}
else if(msg_stat[indexPath.row].is_checked == true)
{
cell.check_image.isHidden = false
}
else{
}
return cell
}
func longpress(gestureRecognizer: UIGestureRecognizer)
{
let righbarButton = UIBarButtonItem(image: UIImage(named:
"rsz_delete")?.withRenderingMode(.alwaysOriginal), style:
UIBarButtonItemStyle.plain, target: self, action:
#selector(myRightTapped(sender:)))
self.navigationItem.rightBarButtonItem = righbarButton
let longpress = gestureRecognizer as! UILongPressGestureRecognizer
let state = longpress.state
let locationInview = longpress.location(in: collection_view)
var indexpath=collection_view.indexPathForItem(at: locationInview)
if(gestureRecognizer.state == UIGestureRecognizerState.began)
{
let cell = collection_view.cellForItem(at: indexpath!) as!
AdvisoryCollectionViewCell
cell.check_image.isHidden = false
msg_stat[(indexpath?.row)!].is_checked = true
ss.append((indexpath?.item)!)
print("index of deleting = \(indexpath?.item)")
msg_count_array.append((indexpath?.item)!)
msg_array.append(struct_array[(indexpath?.item)!].advisory)
selected_date_array.append(struct_array[(indexpath?.item)!].date)
selected_srno_array.append(struct_array[(indexpath?.item)!].srno)
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt
indexPath: IndexPath) {
let cell = collection_view.cellForItem(at: indexPath)
as!AdvisoryCollectionViewCell
if(!(ss.isEmpty)){
cell.check_image.isHidden = !cell.check_image.isHidden
if(cell.check_image.isHidden == true)
{
msg_stat[indexPath.row].is_checked = false
print("why removing.....")
if(!(msg_count_array.isEmpty)){
msg_count_array.remove(at: (indexPath.item))}
if(!(msg_array.isEmpty)){
msg_array.remove(at: (indexPath.item))
}
if(!(selected_srno_array.isEmpty))
{
selected_srno_array.remove(at: (indexPath.item))
}
if(!(selected_date_array.isEmpty))
{
selected_date_array.remove(at: (indexPath.item))
}
}
else{
msg_stat[indexPath.row].is_checked = true
msg_count_array.append((indexPath.item))
msg_array.append(array[(indexPath.item)])
selected_srno_array.append(struct_array[(indexPath.item)].srno)
}
}
}
func myRightTapped(sender:UIBarButtonItem!)
{
do{
for i in 0 ..< msg_count_array.count
{
struct_array.remove(at: i)
msg_stat.remove(at: i)
}
msg_count_array.removeAll()
for i in 0 ..< msg_array.count
{
var msg = msg_array[i]
var srno = selected_srno_array[i]
let
path=NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,
true).first!
let dbQueue = try DatabaseQueue(path: "\(path)/pest_messenger.sqlite")
try dbQueue.inDatabase { db in
try db.execute("DELETE FROM crop_insect_advisory_issued where srno='\
(srno)'")
}
}
msg_array.removeAll()
array.removeAll()
date_array.removeAll()
srno_array.removeAll()
// let dbQueue = try DatabaseQueue(path: "\(path)/p_messenger.sqlite")
try dbQueue?.inDatabase { db in
let rows = try Row.fetchCursor(db, "SELECT distinct brief_advisory,advisory_date,srno FROM crop_insect_advisory_issued where crop_code='\(crop_code)'")
while let row = try rows.next() {
let title: String = row.value(named: "brief_advisory")
let da:String=row.value(named:"advisory_date")
let srno:Int = row.value(named:"srno")
let date_f=DateFormatter()
date_f.dateFormat="yyyy-MM-dd"
let d=date_f.date(from: da)
date_f.dateFormat="dd-MM-yyyy"
let dd=date_f.string(from: d!)
array.append(title)
date_array.append(dd)
srno_array.append("\(srno)")
}
}
for i in 0 ..< array.count
{
struct_array.append(myObject(date:date_array[i],advisory:array[i],
status:"N",srno:srno_array[i]))
}
for i in 0 ..< array.count
{
msg_stat.append(oldMsg(is_checked: false))
}
collection_view.reloadData()
}
catch{
print(error)
}
}
}

Set the KILabel or ActiveLabel's height to 0 when it has no string. But Original UILabel is working fine

This question is related the UITableView and UILabel's height.
Hi I'm using the auto layout to set the dynamic Height in rows.
This is my layout in the table's cell.
Description Label
LikeCountLabel is blue color "1"
Comment Label
Time table is grey "Label"
Time Label
I also checked UILabel's property
import UIKit
import Parse
class ShopDetailCell: UITableViewCell {
#IBOutlet weak var commentBtn: UIButton!
#IBOutlet weak var likeBtn: UIButton!
#IBOutlet weak var profileImg: UIImageView!
#IBOutlet weak var postImg: UIImageView!
#IBOutlet weak var moreBtn: UIButton!
#IBOutlet weak var userNameBtn: UIButton!
#IBOutlet weak var uuidLabel: UILabel!
#IBOutlet weak var descriptionLabel: KILabel!
#IBOutlet weak var likesLabel: UILabel!
#IBOutlet weak var commentLabel: KILabel!
#IBOutlet weak var dateLabel: UILabel!
}
My TableView Controller
import UIKit
import Parse
import SDWebImage
class FeedVC: UITableViewController {
//UI Objects
#IBOutlet weak var indicator: UIActivityIndicatorView!
var refresher=UIRefreshControl()
//arrays to hold server data
var profileArray = [PFFile]()
var usernameArray = [String]()
var dateArray = [NSDate?]()
var postArray = [PFFile]()
var uuidArray = [String]()
var descriptionArray = [String]()
var commentsArray = [String]()
var isLoadedView:Bool = false
var sellingArray = [Bool]()
var followArray = [String]()
//advertise
var advArray = [PFFile]()
//page size
var page : Int = 10
//Default func
override func viewDidLoad() {
super.viewDidLoad()
//background color
tableView?.backgroundColor = UIColor(red: 0.0 / 255.0, green: 0.0 / 255.0, blue: 0.0 / 255.0, alpha: 1)
//automatic row height
tableView.estimatedRowHeight = 450
tableView.rowHeight = UITableViewAutomaticDimension
//pull to refresh
refresher.addTarget(self, action: #selector(FeedVC.loadPosts), forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refresher)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.refresh), name: "liked", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.uploaded(_:)), name: "Uploaded", object: nil)
self.navigationController?.setNavigationBarHidden(true, animated: true)
//calling function to load posts
loadPosts()
//receive notification from UploadViewController
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FeedVC.scrollToFirstRow(_:)), name: "scrollToTop", object: nil)
}
func scrollToFirstRow(notification:NSNotification) {
if isLoadedView == true {
print("scrollToTop!!!!!")
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: .Top, animated: true)
}
}
// reloading func with posts after received notification
func uploaded(notification:NSNotification){
print("receicev")
loadPosts()
}
//refresh function
func refresh(){
self.tableView.reloadData()
}
// load posts
func loadPosts() {
//STEP 1. Find posts related to people who we are following
let followQuery = PFQuery(className: "fans")
followQuery.whereKey("myfans", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
//clean up
self.followArray.removeAll(keepCapacity: false)
//Appending where people following..
//find related objects
for object in objects! {
self.followArray.append(object.objectForKey("fan") as! String)
}
//append current user to see own posts in feed
self.followArray.append(PFUser.currentUser()!.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.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
//clean up
self.usernameArray.removeAll(keepCapacity: false)
self.profileArray.removeAll(keepCapacity: false)
self.dateArray.removeAll(keepCapacity: false)
self.postArray.removeAll(keepCapacity: false)
self.descriptionArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
//find related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.profileArray.append(object.objectForKey("profileImg") as! PFFile)
self.dateArray.append(object.createdAt)
self.postArray.append(object.objectForKey("postImg") as! PFFile)
self.descriptionArray.append(object.objectForKey("title") as! String)
self.uuidArray.append(object.objectForKey("uuid") as! String)
}
//reload tableView & end spinning of refresher
self.tableView.reloadData()
self.refresher.endRefreshing()
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
})
}
//scrolled down
override func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y >= scrollView.contentSize.height - self.view.frame.size.height * 2 {
loadMore()
}
}
// pagination
func loadMore(){
//if posts on the server are more than shown
if page <= uuidArray.count {
//start animating indicator
indicator.startAnimating()
//increase page size to load + 10 posts
page = page + 10
//STEP 1. Find posts related to people who we are following
let followQuery = PFQuery(className: "fans")
followQuery.whereKey("myfans", equalTo: PFUser.currentUser()!.username!)
followQuery.findObjectsInBackgroundWithBlock ({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
//clean up
self.followArray.removeAll(keepCapacity: false)
//Appending where people following..
//find related objects
for object in objects! {
self.followArray.append(object.objectForKey("fan") as! String)
}
//append current user to see own posts in feed
self.followArray.append(PFUser.currentUser()!.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.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
//clean up
self.usernameArray.removeAll(keepCapacity: false)
self.profileArray.removeAll(keepCapacity: false)
self.dateArray.removeAll(keepCapacity: false)
self.postArray.removeAll(keepCapacity: false)
self.descriptionArray.removeAll(keepCapacity: false)
self.uuidArray.removeAll(keepCapacity: false)
//find related objects
for object in objects! {
self.usernameArray.append(object.objectForKey("username") as! String)
self.profileArray.append(object.objectForKey("profileImg") as! PFFile)
self.dateArray.append(object.createdAt)
self.postArray.append(object.objectForKey("postImg") as! PFFile)
self.descriptionArray.append(object.objectForKey("title") as! String)
self.uuidArray.append(object.objectForKey("uuid") as! String)
}
//reload tableView stop indicator animation
self.tableView.reloadData()
self.indicator.stopAnimating()
} else {
print(error!.localizedDescription)
}
})
} else {
print(error!.localizedDescription)
}
})
}
}
//number of cell
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return uuidArray.count + 1
}
// cell config
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// 가장 첫 페이지는 광고영역..
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("AdvertiseCell", forIndexPath: indexPath) as! AdvertiseCell
return cell
}
//define cell
let cell = tableView.dequeueReusableCellWithIdentifier("ShopDetailCell", forIndexPath: indexPath) as! ShopDetailCell
cell.userNameBtn.setTitle(usernameArray[indexPath.row - 1], forState: UIControlState.Normal)
cell.userNameBtn.sizeToFit()
cell.uuidLabel.text = uuidArray[indexPath.row - 1]
cell.descriptionLabel.text = descriptionArray[indexPath.row - 1]
cell.descriptionLabel.sizeToFit()
// manipulate like button depending on did user like it or not
let isComments = PFQuery(className: "comments")
isComments.whereKey("to", equalTo: cell.uuidLabel.text!)
isComments.limit = 1
isComments.addAscendingOrder("createdAt")
isComments.countObjectsInBackgroundWithBlock({(count:Int32, error:NSError?) -> Void in
//if no any likes are found, else found likes
if count==0 {
cell.commentLabel.text = nil
cell.commentLabel.sizeToFit()
// cell.commentHeight.constant = 0
}else{
//STEP 2. Request last (page size 15) comments
let query = PFQuery(className: "comments")
query.whereKey("to", equalTo: cell.uuidLabel.text!)
query.limit = 1
query.addDescendingOrder("createdAt")
query.findObjectsInBackgroundWithBlock({(objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
//find related object
for object in objects!{
let comment = object.objectForKey("comment") as! String
let by = object.objectForKey("username") as! String
let commentString = by + " " + comment
let boldString = NSMutableAttributedString(string: commentString)
boldString.addAttribute(NSFontAttributeName, value: UIFont(name: "SFUIText-Bold", size: 14)!, range: NSRange(0...by.characters.count))
cell.commentLabel.attributedText = boldString
cell.commentLabel.sizeToFit()
// self.tableView?.reloadData()
}
}else {
print(error?.localizedDescription)
}
})
}
})
//STEP 1. Load data of guest
let profileImgQuery = PFQuery(className: "_User")
profileImgQuery.whereKey("username", equalTo: usernameArray[indexPath.row - 1])
profileImgQuery.findObjectsInBackgroundWithBlock({(objects:[PFObject]?, error:NSError?) -> 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.objectForKey("profileImg") as? PFFile
profilePictureObject?.getDataInBackgroundWithBlock { (imageData:NSData?, error:NSError?) -> Void in
if(imageData != nil)
{
let profileURL : NSURL = NSURL(string: profilePictureObject!.url!)!
cell.profileImg.sd_setImageWithURL(profileURL, placeholderImage: UIImage(named: "holderImg"))
}
}
}
} else {
print(error?.localizedDescription)
}
})
// place post picture using the sdwebimage
let postURL : NSURL = NSURL(string: postArray[indexPath.row - 1].url!)!
cell.postImg.sd_setImageWithURL(postURL, placeholderImage: UIImage(named: "holderImg"))
//Calculate post date
let from = dateArray[indexPath.row - 1]
let now = NSDate()
let components : NSCalendarUnit = [.Second, .Minute, .Hour, .Day, .WeekOfMonth]
let difference = NSCalendar.currentCalendar().components(components, fromDate: from!, toDate: 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"
}
//
//
// manipulate like button depending on did user like it or not
let didLike = PFQuery(className: "likes")
didLike.whereKey("by", equalTo: PFUser.currentUser()!.username!)
didLike.whereKey("to", equalTo: cell.uuidLabel.text!)
didLike.countObjectsInBackgroundWithBlock({(count:Int32, error:NSError?) -> Void in
//if no any likes are found, else found likes
if count==0 {
cell.likeBtn.setTitle("unlike", forState: .Normal)
cell.likeBtn.setBackgroundImage(UIImage(named:"heartBtn"), forState: .Normal)
}else{
cell.likeBtn.setTitle("like", forState: .Normal)
cell.likeBtn.setBackgroundImage(UIImage(named: "heartTapBtn"), forState: .Normal)
}
})
//count total likes of shown post
let countLikes = PFQuery(className: "likes")
countLikes.whereKey("to", equalTo: cell.uuidLabel.text!)
countLikes.countObjectsInBackgroundWithBlock({(count:Int32, error:NSError?) -> Void in
cell.likesLabel.text="\(count) likes"
})
//asign index
cell.userNameBtn.layer.setValue(indexPath, forKey: "index")
cell.commentBtn.layer.setValue(indexPath, forKey: "index")
cell.moreBtn.layer.setValue(indexPath, forKey: "index")
// #mention is tapped
cell.descriptionLabel.userHandleLinkTapHandler = { label, handle, rang in
var mention = handle
mention = String(mention.characters.dropFirst())
if mention.lowercaseString == PFUser.currentUser()?.username {
let home = self.storyboard?.instantiateViewControllerWithIdentifier("MyShopCollectionVC") as! MyShopCollectionVC
self.navigationController?.pushViewController(home, animated: true)
} else {
guestname.append(mention.lowercaseString)
let guest = self.storyboard?.instantiateViewControllerWithIdentifier("GuestShopCollectionVC") as! GuestShopCollectionVC
self.navigationController?.pushViewController(guest, animated: true)
}
}
// #Hashtag is tapped
cell.descriptionLabel.hashtagLinkTapHandler = {label, handle, range in
var mention = handle
mention = String(mention.characters.dropFirst())
hashtag.append(mention.lowercaseString)
let hashvc = self.storyboard?.instantiateViewControllerWithIdentifier("HashTagsCollectionVC") as! HashTagsCollectionVC
self.navigationController?.pushViewController(hashvc, animated: true)
}
// cell.layoutIfNeeded()
return cell
}
////////
#IBAction func userNameBtnTapped(sender: AnyObject) {
//call index of button
let i = sender.layer.valueForKey("index") as! NSIndexPath
//call cell to call further cell data
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//if user tapped on himeself go home, else go guest
if cell.userNameBtn.titleLabel?.text == PFUser.currentUser()?.username {
let home = self.storyboard?.instantiateViewControllerWithIdentifier("MyShopCollectionVC") as! MyShopCollectionVC
self.navigationController?.pushViewController(home, animated: true)
}else {
guestname.append(cell.userNameBtn.titleLabel!.text!)
let guest = self.storyboard?.instantiateViewControllerWithIdentifier("GuestShopCollectionVC") as! GuestShopCollectionVC
self.navigationController?.pushViewController(guest, animated: true)
}
}
#IBAction func commentBtnTapped(sender: AnyObject) {
print("commentTapped")
// call index of button
let i = sender.layer.valueForKey("index") as! NSIndexPath
// call cell to call further cell data
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//send related data to global variables
commentUUID.append(cell.uuidLabel.text!)
// commentOwner.append(cell.userNameLabel.titleLabel!.text!)
commentOwner.append(cell.userNameBtn.titleLabel!.text!)
let comment = self.storyboard?.instantiateViewControllerWithIdentifier("CommentVC") as! CommentVC
self.navigationController?.pushViewController(comment, animated: true)
}
#IBAction func moreBtnTapped(sender: AnyObject) {
let i = sender.layer.valueForKey("index") as! NSIndexPath
//Call cell to call further cell date
let cell = tableView.cellForRowAtIndexPath(i) as! ShopDetailCell
//Delete Action
let delete = UIAlertAction(title: "Delete", style: .Default) { (UIAlertAction) -> Void in
//STEP 1. Delete row from tablevIEW
self.usernameArray.removeAtIndex(i.row)
self.profileArray.removeAtIndex(i.row)
self.dateArray.removeAtIndex(i.row)
self.postArray.removeAtIndex(i.row)
self.descriptionArray.removeAtIndex(i.row)
self.uuidArray.removeAtIndex(i.row)
//STEP 2. Delete post from server
let postQuery = PFQuery(className: "posts")
postQuery.whereKey("uuid", equalTo: cell.uuidLabel.text!)
postQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
object.deleteInBackgroundWithBlock({ (success:Bool, error:NSError?) -> Void in
if success {
//send notification to rootViewController to update shown posts
NSNotificationCenter.defaultCenter().postNotificationName("uploaded", object: nil)
//push back
self.navigationController?.popViewControllerAnimated(true)
} else {
print(error?.localizedDescription)
}
})
}
} else {
print(error?.localizedDescription)
}
})
//STEP 2. Delete likes of post from server
let likeQuery = PFQuery(className: "likes")
likeQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
likeQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
object.deleteEventually()
}
}
})
//STEP 3. Delete comments of post from server
let commentQuery = PFQuery(className: "comments")
commentQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
commentQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
object.deleteEventually()
}
}
})
//STEP 4. Delete hashtags of post from server
let hashtagQuery = PFQuery(className: "hashtags")
hashtagQuery.whereKey("to", equalTo: cell.uuidLabel.text!)
hashtagQuery.findObjectsInBackgroundWithBlock({ (objects:[PFObject]?, error:NSError?) -> Void in
if error == nil {
for object in objects! {
object.deleteEventually()
}
}
})
}
//Complain Action
let complain = UIAlertAction(title: "Complain", style: .Default) { (UIAlertAction) -> Void in
//send complain to server
let complainObj = PFObject(className: "complain")
complainObj["by"] = PFUser.currentUser()?.username
complainObj["to"] = cell.uuidLabel.text
complainObj["owner"] = cell.userNameBtn.titleLabel?.text
complainObj.saveInBackgroundWithBlock({ (success:Bool, error:NSError?) -> Void in
if success {
self.alert("Complain has been made successfully", message: "Thank You! We will consider your complain")
}else {
self.alert("ERROR", message: error!.localizedDescription)
}
})
}
//Cancel ACTION
let cancel = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
//create menu controller
let menu = UIAlertController(title: "Menu", message: nil, preferredStyle: .ActionSheet)
//if post belongs to user
if cell.userNameBtn.titleLabel?.text == PFUser.currentUser()?.username {
menu.addAction(delete)
menu.addAction(cancel)
} else {
menu.addAction(complain)
menu.addAction(cancel)
}
//show menu
self.presentViewController(menu, animated: true, completion: nil)
}
//alert action
func alert(title: String, message:String){
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
let ok = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(ok)
presentViewController(alert, animated: true, completion: nil)
}
}
Ok My problem is ...If UILabel's string is nil or "" then It's height should be set to zero. Also Table cell's height is smaller than original height.
UILabel has no strings but It still has height.
Seems like this is the issue in the KILabel library, and the solution is (link) to create custom label class, inherit from KILabel and override this method:
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
if (self.text.length == 0) {
return CGRectZero;
}
return [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines];
}
Declare your UILabel height constraint like this:-
#IBOutlet weak var likeLabelHeightConstraint: NSLayoutConstraint!
And set your height like this
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
let height : CGFloat = 50 //Default cell Height
if likeLabel.text == nil || likeLabel.text == ""{
height = height - likeLabelHeightConstraint.constant
likeLabelHeightConstraint.constant = 0
}else{
//Set default scenario
}
return height
}
If you are retrieving data asynchronously then make sure you reload your data once your DataSource is updated....

swift/parse: error when setting Parse data to labels

What I am trying to do is to have data from Parse be retrieved from columns by object order. All labels are connected to their respective outlets and all of the outputs retrieve their correct data.
When I run it and open a cell in the tableview it crashes and gives me Thread 1: EXC_BAD_INSTRUCTION (code=EXC>I386_INVOP, subcode=0x0) on this line: self.navBar.topItem?.title = output1 if I select the first cell, and then on this line: self.navBar.topItem?.title = output1b if I select the second cell.
Here is the full function:
firstObject is grabbing the first object in the "eventsdetail" column
secondObject is grabbing the second object in the "eventsdetail" column
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var query = PFQuery(className: "eventsdetail")
let runkey = query.orderByAscending("ID")
runkey.findObjectsInBackgroundWithBlock {
(objects: [PFObject]?, error : NSError?) -> Void in
if error == nil {
if let objects = objects as [PFObject]! {
for object in objects {
var firstObject = objects[0]
var secondObject = objects[1]
let output1 = firstObject.objectForKey("navTitle") as! String!
let output2 = firstObject.objectForKey("articleTitle") as! String!
let output3 = firstObject.objectForKey("written") as! String!
let output4 = firstObject.objectForKey("date") as! String!
let output5 = firstObject.objectForKey("article") as! String!
let output1b = secondObject.objectForKey("navTitle") as! String!
let output2b = secondObject.objectForKey("articleTitle") as! String!
let output3b = secondObject.objectForKey("written") as! String!
let output4b = secondObject.objectForKey("date") as! String!
let output5b = secondObject.objectForKey("article") as! String!
if indexPath.row == 0 {
self.performSegueWithIdentifier("0a", sender: nil)
self.tableview.deselectRowAtIndexPath(indexPath, animated: true)
self.navBar.topItem?.title = output1
self.articleTitle.text = output2
self.writtenBy.text = output3
self.date.text = output4
self.article.text = output5
} else if indexPath.row == 1 {
self.performSegueWithIdentifier("0a", sender: nil)
self.tableview.deselectRowAtIndexPath(indexPath, animated: true)
self.navBar.topItem?.title = output1b
self.articleTitle.text = output2b
self.writtenBy.text = output3b
self.date.text = output4b
self.article.text = output5b
}
}
}
}
}
}
If there is an easier way of doing this, please mention it, if not try to just solve this method's problem. I know it isn't the cleanest way of doing things.
I am not sure of how you Parse your data but if it can help you, here's how I would do:
//
// Test.swift
// Test
//
// Created by Charles-Olivier Demers on 16-01-04.
//
import UIKit
//import Parse
class EventViewController: UIViewController, UITableViewDelegate {
private var _info = [EventDetails]()
override func viewDidLoad() {
fetchData()
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.performSegueWithIdentifier("0a", sender: nil)
self.tableview.deselectRowAtIndexPath(indexPath, animated: true)
self.navBar.topItem?.title.text = _info[indexPath.row].navTitle()
self.articleTitle.text = _info[indexPath.row].articleTitle()
self.writtenBy.text = _info[indexPath.row].writtenBy()
self.date.text = _info[indexPath.row].date()
self.article.text = _info[indexPath.row].article()
}
func fetchData() {
let query = PFQuery(className: "eventsDetails")
query.orderByAscending("ID")
query.findObjectsInBackgroundWithBlock { (objects: [PFObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects {
for object in objects {
let navTitleObject = object["navTitle"] as! String
let articleTitleObject = object["articleTitle"] as! String
let writtenByObject = object["writtenByObject"] as! String
let dateObject = object["dateObject"] as! String
let articleObject = object["articleObject"] as! String
_info.append(EventDetails(navTitle: navTitleObject, articleTitle: articleTitleObject, writtenBy: writtenByObject, date: dateObject, article: articleObject))
}
}
}
else {
print("Error #\(error!.code)")
}
}
}
}
class EventDetails {
private var _navTitle: String!
private var _articleTitle: String!
private var _writtenBy: String!
private var _date: String!
private var _article: String!
init(navTitle: String, articleTitle: String, writtenBy: String, date: String, article: String) {
self._navTitle = navTitle
self._article = articleTitle
self._writtenBy = writtenBy
self._date = date
self._article = article
}
func navTitle() -> String {
return _navTitle
}
func articleTitle() -> String {
return _articleTitle
}
func writtenBy() -> String {
return _writtenBy
}
func date() -> String {
return _date
}
func article() -> String {
return _article
}
}
First of all, I would create a class named EventDetails. This class will take all the property of EventsDetails class on Parse. So when you fetch your data, you append the data you fetch in an array of EventDetails class in Swift.
After that in your
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
you take the value in your EventDetails array with the indexPath.row and you fill your Table View.
That is how I would do.