I'm trying to create a custom cell view with some labels, I have created a subclass of UITableViewCell and connected the labels to it. Inside cellForRowAt method I dequeued the cell and cast it as YourCell subclass to access the labels and set text.
Setting class of cell to YourCell
However when running the app, nothing is showing up.
class YourCell: UITableViewCell {
#IBOutlet weak var label1: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label3: UILabel!
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let array1 = ["Name1", "Name2","Name3","Name3"]
let array2 = ["1","2","3","4"]
let array3 = ["18","17","11","9"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.delegate = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCell(withIdentifier: "cell") as! YourCell
cell.label1.text = array1[indexPath.row]
cell.label2.text = array2[indexPath.row]
cell.label3.text = array3[indexPath.row]
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array2.count
}
}
You have conformed the UITableViewDelegate protocol correctly, the only thing you are missing is to set up your datasource by including this line in your viewDidLoad.
tableview.dataSource = self
Related
I've created a tableView, but when I click it, I don't get any results. I wanted to add a new feature to improve my project, but I couldn't add the videos I watched and the things I researched.
Table View
import UIKit
class ViewController1: UIViewController {
#IBOutlet weak var FoodView: UITableView!
let dogfoods = ["pork", "banana", "chicken-leg"]
override func viewDidLoad() {
super.viewDidLoad()
FoodView.delegate = self
FoodView.dataSource = self
// not tapped no see
FoodView.allowsSelection = false
}
}
extension ViewController1: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 120
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dogfoods.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = FoodView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
let dogfood = dogfoods[indexPath.row]
cell.foodImageView.image = UIImage(named: dogfood)
cell.nameLabel.text = dogfood
return cell
}
}
CustomCell
class CustomCell: UITableViewCell {
#IBOutlet weak var dogView: UIView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var foodImageView: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
When I click on one of the cells in the picture, I want to write a larger version of the picture and a description, how can I do this? When I searched on the internet, I applied similar ones, but I couldn't get any results.
You have a few choices. You can add one or more buttons to your custom cell. You can attach a tap gesture recognizer to your cell's content view.
Probably the easiest way to respond to a tap on the whole cell is to have view controller conform to the UITableViewDelegate protocol and implement the tableView(_:didSelectRowAt:) method.
That method will be called when the user selects a cell, and you would use the indexPath of the tapped cell to figure out which one was tapped and do whatever is appropriate.
You can do that with easy and efficient way using Delegate in Swift
//create protocol as we used interface in Java
#objc protocol TableViewCellDelegate {
#objc func click(indexPath: IndexPath?)
}
// Modify your class CustomCell as:
#IBOutlet weak var dogView: UIView!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var foodImageView: UIImageView!
var delegate: TableViewCellDelegate?
var indexPath: IndexPath?
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
foodImageView.isUserInteractionEnabled = true
foodImageView.addGestureRecognizer(tapGestureRecognizer)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
#objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer) {
let tappedImage = tapGestureRecognizer.view as! UIImageView
self.delegate.click?(indexPath: self.indexPath)
}
// Modify your tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) in ViewController1 as
let cell = FoodView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.delegate = self
cell.indexPath = indexPath
let dogfood = dogfoods[indexPath.row]
cell.foodImageView.image = UIImage(named: dogfood)
cell.nameLabel.text = dogfood
return cell
// And now add extension add the end of ViewController1
extension ViewController1: TableViewCellDelegate {
func click(indexPath: IndexPath?) {
// open image for preview here
}
}
You can do it in many ways
use a add a UITableViewDelegate method which is
override func tableView(_ tableView: UITableView, didSelectRowAt
indexPath: IndexPath){
//your code...
}
it will called every time when cell clicked.
if you prefer to trigger any button click rather then cell click then go for delegate (Izaan Saleem already explained), or you can use NotificationCenter, but for this task I prefer didSelect or delegate solution.
I already make an array to access the picture.. Can someone help? thanks
Here is my code:
import UIKit
class MainMenuViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let labeltitle = ["Acme De la Vie Tee", "Anti Social Social Club Black Hoodie", "CDG Play Gold Black Tee"]
let labelprice = [("RM 240"), ("RM 305"), ("RM 418")]
let myImage = [UIImage(named: "adlv1"), UIImage(named: "assc"), UIImage(named: "cdg1")]
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return labeltitle.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MainMenuTableViewCell
cell.label11?.text = labeltitle[indexPath.row]
cell.label2?.text = labelprice[indexPath.row]
cell.myImage.image = self.myImage[indexPath.row]
return cell
}
}
Here is my code for MainMenuTableViewCell
import UIKit
class MainMenuTableViewCell: UITableViewCell {
#IBOutlet weak var label11: UILabel!
#IBOutlet weak var label3: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var myImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
you need to register your tableviewcell in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.register(MainMenuTableViewCell.self, forCellReuseIdentifier: "cell")
}
Apple Documentation
More Info
Did u add constraint ?
Select to viewController and do reset the suggested constraint and im sure it will be solved
cell.myImage.image = self.myImage[indexPath.row]
try to change your image Array name
I don't know why I can't view my pets in the table.
Few days ago the app is working perfect but when I updated the last version of Xcode the app crashed, I can't see the data whet the App run.
I new developer in swift
Help me, please.
------------------------------Model------------------------
import UIKit
struct InfoPet{
let PetPicture: String
let PetBackground: String
let PetName: String
let PetAge: String
static func InfoPets() -> [InfoPet]{
let pet1 = InfoPet(PetPicture: "Drako", PetBackground: "Background Can", PetName: "Drako", PetAge: "2 years old")
let pet2 = InfoPet(PetPicture: "Lucky", PetBackground: "Background Cat", PetName: "Lucky", PetAge: "3 years old")
return [pet1, pet2]
}
}
-----------------------TableViewController----------------
class PetsTableViewController: UITableViewController {
// MARK: - Global Var
var pets: [InfoPet] = InfoPet.InfoPets()
// MARK: - UITableViewDataSource
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return pets.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "PetCell", for: indexPath) as! PetsTableViewCell
let pet = pets[indexPath.row]
cell.pet = pet
return cell
}
// MARK: - UITableViewDalegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
}
-----------------------tableViewCell-----------------------
class PetsTableViewCell: UITableViewCell {
#IBOutlet weak var ImgPhotoPet: UIImageView!
#IBOutlet weak var ImgBackgroundPet: UIImageView!
#IBOutlet weak var LblNamePet: UILabel!
#IBOutlet weak var LblAgePet: UILabel!
var pet: InfoPet!{
didSet{
updateUI()
}
}
func updateUI() {
ImgBackgroundPet.image = UIImage(named: pet.PetBackground)
ImgPhotoPet.image = UIImage(named: pet.PetPicture)
ImgPhotoPet.layer.cornerRadius = 10.0
ImgPhotoPet.layer.masksToBounds = true
LblNamePet.text = pet.PetName
LblAgePet.text = pet.PetAge
}
}
Add Cell Identifier as "PetCell"
and add viewDidLoad method in PetsTableViewController class.
create IBOutlet of the table view.
#IBOutlet weak var tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
}
IĀ“have a table view with a custom cell. In this cell I have two buttons that are used for counting. One pluss button, and one minus button. These buttons should increment and decrease a counterLabel with 1.
I have done this in a project I did a long time ago, but then I used extensions, witch I don't do in this project. My problem is that I cannot figure out how to implement the delegate method that I used in the previous project.
I will show the code I'm trying, as an extension. This gives the error "Ambiguous reference to member 'tableView(_:numberOfRowsInSection:)'".
How should I correctly implement the delegate?
Main View Controller
import UIKit
class MainViewController: UIViewController, UITableViewDelegate {
let staticList: [ListItem] =
[
ListItem(item1: "item1", item2: "item2", item3: "item3")]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return staticList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell: UITableViewCell
cell = tableView.dequeueReusableCell(withIdentifier: "MenuCell", for: indexPath)
if let customCell = cell as? MenuCell
{
let itemIndex = indexPath.row
let listItem = staticList[itemIndex]
customCell.item1Label.text = listItem.item1
customCell.item2Label.text = listItem.item2
customCell.item3Label.text = listItem.item3
customCell.counterLabel.text = "\(listItem.count)"
}
return cell
}
}
#IBOutlet weak var mainTableView: UITableView!
}
extension MainViewController: CountDelegate {
func didAddItemCell(cell: MainCell) {
let indexPath = tableView.indexPath(for: cell)!
staticList[indexPath.row].count += 1
cell.countLabel.text = "\(staticList[indexPath.row].count)"
}
func didSubtractItemCell(cell: MenuCell) {
let indexPath = tableView.indexPath(for: cell)!
if staticList[indexPath.row].count > 0 {
staticList[indexPath.row].count -= 1
cell.countLabel.text = "\(staticList[indexPath.row].count)"
}
}
}
Table View Cell file
import Foundation
import UIKit
protocol CountDelegate: NSObjectProtocol {
func didAddItemCell(cell: MainCell)
func didSubtractItemCell(cell: MainCell)
}
class MenuCell : UITableViewCell
{
#IBOutlet weak var item1Label: UILabel!
#IBOutlet weak var item2Label: UILabel!
#IBOutlet weak var item3Label: UILabel!
#IBOutlet weak var counterLabel: UILabel!
#IBOutlet weak var minusButton: UIButton!
#IBOutlet weak var plusButton: UIButton!
weak var delegate: CountDelegate?
#IBAction func minusButton(_ sender: UIButton)
{
delegate?.didAddItemCell(cell: self)
}
#IBAction func plusButton(_ sender: UIButton)
{
delegate?.didSubtractItemCell(cell: self)
}
}
The numberOfRowsInSection and cellForRowAt methods are not part of the UITableViewDelegate protocol but the UITableViewDataSource protocol. You therefore need to change add that protocol like this:
class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
You will also need to implement this as well:
func numberOfSections(in tableView: UITableView) -> Int {
return 1 // Or whatever it should be
}
**Where's the wrong?
ERROR "SecondViewController does not conform to protocol 'UITableViewDataSource"**
import UIKit
class SecondViewController: UIViewController, UITableViewDataSource, UITableViewDelegate
{
#IBOutlet weak var tableView: UITableView!
var videos:[video] = [video]()
#IBOutlet weak var menuButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
if self.revealViewController() != nil {
menuButton.target = self.revealViewController()
menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
let model = videoModel()
self.videos = videoModel().getVideos()
self.tableView.dataSource = self
self.tableView.delegate = self
}
func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return videos.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "BasicCell", for: indexPath)
let videoTitle = videos[indexPath.row].videoTitle
//customize the cell
cell.textLabel?.text = videoTitle
return cell
}
}
}
Perhaps, You did not connect UIViewController and UITableView.
In Stroyboard,
Place your mouse over UITableView, Drag to UIViewController using right button. And then you can check outlets options, datasource and delegate. Check these.