tableView jumping scrolling after reloadData - ios

My tableView scrolling is jumping when I reload tableView with new data. Here is the code for cellForRowAtIndexPath:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let section = indexPath.section
let index = indexPath.row
let info = data[sections[section]]![index] as ConversationMessage
if info.from == .Me {
var cell: ConversationDialogMeTableCell = tableView.dequeueReusableCellWithIdentifier("meCell", forIndexPath: indexPath) as! ConversationDialogMeTableCell
cell.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
cell.messageLabel.text = info.text
return cell
} else if info.from == .Other {
var cell: ConversationDialogOtherTableCell = tableView.dequeueReusableCellWithIdentifier("otherCell", forIndexPath: indexPath) as! ConversationDialogOtherTableCell
cell.backgroundColor = UIColor.clearColor()
cell.selectionStyle = .None
cell.personName.textColor = UIColor(hex: 0x6d6d6d)
cell.messageContainerView.backgroundColor = UIColor(hex: 0x6d6d6d)
cell.messageContainerView.layer.cornerRadius = 5
cell.messageContainerView.clipsToBounds = true
Alamofire.request(.GET, info.personImage).response {
(request, response, data, error) in
let image = UIImage(data: data!, scale: 1)!
cell.personImage.image = image
cell.personImage.contentMode = UIViewContentMode.ScaleAspectFill
cell.personImage.layer.cornerRadius = cell.personImage.frame.height / 2
cell.personImage.clipsToBounds = true
}
cell.personName.text = info.personName
cell.personMessage.text = info.text
return cell
}
return UITableViewCell()
}
For the first load scrolling is smooth, but if I will add new data in my tableView and call reloadData() the scrolling is jumping when new cells are shown.
Here is the code where I insert new data to my model:
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
if message.data.subscribedChannel == self.channel {
if let messageInfo: AnyObject = message.data.message {
let date = (messageInfo["date"] as! String).getDateString()
let messageText = messageInfo["message"] as! String
let from: ConversationMessage.sendFromType = (messageInfo["userID"] as! String) == self.userID ? .Me : .Other
let image = messageInfo["userPhoto"] as! String
let name = messageInfo["userName"] as! String
if data[date] != nil {
data[date]!.append(ConversationMessage(text: messageText, from: from, personImage: image, personName: name, date: messageInfo["date"] as! String))
} else {
data[date] = [ConversationMessage(text: messageText, from: from, personImage: image, personName: name, date: messageInfo["date"] as! String)]
}
for section in self.sections {
self.data[section]! = sorted(self.data[section]!) { Utils.compareDateTime($0.date, with: $1.date, order: .OrderedAscending) }
}
tableView.reloadData()
tableViewScrollToBottom(false)
}
}
}
Maybe it happens because of function to scroll tableView to bottom:
func tableViewScrollToBottom(animated: Bool) {
let delay = 0.1 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue(), {
let numberOfSections = self.tableView.numberOfSections()
let numberOfRows = self.tableView.numberOfRowsInSection(numberOfSections - 1)
if numberOfRows > 0 {
let indexPath = NSIndexPath(forRow: numberOfRows - 1, inSection: (numberOfSections - 1))
self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}
})
}
One more thing. Should I cache uploaded images? Maybe this is causing jumping scroll. Can someone help me to solve my issue?

Do not return UITableViewAutomaticDimension from
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
There may be two possible solutions -
Either you should return max height for your cell.
OR you may cache the cell.bounds.size.height from
tableView:willDisplayCell:forRowAtIndexPath: and return same value in estimatedHeightForRowAtIndexPath

Related

images repeating cells when scrolled in tableview

