Table view not reloading issue - xcode

I am implementing chat using socket and I want to get list from server using once listener of socketIO.Problem I am facing is after getting response from socket my table view is not reloading I had made delegate and datasource self using code as well as from storyboard but no success. Here is my code:
//List data Socket completion handler
SocketHelper.shared.messageChatList(recieverID ?? "0"){success,responseData,error in
if success == true{
if let arr = responseData as? [[String: Any]]{
DispatchQueue.main.asyncAfter(deadline: .now()) {
if let dataArray = arr[0]["data"] as? NSArray {
for i in 0..<dataArray.count {
if let dataDict = dataArray[i] as? NSDictionary {
let chatListModelObj = ChatListModel()
chatListModelObj.dataDict(dict: dataDict)
self.chatListModelAry.append(chatListModelObj)
}
}
}
}
print("Array Count:",self.chatListModelAry.count)
self.tblVw.delegate = self
self.tblVw.dataSource = self
self.tblVw.reloadData()
self.tblVw.layoutIfNeeded()
}
} else{
self.tblVw.reloadData()
}
}
// my table view functions
extension BusinessesChatVC: UITableViewDataSource,UITableViewDelegate{
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return chatListModelAry.count
print("chatListModelAry:",chatListModelAry.count)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellObj = self.tblVw.dequeueReusableCell(withIdentifier: "BusinessChatTVC", for: indexPath) as! BusinessChatTVC
if chatListModelAry.count > 0 {
DispatchQueue.main.async {
let chatListModelAryObj = self.chatListModelAry[indexPath.row]
cellObj.lblRecievedMsg.text = chatListModelAryObj.message
}
}
return cellObj
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
return UITableView.automaticDimension
print("Dimension:",UITableView.automaticDimension)
}
}

Related

Did Select method in Table View not Working in Swift

I'm using two table view in one view controller to populate my different data. All the other delegates methods are working fine but didselect method is not performing an action neither its printing any value in console. I hae checked through story board also all the things looks fine and i have set its delegate and datasources methods also but still it isn't working. Searched a lot from net but still unsuccessful in it. My code is this,
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.isNavigationBarHidden = true
self.searchBar.delegate = self
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(LoginViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
dishDetailTableView.delegate = self
dishDetailTableView.dataSource = self
self.addOnTableView.allowsMultipleSelection = true
addOnTableView.delegate = self
addOnTableView.dataSource = self
dishDetailTableView.reloadData()
sectionArray = [String(MenuService.instance.subCategoryModelInstance[0].sub_categoryName)]
print(sectionArray)
cancelBtn.cornerButton()
cancelBtn.layer.borderColor = #colorLiteral(red: 1, green: 0, blue: 0.03742904276, alpha: 1)
cancelBtn.layer.borderWidth = 1.5
nextBtn.layer.borderColor = #colorLiteral(red: 0.09759091236, green: 0.5779017098, blue: 1, alpha: 1)
nextBtn.layer.borderWidth = 1.5
nextBtn.cornerButton()
menuTypeLbl.layer.cornerRadius = 5
addOnView.borderView(view: addOnView)
addOnView.isHidden = true
shadowView.isHidden = true
}
extension DishDetailViewController : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
var count:Int?
if tableView == dishDetailTableView {
count = MenuService.instance.subCategoryItemModelInstance.count
}
if (tableView == addOnTableView) {
count = AddOnService.instance.AddOnModelInstance.count
}
return count!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
var cell:UITableViewCell?
if tableView == dishDetailTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "menuCell", for: indexPath) as! MenuDetailTableViewCell
cell.titleLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemName
cell.descriptionLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemdescription
cell.priceLbl?.text = MenuService.instance.subCategoryItemModelInstance[indexPath.row].itemprice
cell.backgroundColor = UIColor.clear
cell.delegate = self
cell.selectionStyle = .none
return cell
}
if tableView == addOnTableView{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! AddOnTableViewCell
cell.addOnLbl.text = AddOnService.instance.AddOnModelInstance[indexPath.row].itemName
print(cell.addOnLbl?.text! as Any)
return cell
}
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView == dishDetailTableView{
print("Hi")
dishDetailTableView.reloadData()
}
if tableView == addOnTableView {
print("Hello")
addOnTableView.reloadData()
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
var count : Int?
if tableView == dishDetailTableView{
count = 120
}
if tableView == addOnTableView{
count = 60
}
return CGFloat(count!)
}
}
How can i perform any action on cell?

Swift - search table view with multiple selection

