Modify cell contents in tableview after clicking in Swift - swift

I have a chat app with 2 custom cells, sender and receiver cell. Once the cells are populated, only the ones with "show image" text can be clicked. I am trying to click on these cells so that
i can hide the label
I can show the image from the url
The tap function works but i am not able to do the above steps. Kindly help because i do not know how to go about this
Here is my code
#objc
func tapFunctionCell(sender:UITapGestureRecognizer) {
print("tap again sen")
let tapLocation = sender.location(in: tblViewChat)
let indexPath = self.tblViewChat.indexPathForRow(at: tapLocation)
let position = indexPath?.row ?? 0
print(position)
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "senderCell") as! SenderTblCell
cell.lblMessage.isHidden = true
let url = URL(string:objChatVM.getMessage(index:position))
print(url)
cell.ImageB.kf.setImage(with:url)
cell.ImageB.isHidden = false
}
#objc
func tapFunction(sender:UITapGestureRecognizer) {
print("tap again receive")
let cell2 = tblViewChat.dequeueReusableCell(withIdentifier: "receiverCell") as! ReceiverTblCell
cell2.lblMessage.isHidden = false
let tapLocation = sender.location(in: tblViewChat)
let indexPath = self.tblViewChat.indexPathForRow(at: tapLocation)
let position = indexPath?.row ?? 0
print(position)
let url = URL(string:objChatVM.getMessage(index:position))
print(url)
cell2.imageButton.kf.setImage(with:url)
cell2.imageButton.isHidden = false
}

Issues in your tap function code. When you want to get a cell from the index path use the cellForRow method of table view. so instead of this
let cell = tblViewChat.dequeueReusableCell(withIdentifier: "senderCell") as! SenderTblCell
use this for both tap action.
let cell = tblViewChat.cellForRow(at: indexPath) as! SenderTblCell

Related

Getting tableview cell value nil in swift

I have tableview with 3 sections. Every section has a row. In my simulator screen only 2 sections are showing . If I will scroll the table view the third cell will be shown. There is a save button, by clicking it I am passing data to another view controller. If I will not scroll the tableview and click the save button then the cell of third section is nil.
My code is:-
let indexPath = IndexPath(row: 0, section: 0)
let indexPath1 = IndexPath(row: 0, section: 1)
let indexPath2 = IndexPath(row: 0, section: 2)
let cell1 = tableView.cellForRow(at: indexPath) as? PatientInformationTableViewCell
let cell2 = tableView.cellForRow(at: indexPath1) as? PatientAdressTableViewCell
let cell3 = tableView.cellForRow(at: indexPath2) as? OtherInfoTableViewCell
guard let name = nameTextField.text,
let id = cell1.patientTextField.text,
let dob = cell1.dobTextField.text,
let street = cell1.streetAdressTextField.text,
let city = cell2.cityTextField.text,
let state = cell2.stateTextField.text,
let zip = cell2.zipTextField.text,
let country = cell2.CountryTextField.text,
let practioner = cell3.practionerTextField.text,
let lcode = cell3.lcodeTextField.text,
let qty = cell3.qtyTextField.text,
let prescription = cell3.PrescriptionTextView.text,
let klLevel = cell3.kLevelTextField.text,
let deviceType = cell3.deviceTypeTextField.text,
let guardian = cell3.guardianTextField.text,
let relationship = cell3.relationshipwithPatient.text
else {
return
}
let patient = PatientInformationModel(name: name, id: id, dob: dob, streetAdress: street, city: city, state: state, zip: zip, country: country, klevel: klLevel, deviceType: deviceType, visitType: "visitType", deliveryLocation: "deliveryLocation", lCode: lcode, qty: qty, descripePrescription: prescription, practioner: practioner, guardian: guardian, relationship: relationship)
let encoder = JSONEncoder()
if let encoded = try? encoder.encode(patient) {
let defaults = UserDefaults.standard
defaults.set(encoded, forKey: "SavedPerson")
}
if let storyBoard = UIStoryboard(name: "Pdf", bundle: nil) as? UIStoryboard{
captureSignature { (sign) in
signatureImage = sign?.image
print("signature image is \(signatureImage)")
}
let PatientListViewController = storyBoard.instantiateViewController(identifier: "GeneratePdfViewController") as? GeneratePdfViewController
PatientListViewController?.signatureImage = signatureImage
self.navigationController?.pushViewController(PatientListViewController!, animated: true)
}
in this above code, if i am clicking on save button without scrolling to bottom , i am getting cell3 value nil.Is there any soution. please help me.