images are not showing properly in tableview , I have two Json Api (Primary/high) school. I can append the Both Json api Data and display into tableview,
tableview working fine it's showing both(primary/high) school data. when I can scroll the tableview images are jumping and images loading very slow in image view at tableview.
Before scrolling tableview its showing like this
After scrolling the tableview it's shows like this
after scrolling images are jumping,
this is the code
var kidsdata = [KidDetails]()
func getprimarydata(_firsturl: String,firstid:String,updatedate:String)
{
if errorCode == "0" {
if let kid_list = jsonData["students"] as? NSArray {
self.kidsdata.removeAll()
for i in 0 ..< kid_list.count {
if let kid = kid_list[i] as? NSDictionary {
let imageURL = url+"/images/" + String(describing: kid["photo"]!)
self.kidsdata.append(KidDetails(
name:kid["name"] as? String,
photo : (imageURL),
standard: ((kid["standard"] as? String)! + "std" + " " + (kid["section"] as? String)! + " section ")
))}}}}
}
func gethighdata(_secondurl:String ,secondid:String,updatedate:String)
{
if errorCode == "0" {
if let kid_list = jsonData["students"] as? NSArray {
for i in 0 ..< kid_list.count {
if let kid = kid_list[i] as? NSDictionary {
let imageURL = url+"/images/" + String(describing: kid["photo"]!)
self.kidsdata.append(KidDetails(
name:kid["name"] as? String,
photo : (imageURL),
standard: ((kid["standard"] as? String)! + "th" + " " + (kid["section"] as? String)! + " section ")
)
)
}
}
self.do_table_refresh()
}
}
}
func do_table_refresh()
{
DispatchQueue.main.async(execute: {
self.TableView.reloadData()
return
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCell(
withIdentifier: "cell", for: indexPath) as! DataTableViewCell
cell.selectionStyle = .none
cell.ProfileImage?.image = nil
let row = (indexPath as NSIndexPath).row
let kid = kidsdata[row] as KidDetails
cell.NameLabel.text = kid.name
cell.ProfileImage.image = UIImage(named: "profile_pic")
cell.ProfileImage.downloadImageFrom(link:kid.photo!, contentMode: UIViewContentMode.scaleAspectFill)
cell.ClassNameLabel.text = kid.standard
return cell
}
where I did mistake pls help me....!
AlamofireImage handles this very well. https://github.com/Alamofire/AlamofireImage
import AlamofireImage
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DataTableViewCell
cell.selectionStyle = .none
let kid = kidsdata[indexPath.row] as KidDetails
cell.NameLabel.text = kid.name
cell.ClassNameLabel.text = kid.standard
// assuming cell.ProfileImage is a UIImageView
cell.ProfileImage.image = nil
let frame = CGSize(width: 50, height: 50)
let filter = AspectScaledToFillSizeWithRoundedCornersFilter(size: frame, radius: 5.0)
cell.ProfileImage.af_setImage(withURL: urlToImage, placeholderImage: nil, filter: filter,
imageTransition: .crossDissolve(0.3), runImageTransitionIfCached: false)
return cell
}
All we need to do is use the prepareForReuse() function. As discussed in this medium article, This function is called before cell reuse, letting you cancel current requests and perform a reset.
override func prepareForReuse() {
super.prepareForReuse()
ProfileImage.image = nil
}

UITableView Checkmark not appearing when selected

I am using a UITableView on button click i am putting the tableview into edit mode I have added
tableView.allowMultiselectionduringedit = true
Here i am getting circles to select the table but no check mark is added when tapped. But code in didselectrow is getting executed
I have attached a picture
What should i change to get the rows selected
Code for didselect
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("Did select Run")
if(isEditing){
let cell = chatTableView.cellForRow(at: indexPath)
cell?.setSelected(true, animated: true)
}else{
let groupMsg = groupMsgList[indexPath.row]
if(groupMsg.messageType == "file")
{
let fileNameString = groupMsg.fileOriginalName
if(fileNameString != nil){
let fileName: NSString = fileNameString! as NSString
let extention = fileName.pathExtension.lowercased()
switch extention {
case "jpg","png","jpeg":
if (groupMsg.senderUserId != LoginStatusInfo.userId){
let row = chatTableView.cellForRow(at: indexPath) as! PhotoReciveCell
chatTableView.beginUpdates()
row.downloadLabel.text = " Downloading... "
row.downloadLabel.sizeToFit()
row.downloadLabelConstraint.constant = 30.0
row.downloadLabel.layoutMargins = UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0)
downloadFileBackground(id: groupMsg.messageId!, fileName: groupMsg.message!, cellIndexPath: indexPath )
chatTableView.endUpdates()
}else{
let row = chatTableView.cellForRow(at: indexPath) as! PhotoSentCell
chatTableView.beginUpdates()
row.downloadLabel.text = " Downloading... "
row.downloadLabel.sizeToFit()
row.downloadLabelConstraint.constant = 30.0
row.downloadLabel.layoutMargins = UIEdgeInsets(top: 2.0, left: 2.0, bottom: 2.0, right: 2.0)
downloadFileBackground(id: groupMsg.messageId!, fileName: groupMsg.message!, cellIndexPath: indexPath )
chatTableView.endUpdates()
}
break
default :
if (groupMsg.senderUserId != LoginStatusInfo.userId){
let row = chatTableView.cellForRow(at: indexPath) as! FileRecieveCell
chatTableView.beginUpdates()
row.downloadStatusIndicator.isHidden = true
row.downloadingIndicator.alpha = 1.0
chatTableView.endUpdates()
}else{
let row = chatTableView.cellForRow(at: indexPath) as! FileSentCell
chatTableView.beginUpdates()
row.downloadStatusIndicator.isHidden = true
row.downloadingIndicator.alpha = 1.0
chatTableView.endUpdates()
}
downloadFileBackground(id: groupMsg.messageId!, fileName: groupMsg.fileOriginalName!, cellIndexPath: indexPath )
break
}
}
}
print(indexPath)
}
}
For CellatRow
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let groupMsg = groupMsgList[indexPath.row]
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressed(_:)))
groupId = groupMsg.groupId
//MARK: MessageType is textmessage
if (groupMsg.messageType == "message")
{
if (groupMsg.senderUserId != LoginStatusInfo.userId)
{
let cell : RecievedMessageCell = chatTableView.dequeueReusableCell(withIdentifier: "recieve") as! RecievedMessageCell
cell.name.text = groupMsg.senderDisplayName
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
// cell.message.sizeToFit()
cell.receiveMessageView.tag = indexPath.row
cell.receiveMessageView.addGestureRecognizer(longPressGesture)
return cell
}
else
{
let cell : SentMessageCell = chatTableView.dequeueReusableCell(withIdentifier: "send") as! SentMessageCell
// cell.sentMessageView.roundCorners(corners: [.topLeft,.topRight,.bottomLeft], radius: 20)
// cell.sentMessageView.layer.masksToBounds = false
cell.sentMessageView.layer.cornerRadius = 10
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
cell.messageStatus.isHidden = false
cell.messageStatus.text = groupMsg.status
// cell.message.sizeToFit()
cell.sentMessageView.tag = indexPath.row
cell.sentMessageView.addGestureRecognizer(longPressGesture)
return cell
}
}
//MARK: Message type is Banner
else if (groupMsg.messageType == "banner") {
let cell : BotBanner = chatTableView.dequeueReusableCell(withIdentifier: "botBanner") as! BotBanner
hasBanner = true
scrollToIndex = indexPath.row
return cell
}
//MARK: Message type is File
else{
if (groupMsg.senderUserId != LoginStatusInfo.userId)
{
//MARK: File Recived
let fileNameString = groupMsg.fileOriginalName
if(fileNameString != nil){
let fileName: NSString = fileNameString! as NSString
let extention = fileName.pathExtension.lowercased()
let cell : FileRecieveCell = chatTableView.dequeueReusableCell(withIdentifier: "fileRecieve") as! FileRecieveCell
let fileUrl = self.getImageURL(forFileName: fileNameString!)
if(fileUrl == nil){
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "fileDonwloadBlack")
}else{
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "downloadedBlack")
}
cell.downloadStatusIndicator.isHidden = false
cell.downloadingIndicator.alpha = 0.0
cell.receiveFileView.layer.cornerRadius = 10
cell.name.text = groupMsg.senderDisplayName
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
cell.fileIcon.image = returnImage(fileName:groupMsg.message!)
cell.receiveFileView.isUserInteractionEnabled = true
cell.receiveFileView.addGestureRecognizer(longPressGesture)
cell.receiveFileView.tag = indexPath.row
return cellname.text = groupMsg.senderDisplayName
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
cell.fileIcon.image = returnImage(fileName:groupMsg.message!)
cell.receiveFileView.isUserInteractionEnabled = true
cell.receiveFileView.addGestureRecognizer(longPressGesture)
cell.receiveFileView.tag = indexPath.row
return cell
}
}
else
{
let cell : FileSentCell = chatTableView.dequeueReusableCell(withIdentifier: "fileSend") as! FileSentCell
let fileUrl = self.getImageURL(forFileName: fileNameString!)
if(fileUrl == nil){
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "fileDownloadWhite")
}else{
cell.downloadStatusIndicator.image = #imageLiteral(resourceName: "downloadedWhite")
}
cell.downloadStatusIndicator.isHidden = false
cell.downloadingIndicator.alpha = 0.0
cell.sendFileView.layer.cornerRadius = 10
cell.name.text = groupMsg.senderDisplayName
cell.message.text = groupMsg.message
cell.time.text = groupMsg.dateSent!
cell.fileStatus.text = groupMsg.status
cell.fileIcon.image = returnImage(fileName:groupMsg.message!)
cell.sendFileView.tag = indexPath.row
cell.sendFileView.addGestureRecognizer(longPressGesture)
cell.sendFileView.isUserInteractionEnabled = true
return cell
}
}
}
}
Solved!
My Mistake was i needed to add cell.setSelectionStype = .default in cellForAtRow
Tableview use dequeueReusableCell , so you can
cell?.setSelected(true, animated: true)
When you scroll tableview , the same cell - reusable from a cell will is selected -> wrong.
In GroupMessage model add property: isSelected . and set
isSelected = true
self.tableview.reloadrowatindexpath ....
when didselected
In cellForRowAt indexPath
If groupMsg.isSelected{
cell?.setSelected(true, animated: true)
}else{
cell?.setSelected(false, animated: true)
}
OR create a NSMutableArray - selectedMessage to hold message selected didSelected add/remove groupmessage in selectedMessage
In cellForRowAt indexPath check selectedMessage contains groupmessage - setSelected = true or no