I have followed a tutorial of Vea software (https://www.veasoftware.com/tutorials/2015/6/27/uisearchcontroller-in-swift-xcode-7-ios-9-tutorial) to create a table view with search bar on xcode 7, ios 9. Now I need to select multiple rows from the table view by adding a checkmark on each row when selected, the problem is that when I use the search bar the checkmarks don't match the rows anymore..
Here's my code:
class SportSearchTableViewController: UITableViewController, UISearchResultsUpdating {
let appleProducts = ["Mac","iPhone","Apple Watch","iPad"]
var filteredAppleProducts = [String]()
var resultSearchController = UISearchController()
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath,animated: true)
let selectedRow = tableView.cellForRowAtIndexPath(indexPath)!
if selectedRow.accessoryType == UITableViewCellAccessoryType.None {
selectedRow.accessoryType = UITableViewCellAccessoryType.Checkmark
selectedRow.tintColor = UIColor.blueColor()
} else {
selectedRow.accessoryType = UITableViewCellAccessoryType.None
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = self.resultSearchController.searchBar
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.resultSearchController.active)
{
return self.filteredAppleProducts.count
}
else
{
return self.appleProducts.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell?
if (self.resultSearchController.active)
{
cell!.textLabel?.text = self.filteredAppleProducts[indexPath.row]
return cell!
}
else
{
cell!.textLabel?.text = self.appleProducts[indexPath.row]
return cell!
}
}
func updateSearchResultsForSearchController(searchController: UISearchController)
{
self.filteredAppleProducts.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (self.sportsList as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredAppleProducts = array as! [String]
self.tableView.reloadData()
}
Does anyone know how to fix that?

How do you edit or delete text in a tableView?

I am trying have the user to modify/delete default text in a tableview, I have tried the following code witch works but as soon as the user goes to the other view controller and back (or leaves the app and comes back), the text goes back to being the default text.
How could I have it work?
I have posted the entire code for the tableView so you can have an overview of what I could have done wrong.
thank you !
var places = [Dictionary<String,String>()]
var activePlace = -1
class TableViewController: UITableViewController {
func companyNameUpdatedAlert(title: String, error: String, indexPath: Int) {
let alert = UIAlertController(title: title, message: error, preferredStyle: UIAlertControllerStyle.Alert)
alert.addTextFieldWithConfigurationHandler { (textField) -> Void in
textField.placeholder = "Enter new text"
}
alert.addAction(UIAlertAction(title: "OK", style: .Default, handler: { (action) -> Void in
let lat = places[indexPath]["lat"]!
let lon = places[indexPath]["lon"]!
places.removeAtIndex(indexPath)
places.insert(["name" : alert.textFields![0].text!, "lat" : lat, "lon" : lon], atIndex: indexPath)
self.tableView.reloadData()
}))
self.presentViewController(alert, animated: true, completion: nil)
}
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
let changeText = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Change text" , handler: { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
self.companyNameUpdatedAlert("Update text", error: "enter text below", indexPath: indexPath.row)
})
let deleteAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Delete" , handler: { (action:UITableViewRowAction, indexPath:NSIndexPath) -> Void in
places.removeAtIndex(indexPath.row)
tableView.reloadData()
})
return [changeText, deleteAction]
}
override func viewDidLoad() {
//save start
if NSUserDefaults.standardUserDefaults().objectForKey("places") != nil {
places = NSUserDefaults.standardUserDefaults().objectForKey("places") as! [Dictionary]
//save stop
super.viewDidLoad()
if places.count == 1 {
places.removeAtIndex(0)
places.append(["name":"Long press on map to add location","lat":"90","lon":"90"])
}
if NSUserDefaults.standardUserDefaults().objectForKey("places") != nil {
places = NSUserDefaults.standardUserDefaults().objectForKey("places") as! [Dictionary]
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return places.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = places[indexPath.row]["name"]
return cell
}
override func tableView(tableView: UITableView, willSelectRowAtIndexPath indexPath: NSIndexPath) -> NSIndexPath? {
activePlace = indexPath.row
return indexPath
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "newPlace" {
activePlace = -1
}
}
override func viewWillAppear(animated: Bool) {
tableView.reloadData()
}
}
When you edit the table you should persist your data in the NSUserDefaults. Otherwise you are just changing the class property which is reloaded from the original NSUserDefaults each time the class loads.
Try this inside your UIAlertAction closure:
NSUserDefaults.standardUserDefaults().setObject(places, forKey: "places")
NSUserDefaults.standardUserDefaults().synchronize()

Load data to UITableView

I have data saved like this:
var mineSpillere = ["erik", "tom", "phil"]
How can i add that data to a UITableView by pressing a UIButton like this?:
#IBAction func backButtonAction(sender: AnyObject) {
// Press this button here to add the "mineSpillere" data to myTableView
}
Set the data source of the table view inside the IBAction. so like this:
#IBAction func backButtonAction(sender: AnyObject) {
myTableView.dataSource = self
// Loading from NSUserDefaults:
// Please name it something better than array I couldn't come up with any names.
if let array = NSUserDefaults.standardUserDefaults().arrayForKey("key") as? [String]
{
// The key exists in user defaults
}
else
{
// The key doesn't exist in the user defaults, do some error handling here.
}
}
And then implement the data source:
extension MyVC : UITableViewDataSource
{
func numberOfSectionsInTableView(tableView: UITableView) -> Int
{
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return mineSpillere.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
cell.textLabel!.text = mineSpillere[indexPath.row]
return cell
}
}