If there is a like button next to each user, why could scrolling trigger random users' like buttons be highlighted?

I use self.like.alpha = 0.5 to grey out the like button next to the user who was liked. Scrolling causes the highlight to sometimes disappear and appear next to other users.
I've used self.like.alpha = 0.5 last various places in the code but it changes nothing.
#IBAction func likePressed(_ sender: Any) {
self.like.alpha = 0.5
let ref = Database.database().reference()
let keyToPost = ref.child("likes").childByAutoId().key
ref.child("humans").child(self.postID).observeSingleEvent(of: .value, with: {(snapshot) in
if let humans = snapshot.value as? [String: AnyObject] {
let updateLikes: [String: Any] = ["humansWhoLike/\(keyToPost)" : Auth.auth().currentUser!.uid]
ref.child("humans").child(self.postID).updateChildValues(updateLikes, withCompletionBlock: { (error, reff) in
if error == nil {
ref.child("humans").child(self.postID).observeSingleEvent(of: .value, with: { (snap) in
if let properties = snap.value as?[String: AnyObject]{
if let likes = properties["humansWhoLike"] as? [String : AnyObject] {
let count = likes.count
let update = ["likes" : count]
ref.child("humans").child(self.postID).updateChildValues(update)
}
}
})
}
})
}
})
ref.removeAllObservers()
}
What I need is for the like button that is clicked to be greyed out. It has to stay greyed out and the greying out should not jump to another user's like button.
/Updated code after 1st answer
public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ViewControllerTableViewCell
let like = cell.viewWithTag(3) as! UIButton
let immy = cell.viewWithTag(1) as! UIImageView
let person: Userx = humans[indexPath.row]
cell.lblName.text = person.Education
cell.postID = self.humans[indexPath.row].postID
if let PhotoPosts = person.PhotoPosts {
let url = URL(string: PhotoPosts)
immy.sd_setImage(with: url)
}
return cell
}
Remember that tableView cells are reusable. When you dequeue one, you cannot assume anything about the existing values. If you mark a cell liked (with button formatting), when that cell is reused, the formatting is still there.
When you dequeue a cell in your cellForRowAt function, you need to reset all the values according to your data store.
I am having a little trouble understanding your database design/usage, but based on the code you added to the post:
let currUser = Auth.auth().currentUser!.uid // better to add this as a VC level variable as you will do this lookup a lot.
let likeArray = person.humansWhoLike ?? []
let likeStatus = likeArray.contains(currentUser)
//from your code, 'like' is the button to be formatted
like.alpha = likeStatus ? 0.5 : 1.0

Failure while attempt to find specific cell in table view swift