TableView Cell only refreshes when its scrolled on and off the screen (Firebase observe)

I have a tableview that updates using the observe listener with Firebase.
If I say, change some data, the actual data structure is updated, and I do call tableView.reloadData(), but it only loads the data into the cells when you scroll the cell off the screen visible in the table, and then bring it back on. It's like it then draws the cell now it's come on and off but with the updated data.
How do I make this dynamic?
func getProblems(){
print("getting problems")
let ref = FIRDatabase.database().reference(withPath: "problems")
ref.observe(.value, with: { (snapshot) in
self.problems = []
var newProblems: Array<Problem> = []
let json = JSON(snapshot.value)
//print(json)
for (key, value) in json {
var problemReceived = json[key]
var newProblem = Problem(id: "", user_id: "", title: "", message: "", status: 0, category: 0, image: #imageLiteral(resourceName: "NoImage"), commentCount: 0, distance: 0, date: Date(timeIntervalSinceNow: 5 * 60), user_name: "Derek Sibling", comments: [])
newProblem.id = problemReceived["id"].stringValue
newProblem.user_id = problemReceived["user_id"].stringValue
newProblem.title = problemReceived["title"].stringValue
newProblem.message = problemReceived["message"].stringValue
newProblem.status = problemReceived["status"].intValue
newProblem.category = problemReceived["category"].intValue
newProblem.status = problemReceived["status"].intValue
newProblem.distance = Double(arc4random_uniform(9) + 1)
newProblem.image_url = problemReceived["image_url"].stringValue
newProblem.downloadImage()
newProblem.getComments()
if(newProblem.status != 1){
newProblems.append(newProblem)
}
self.counter = self.counter + 1
if(self.counter == Int(snapshot.childrenCount)){
//self.comments = tempComments
}
}
self.problems = newProblems
self.problems = self.problems.shuffled()
self.tableView.reloadData()
})
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "Cell", for : indexPath) as! CustomCell
cell.titleLabel.text = problems[(indexPath as NSIndexPath).row].getTitle()
cell.descriptionLabel.text = problems[(indexPath as NSIndexPath).row].getMessage()
cell.statusLabel.text = problems[(indexPath as NSIndexPath).row].calculateSolved()
cell.messageCountLabel.text = "\(problems[(indexPath as NSIndexPath).row].comments.count)"
cell.distanceLabel.text = "\(problems[(indexPath as NSIndexPath).row].getDistance())km"
cell.problemImage.image = problems[(indexPath as NSIndexPath).row].getImage()
return cell
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
var cell:CustomCell = cell as! CustomCell
cell.messageCountLabel.text = "\(problems[(indexPath as NSIndexPath).row].comments.count)"
}