Cannot invoke 'getDataInBackgroundWithBlock' with an argument list of type '((NSData!, NSError!) -> Void)'

I'm using swift 6.3 and having 2 similar errors
Cannot invoke 'findObjectsInBackgroundWithBlock' with an argument list of type '(([AnyObject]!, NSError!) -> Void)'
Cannot invoke 'getDataInBackgroundWithBlock' with an argument list of type '((NSData!, NSError!) -> Void)'
Any ideas please?
import Parse
import UIKit
class UserVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var resultTable: UITableView!
var resultNameArray = [String]()
var resultUserNameArray = [String]()
var resultUserImageFiles = [PFFile]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewDidAppear(animated: Bool) {
resultNameArray.removeAll(keepCapacity: false)
resultUserNameArray.removeAll(keepCapacity: false)
resultUserImageFiles.removeAll(keepCapacity: false)
var query = PFUser.query()
query!.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
//// here is the error////
query.findObjectsInBackgroundWithBlock {(objects:[AnyObject]!, error:NSError!) -> Void in
if error == nil {
for object in objects {
self.resultNameArray.append(object.objectForKey("profileName") as String)
self.resultUserImageFiles.append(object.objectForKey("photo") as PFFile)
self.resultUserNameArray.append(object.objectForKey("username") as String)
self.resultsTable.reloadData()
}
}
}
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultNameArray.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 64
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:User_Cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! User_Cell
cell.profileLbl.text = self.resultNameArray[indexPath.row]
cell.userLbl.text = self.resultUserNameArray[indexPath.row]
//// here is the error////
self.resultUserImageFiles[indexPath.row].getDataInBackgroundWithBlock {
(imageData:NSData!, error:NSError!) -> Void in
if error == nil {
let image = UIImage(data: imageData)
cell.imgView.image = image
}
}
return cell
}
}
The first error is due to block parameters are wrong. objects and error both should be optional.
Like below:
query?.findObjectsInBackgroundWithBlock({ (objects: [AnyObject]?, error: NSError?) -> Void in
Second is same reason. imageData and error also both optional.
Like below:
self.resultUserImageFiles[indexPath.row].getDataInBackgroundWithBlock { (imageData: NSData?, error: NSError?) -> Void in
All fixed code:
class UserVC: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var resultTable: UITableView!
var resultNameArray = [String]()
var resultUserNameArray = [String]()
var resultUserImageFiles = [PFFile]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewDidAppear(animated: Bool) {
resultNameArray.removeAll(keepCapacity: false)
resultUserNameArray.removeAll(keepCapacity: false)
resultUserImageFiles.removeAll(keepCapacity: false)
var query = PFUser.query()
query!.whereKey("username", notEqualTo: PFUser.currentUser()!.username!)
//// here is the error////
query?.findObjectsInBackgroundWithBlock({ (objects: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
if let objects = objects {
for object in objects {
self.resultNameArray.append(object.objectForKey("profileName") as! String)
self.resultUserImageFiles.append(object.objectForKey("photo") as! PFFile)
self.resultUserNameArray.append(object.objectForKey("username") as! String)
self.resultsTable.reloadData()
}
}
}
})
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return resultNameArray.count
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 64
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:User_Cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! User_Cell
cell.profileLbl.text = self.resultNameArray[indexPath.row]
cell.userLbl.text = self.resultUserNameArray[indexPath.row]
//// here is the error////
self.resultUserImageFiles[indexPath.row].getDataInBackgroundWithBlock { (imageData: NSData?, error:NSError?) -> Void in
if error == nil {
let image = UIImage(data: imageData!)
cell.imgView.image = image
}
}
return cell
}
}
In swift 1.2 (Xcode update to 6.3) optionals were changed, so now, the NSError is optional.
Which makes your function the following:
query?.findObjectsInBackgroundWithBlock({ (objects: [AnyObject]?, error: NSError?) -> Void in
// Do whatever you want with these objects
})
it works great now and other error shows up here
self.resultsTable.reloadData()
the error UsersVC does not have a member named resultsTable.

Resources