I want to find specific cell class in my table view. I use following code:
func setConfirmEnabledIfNeed(){
let ip = IndexPath(row: 8, section: 0)
if let cell = tableView.cellForRow(at: ip) as? ConfirmBtnCell {
print("find confirm cell")
}
let c = tableView.cellForRow(at: ip) as? ConfirmBtnCell
print("type of cell \(type(of: c))")
}
print("find confirm cell") is never called, however, second print output: type of cell Optional<ConfirmBtnCell>, what is obviously what i need. But why first print not called?
My cell for row look like this:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = viewModel.items[indexPath.row]
switch item {
case .selectable(let value, let placeholder, let type):
let selectionCell = tableView.dequeueReusableCell(withIdentifier: "SelectionCell") as! SelectionCell
if let placeholder = placeholder { selectionCell.setPlaceholder(placeholder) }
if let text = value as? String, !text.isEmpty { selectionCell.hidePlaceholder();
selectionCell.textLbl.text = text }
if let date = value as? Date { selectionCell.hidePlaceholder();
selectionCell.textLbl.text = DateFormatterUtil.getReadableStringFromDate(date) }
return selectionCell
case .back:
return tableView.dequeueReusableCell(withIdentifier: "BackBtnCell") as! BackBtnCell
case .confirm:
return tableView.dequeueReusableCell(withIdentifier: "ConfirmBtnCell") as! ConfirmBtnCell
case .editableNumbers(let text, let placeholder, let type):
let editableCell = tableView.dequeueReusableCell(withIdentifier: "TextEditCell") as! TextEditCell
editableCell.setup(isNumerical: true)
if let placeholder = placeholder { editableCell.setPlaceholder(placeholder) }
if let text = text {editableCell.hidePlaceholder(); editableCell.txtf.text = text }
editableCell.textChanged = {[weak self] text in
guard let text = text else { return }
if type == .sumCash {
self?.viewModel.collectedInfo[CorrectionChequeViewModel.infoKeys.sumCash.rawValue] = text
self?.setConfirmEnabledIfNeed()
}
if type == .sumElectronic {
self?.viewModel.collectedInfo[CorrectionChequeViewModel.infoKeys.sumElectronic.rawValue] = text
}
}
return editableCell
case .editableText(let text, let placeholder, let type):
let editableCell = tableView.dequeueReusableCell(withIdentifier: "TextEditCell") as! TextEditCell
editableCell.setup(isNumerical: false)
if let placeholder = placeholder { editableCell.setPlaceholder(placeholder) }
if let text = text {editableCell.hidePlaceholder(); editableCell.txtf.text = text }
editableCell.textChanged = {[weak self] text in
guard let text = text else { return }
if type == .sumCash {
self?.viewModel.collectedInfo[CorrectionChequeViewModel.infoKeys.description.rawValue] = text
}
if type == .sumElectronic {
self?.viewModel.collectedInfo[CorrectionChequeViewModel.infoKeys.number.rawValue] = text
}
}
return editableCell
default:
return UITableViewCell()
}
}
UPDATE:
I find that code work if it's not called from table view cellForRow method. I tried to launch that block of code with dispatch_after, and it works.
In your if statement, the value for tableView.cellForRow(at: ip) as? ConfirmBtnCell is nil, so you never enter the block.
In the second statement (let c = tableView.cellForRow(at: ip) as? ConfirmBtnCell), the value of c is an Optional<ConfirmBtnCell>. If you unwrap the optional, you will see that its unwrapped value is also a nil.
If your row is not visible, tableView.cellForRow will return a nil even when the cell is set. See the Apple Documentation.

Detail view data confusing when peek

Im trying to implement 3D touch support for my app and I'm encountering some issues at the moment
//3D Touch - Peek
func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
guard let indexPath = tableView.indexPathForRow(at: location),
let cell = tableView.cellForRow(at: indexPath) as? CustomCell else {return nil}
let identifier = "TemplateTestViewController"
guard let BarVC = storyboard?.instantiateViewController(withIdentifier: identifier) as?
TemplateTestViewController else { return nil }
//Set Ups the Image Template :
BarVC.HeaderprofileImage?.image = UIImage(named: ProfileImages[indexPath.row] + "jpg")
//Sets Up Bar Or Club Text :
BarVC.BarOrClubLabel?.text = ProfileBarOrClub[MyIndex]
//Sets Up Age Text :
BarVC.AgeLabel.text = AgeText[MyIndex]
//Sets Up Phone Number Text :
BarVC.ProfilePhoneNumberLabel?.setTitle(ProfilePhoneNumbers[indexPath.row], for: .normal)
if #available(iOS 9.0, *) {
previewingContext.sourceRect = cell.frame
} else {
// Fallback on earlier versions
}
return BarVC
}
As you can see I'm trying to change the data between each cells with MyIndex which is basically indexPath.row. I don't get any errors and yet when i run the app the data isn't changed between different cells being peeked...
any help will be really appreciated !

Update label in custom UITableView Cell

I need to Update an label by clicking on an Button in the same cell. Why does my code doesn't work ?
#IBAction func actionFaveUnfave(sender: AnyObject) {
let cell = self.tableView.cellForRowAtIndexPath(sender.indexPath)
println(cell?.labelFavedTimes)
cell.labelFavedTimes = "22"}
cell?.labelFavedTimes.text = "22"
BTW
self.tableView.cellForRowAtIndexPath(sender.indexPath)
can return nil if cell is not visible
I solved the problem by using superview...here is my solution:
let button = sender as! UIButton
let view = button.superview!
let cell = view.superview as! TableViewCellHome
let indexPath = tableView.indexPathForCell(cell)
println(indexPath)
if(indexPath != nil){
var cell = self.tableView.cellForRowAtIndexPath(indexPath!) as! TableViewCellHome
cell.labelFavedTimes.text = favedTimesInt + " Faves"
}
cell.labelFavedTimes.text = "22"