Transferring UITableView Section to Another TableView

I am currently set up to transfer section 1 of my tableview to another tableView. This is done by moving the didSelectRow: rows. However, the issue is that when I attempt to move the section when every row is selected (and there is nothing in section 0) it crashes with an index is beyond bounds error.
I am using a boilerPlate code for my sectionHeaders due to section 1 header changing back to section 0 header when all items selected in section 1. I believe this is what is causing the index to be out of bounds error, but am not sure how to correct it.
My sections are set up as:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
let numberOfSections = frc.sections?.count
return numberOfSections!
}
//Table Section Headers
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
let sectionHeader = "Items Needed - #\(frc.sections![section].numberOfObjects)"
let sectionHeader1 = "Items in Cart - #\(frc.sections![section].numberOfObjects)"
if (frc.sections!.count > 0) {
let sectionInfo = frc.sections![section]
if (sectionInfo.name == "0") {
return sectionHeader
} else {
return sectionHeader1
}
} else {
return nil
}
}
with my didSelectRow and cells as:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SLTableViewCell
//assign delegate
cell.delegate = self
let items = frc.objectAtIndexPath(indexPath) as! List
cell.backgroundColor = UIColor.clearColor()
cell.tintColor = UIColor.grayColor()
cell.cellLabel.text = "\(items.slitem!) - Qty: \(items.slqty!)"
cell.cellLabel.font = UIFont.systemFontOfSize(25)
moveToPL.hidden = true
if (items.slcross == true) {
cell.accessoryType = .Checkmark
cell.cellLabel.textColor = UIColor.grayColor()
cell.cellLabel.font = UIFont.systemFontOfSize(20)
self.tableView.rowHeight = 50
moveToPL.hidden = false
} else {
cell.accessoryType = .None
cell.cellLabel.textColor = UIColor.blackColor()
cell.cellLabel.font = UIFont.systemFontOfSize(25)
self.tableView.rowHeight = 60
moveToPL.hidden = true
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let items = frc.objectAtIndexPath(indexPath) as! List
if (items.slcross == true) {
items.slcross = false
} else {
items.slcross = true
}
tableView.reloadData()
}
Is this my issue or is something else causing this?
Edit:
I tried changing my function in charge of moving items from this:
#IBAction func moveToPantry(sender: AnyObject) {
let sectionInfo = self.frc.sections![1]
let objectsToAppend = sectionInfo.objects as! [List]
for item in objectsToAppend {
item.slist = true
item.slcross = false
item.plist = false
item.slitem = item.pitem
item.slqty = item.pqty
item.sldesc = item.pdesc
item.slprice = item.pprice
item.slminqty = item.pminstepperlabel
}
}
to:
#IBAction func moveToSL(sender: AnyObject) {
if (frc.sections!.count > 0) {
let sectionInfo = self.frc.sections![1]
if (sectionInfo.name == "0") {
let objectsToAppend = sectionInfo.objects as! [List]
for item in objectsToAppend {
item.slist = true
item.slcross = false
item.plist = false
item.slitem = item.pitem
item.slqty = item.pqty
item.sldesc = item.pdesc
item.slprice = item.pprice
item.slminqty = item.pminstepperlabel
}
}
}
}
It is still throwing the error. It will move all the objects as long as section 0 isn't empty. Any more help in figuring this out would be appreciated! Thanks in advance.

