I have a tableView with custom cells and my goal is to be able to click on one and print the number of the current row.
Right now when I click on a cell not happens and I can't understand why.
This is the code:
//MARK: - UITableDataSource
extension ChannelViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return groupResult.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let group = groupResult[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: K.cellContactNibName, for: indexPath) as! ContactCell
cell.usernameLabel.text = group.name
cell.messageLabel.text = group.recentMessage
let storage = Storage.storage()
let storageRef = storage.reference()
// Reference to an image file in Firebase Storage
let reference = storageRef.child("imagesFolder/\(group.image)")
// UIImageView in your ViewController
let imageView: UIImageView = cell.uImage
// Placeholder image
let placeholderImage = UIImage(named: "MeAvatar")
// Load the image using SDWebImage
imageView.sd_setImage(with: reference, placeholderImage: placeholderImage)
cell.uImage.image = imageView.image
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("You selected cell #\(indexPath.row)!")
}
}
and as you can see in the screen the single selection is enabled:
change to
extension ChannelViewController: UITableViewDataSource, UITableViewDelegate
or move the method into another extension conformed to UITableViewDelegate
also, remember to set the tableView's delegate to the ChannelViewController
Related
Hi I'm making an app with UIkit and I'm having a problem trying to achieve the layout of a cell.
What I want is to make a cell that has an image header, a stack of user images, and a label. I place this cell in a UITableView. The problem I'm having is that the image header is optional so if it's not there I need it to display like the cell shown below in the attached image.
Can someone who has more knowledge in UIkit help me please?
let suppose you have struct that use to populate tableview
struct User {
let name:String
let headerImage:UIImage? // an optional image
}
your controller
class ViewController:UIViewController {
var users = [User]()
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let image = users[indexPath.row].image {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserHeaderCell", for: indexPath) as! UserHeaderCell
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "UserSimpleCell", for: indexPath) as! UserSimpleCell
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if let image = users[indexPath.row].image {
return 100 // with image
}
return 50 // without image
}
}
make two cell one for header image and one for simple
class UserHeaderCell:UITableViewCell {
}
class UserSimpleCell:UITableViewCell {
}
I have a UITableView.
I can select multiple cells make them highlighted.
But, whenever I reload App, the selected and highlighted state disappears.
I think I need to put some codes in 'viewDidAppear' and 'didSelectRowAt'. But I don't have any idea of specific codes.
What do I have to put in this syntax?
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
}
I recommend u add to dataSource item field selected, and in method cellForRowAtindexPath configure by your dataSource items.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cellClass = (self.cellClass(for: indexPath) ?? self.cellClasses.first) else { return UITableViewCell() }
let cell = tableView.dequeueReusableCell(withIdentifier: cellClass.identifier, for: indexPath)
if let configurable = cell as? ConfigurableComponent, let object = self.object(at: indexPath) {
let item = self.dataSource[indexPath.row]
configurable.selected = item.selected
}
return cell
}
When call didSelectRowAt, just take item and change selected field, sample:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let item = self.dataSource[indexPath.row]
item.selected = !item.selected
tableView.reloadData()
}
I have an array which i show as dequeueReusableCell, I'd like to show an appropriate image next to the cell. My images are the same name like items in array located in Assets.
How do I show an appropriate image in dequeueReusable cell?
My code:
import UIKit
class Nicosia: UIViewController, UITableViewDelegate, UITableViewDataSource {
let nicosiaPlaces = ["Famagusta Gate", "Laiki Geitonia", "Ledra Street","Omeriye Hamam","Cyprus Museum","Venetian Walls","The House of Hatjigeorgakis Kornessios","Byzantine Art Museum","Archbishop's Palace","Liberty Monument","The Faneromeni Church","Nicosia International Conference Center"]
var identities = ["Famagusta Gate", "Laiki Geitonia", "Ledra Street","Omeriye Hamam","Cyprus Museum","Venetian Walls","The House of Hatjigeorgakis Kornessios","Byzantine Art Museum","Archbishop's Palace","Liberty Monument","The Faneromeni Church","Nicosia International Conference Center"]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return nicosiaPlaces.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
let city = nicosiaPlaces [indexPath.row]
cell?.textLabel?.text = city
//cell.imageCellNicosia?.image = UIImage(named: city)
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vcName = identities[indexPath.row]
let viewController = storyboard?.instantiateViewController(withIdentifier: vcName)
self.navigationController?.pushViewController(viewController!, animated: true)
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
}
If you have a custom table cell class cast this
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! MyCellClass
cell.imageCellNicosia?.image = UIImage(named: city)
if not use build in imageView property of UITableViewCell
cell.imageView?.image = UIImage(named: city)
below code supposed to call usernames from an array and user able to tap on the desired username. call to that array is a success and I can see the usernames but won't able to tap into it. and it don't even print "didSelectRowAt". appreciate your help. thanks.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifier", for: indexPath) as! MentionUserCell
cell.username!.text = autoComplete[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return autoComplete.count
}
func numberOfSections(in tableView: UITableView) -> Int
{
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let selectedCell: MentionUserCell = tableView.cellForRow(at: indexPath)! as! MentionUserCell
let selectedWord: String = selectedCell.username!.text! + " "
print("didSelectRowAt")
var string: NSString = NSString(string: self.commentTextView.text!)
string = string.replacingCharacters(in: otoCadang.sharedInstance.foundRange, with: selectedWord) as NSString
// change text field value
commentTextView.text = string as? String
// change cursor position
let positionOriginal = commentTextView.beginningOfDocument
if let cursorLocation: UITextPosition = self.commentTextView.position(from: positionOriginal, offset: otoCadang.sharedInstance.foundRange.location + selectedWord.characters.count)
{
self.commentTextView.selectedTextRange = self.commentTextView.textRange(from: cursorLocation, to: cursorLocation)
}
// remove suggestion
self.autoComplete.removeAll()
self.tableView.reloadData()
tableView.isHidden = true
}
Check List
tableview delegate is set properly
tableview selection mode == No Selection, then change to single selection
function name is correct func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
are you using any tap gesture on this view? remove it.
If you are editing UITextView will can't call to `didselectRowAt. Try to get the Your MentionUserCell, IndexPath in UITextView's methods and handle there. Example:
func textViewDidChange(_ textView: UITextView) {
var parentView = textView as UIView
while !(parentView is UITableViewCell) {
parentView = parentView.superview!
}
if let cell: MentionUserCell = parentView as? MentionUserCell {
if let indexPath = self.tableView.indexPath(for: cell) {
let yourIndexPath = indexPath
}
}
//your code
}
Hope it will help you.
When are using two or more cells the didSelectRow method is not working Well. You can use a button in cell.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cellIdentifierName", for: indexPath) as! MentionUserCell
cell.username!.text = autoComplete[indexPath.row]
let button = cell.viewWithTag(101) as! UIButton
button.cellclick.addTarget(self, action: #selector(functionName(sender:)), for: .touchDown)
return cell
}
Now you get the indexPath:-
func functionName(sender:UIButton) {
let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableview)
let indexPath = self.tableview.indexPathForRow(at: buttonPosition)
print(indexPath.row)
}
I am using firebase database and have a table view showing name, age, location, and image of user at index path.row. How would I go about showing another view when the cell is clicked to the users profile with more information and photos of the user. here is the code for my tableView.
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return userList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "prefCell", for: indexPath) as! SFPTableViewCell
let user = userList[indexPath.row]
cell.name.text = userList[indexPath.row].name
cell.location.text = userList[indexPath.row].location
if let imageURL = user.image {
cell.imageOne.loadImageUsingCacheWithUrlString(urlString: imageURL)
}
return cell
}
}
Using Code use didSelectRowAtIndexPath.
or
Using Storyboard:
step 1: select tableview cell.
step 2: Control + click mouse and drag in destination view.
step 3: Give Any of segue.
step 4: Done.
Add this below code
override func tableView(_ tableView: UITableView, didSelectRowAtindexPath: IndexPath){
let detailVC = storyboard.instantiateViewControllerWithIdentifier("MyDetailVC") as MyDetailVC // get the obect of other VC
detailVC.myImage = <your_image> // assign your image which you wanted to send to other VC.
self.navigationController?.pushViewController(detailVC,animated: true // Push to other VC
}
in MyDetailVC.swift
var myImage : UIImage? // Create variable of image type in required VC where you wanted to send data
Now use your Image in MyDetailVC.swift.
Any further query you can ask.
Just used UITableViewDelegate method "didSelectRowAtIndexPath" and send image to other view controller with its indexPath
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let sb = UIStoryboard(name: "Main", bundle: nil)
let detailVC = sb.instantiateViewController(withIdentifier: "ImageVC") as! DetailViewController
detailVC.strImage = self.arrImage[indexPath.row]
self.navigationController?.pushViewController(detailVC, animated: true)
}
In DetailViewController take one variable
var strImage : String = ""
and assgin this variable to UIImagView
imgView.image = UIImage(named: strImage)