Two custom cells in UITableView

I'm trying to use two custom cells for displaying the product information, on the first one I show the product main information and in the second one I display the comments of this product.
At the moment everything is linked in the StoryBoard and I have my tableview prepared for storing the comment information in the second custom cell (I have checked the requestComments() function and It's working fine but I can't make them appear.
Is it something related to the numberOfRowsInSection? Because I tried to SUM the products.count with the comments.count and It's showing an error.
It's my first time using two custom cells so I hope someone can help me.
Here is my code:
import UIKit
import Social
class MarcaProductoViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet var productoImageView:UIImageView!
#IBOutlet var tableView:UITableView!
#IBOutlet var votarFrame:UIView!
#IBOutlet var votarBarra:UISlider!
#IBOutlet var votarLabel:UILabel!
var productoImage:String!
var nombre:String!
var producto:Producto!
var productos = [Producto]()
var mensaje:Mensaje!
var mensajes = [Mensaje]()
var img:UIImage?
override func viewDidLoad() {
super.viewDidLoad()
// Set table view background color
self.tableView.backgroundColor = UIColor(red: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 0.2)
// Remove extra separator
self.tableView.tableFooterView = UIView(frame: CGRectZero)
// Change separator color
self.tableView.separatorColor = UIColor(red: 240.0/255.0, green: 240.0/255.0, blue: 240.0/255.0, alpha: 0.8)
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 88.0
requestPost()
requestComments()
tableView.reloadData()
}
override func viewDidAppear(animated: Bool) {
tableView.reloadData()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.hidesBarsOnSwipe = false
self.navigationController?.setNavigationBarHidden(false, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func requestPost () {
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.website.es/product.php")!)
request.HTTPMethod = "POST"
let postString = "name="+name
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
self.productos = self.parseJsonData(data!)
// Reload table view
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
task.resume()
tableView.reloadData()
}
func parseJsonData(data: NSData) -> [Producto] {
var productos = [Producto]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Parse JSON data
let jsonProductos = jsonResult?["lista_productos"] as! [AnyObject]
for jsonProducto in jsonProductos {
let producto = Producto()
producto.image = jsonProducto["image"] as! String
producto.name = jsonProducto["name"] as! String
producto.desc = jsonProducto["desc"] as! String
productos.append(producto)
}
}
catch let parseError {
print(parseError)
}
return productos
}
func requestComments () {
//print("Hola")
let request = NSMutableURLRequest(URL: NSURL(string: "http://www.website.es/comments.php")!)
request.HTTPMethod = "POST"
let postString = "name="+name
//print(postString)
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
if error != nil {
print("error=\(error)")
return
}
let responseString = NSString(data: data!, encoding: NSUTF8StringEncoding)!
print("mensajes = \(responseString)")
self.mensajes = self.parseJsonDataComments(data!)
// Reload table view
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
task.resume()
tableView.reloadData()
}
func parseJsonDataComments(data: NSData) -> [Mensaje] {
var messages = [Mensaje]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Parse JSON data
let jsonProductos = jsonResult?["messages"] as! [AnyObject]
for jsonProducto in jsonProductos {
let message = Mensaje()
message.author = jsonProducto["author"] as! String
message.message = jsonProducto["message"] as! String
message.date = jsonProducto["date"] as! String
messages.append(message)
}
}
catch let parseError {
print(parseError)
}
return message
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return productos.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
title = productos[indexPath.row].nombre
if indexPath.row == 0 {
print("11")
let cell = tableView.dequeueReusableCellWithIdentifier("CellDetail", forIndexPath: indexPath) as! ProductoTableViewCell
cell.selectionStyle = .None
if let url = NSURL(string: productos[indexPath.row].imagen) {
if let data = NSData(contentsOfURL: url) {
self.productoImageView.image = UIImage(data: data)
}
}
cell.name.text = productos[indexPath.row].name
cell.desc.text = productos[indexPath.row].desc
cell.layoutIfNeeded()
return cell
}
else {
print("22")
let cell2 = tableView.dequeueReusableCellWithIdentifier("MostrarComentarios", forIndexPath: indexPath) as! ComentariosTableViewCell
cell2.selectionStyle = .None
cell2.author.text = mensajes[indexPath.row].author
cell2.comment.text = mensajes[indexPath.row].comments
cell2.date.text = mensajes[indexPath.row].date
cell2.layoutIfNeeded()
return cell2
}
} }
Update:
I have made the following changes:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// Return the number of sections.
return productos.count+mensajes.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of rows in the section.
return productos.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
title = productos[indexPath.row].nombre
if indexPath.section == 0 {
print("11")
let cell = tableView.dequeueReusableCellWithIdentifier("CellDetail", forIndexPath: indexPath) as! ProductoTableViewCell
cell.selectionStyle = .None
if let url = NSURL(string: productos[indexPath.row].imagen) {
if let data = NSData(contentsOfURL: url) {
self.productoImageView.image = UIImage(data: data)
}
}
cell.nombre.text = productos[indexPath.row].nombre
cell.descripcion.text = productos[indexPath.row].descripcion
cell.modo_de_empleo.text = productos[indexPath.row].modo_de_empleo
cell.marca.text = productos[indexPath.row].marca
cell.linea.text = productos[indexPath.row].linea
cell.distribuidor.text = productos[indexPath.row].distribuidor
cell.tamano.text = productos[indexPath.row].tamano
cell.precio.text = productos[indexPath.row].precio
cell.codigo_nacional.text = productos[indexPath.row].codigo_nacional
cell.layoutIfNeeded()
return cell
}
else {
let cell2 = tableView.dequeueReusableCellWithIdentifier("MostrarComentarios", forIndexPath: indexPath) as! ComentariosTableViewCell
print(mensajes[indexPath.row].mensaje)
cell2.selectionStyle = .None
cell2.comentario.text = mensajes[indexPath.row].mensaje
cell2.fecha.text = mensajes[indexPath.row].fecha
cell2.layoutIfNeeded()
return cell2
}
}
At the moment, I can display the comments perfectly, but the problem is that the messages from this product are always the same (repeated in every new comment row) I just need to change something (I don't know what exactly) to show the correct information for the messages without beeing duplicated.
Thanks in advance.
I think you have to use return products.count
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return products.count
}
And you have to use % 2 == 0 instead of == 0
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
title = productos[indexPath.row].nombre
if indexPath.row % 2 == 0 { // runs if indexPath.row = 0, 2, 4, 6 etc
let cell = tableView.dequeueReusableCellWithIdentifier("CellDetail", forIndexPath: indexPath) as! ProductoTableViewCell
return cell
} else { // runs if indexPath.row = 1, 3, 5, 7 etc
let cell2 = tableView.dequeueReusableCellWithIdentifier("MostrarComentarios", forIndexPath: indexPath) as! ComentariosTableViewCell
return cell2
}
}
Remainder Operator
The remainder operator (a % b) works out how many multiples of b will
fit inside a and returns the value that is left over (known as the
remainder).
Here’s how the remainder operator works. To calculate 9 % 4, you first
work out how many 4s will fit inside 9:
You can fit two 4s inside 9, and the remainder is 1 (shown in orange).
In Swift, this would be written as:
9 % 4 // equals 1
If someone has the same problem:
else {
let cell2 = tableView.dequeueReusableCellWithIdentifier("MostrarComentarios", forIndexPath: indexPath) as! ComentariosTableViewCell
cell2.selectionStyle = .None
cell2.comentario.text = mensajes[(indexPath.section)-1].mensaje
cell2.fecha.text = mensajes[(indexPath.section)-1].fecha
cell2.layoutIfNeeded()
return cell2
}
Regards,

Resources