two sections and different three cells - swift

1.I have one more section1
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return 1
}else{
return 3 //imageName.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var thirdCell = ThirdTableViewCell()
var cell = UITableViewCell()
var row2Cell = Row2TableViewCell()
if indexPath.row == 0 {
cell = tableView.dequeueReusableCell(withIdentifier: "Cell1", for: indexPath)
return cell
}else if indexPath.row == 1{
thirdCell = tableView.dequeueReusableCell(withIdentifier: "thirdCell", for: indexPath) as! ThirdTableViewCell
thirdCell.image1.image = #imageLiteral(resourceName: "plus")//imageArray[indexPath.row]
return thirdCell
}else{
row2Cell = tableView.dequeueReusableCell(withIdentifier: "Row2Cell", for: indexPath) as! Row2TableViewCell
return row2Cell
}
}
2.How did I get ThirdViewController.image

As I see you want to access ThirdViewController.image in your ThirdTableViewCell Class
this is how you can access instance of viewController (e.g Labels, Images and TextFeilds etc) in other View Controller or in custom class.
import UIKit
internal weak var AccessThirdViewController: ThirdViewController?
class ThirdViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var imageViewToChange: UIImageView!
override func viewDidLoad() {
AccessThirdViewController = self
}
it will make it accessible in all other viewControllers or classes
import UIKit
class ThirdTableViewCell: UITableViewCell {
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
}
#IBAction func onButtonClick(_ sender: Any) {
AccessThirdViewController?.imageViewToChange.image = UIImage(named: "rocket")!
}
}
Now you can simply access ThirdViewController directly using AccessThirdViewContoller
Or you can achieve this by using NotificationCenter as creating
NotificationCenter addObserver
Receive(Get) Notification and Function-Method handler for received Notification:
import UIKit
class ThirdViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var imageViewToChange: UIImageView!
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(setImage), name: Notification.Name("UpdateImage"), object: nil)
}
#objc func setImage(){
self.imageViewToChange.image = UIImage(named: "rocket")
}
Then Send(Post) Notification from ThirdTableViewCell Class on #IBAction of UIButton
import UIKit
class ThirdTableViewCell: UITableViewCell {
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
}
#IBAction func onButtonClick(_ sender: Any) {
NotificationCenter.default.post(name: Notification.Name("UpdateImage"), object: nil)
}
}

Related

DidSelectRow function is not called

I'm trying to implement the didSelectRow function and perform a segue but when running the cells select and nothing happens.
I created a print statement that also doesn't run which proves that the function doesn't appear to be firing. Why would this be?
I have checked the identifier is correct and have researched these for a few hours going through many stack overflow threads but with little luck.
import UIKit
import CoreData
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let viewController = ListNameViewController()
let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
var itemChoosen = 0
override func viewDidLoad() {
super.viewDidLoad()
homeListsTableView.delegate = self
homeListsTableView.dataSource = self
viewController.loadList()
}
#IBOutlet weak var homeListsTableView: UITableView!
#IBAction func templatesButton(_ sender: Any) {
tabBarController?.selectedIndex = 2
}
#IBAction func allListsButton(_ sender: Any) {
tabBarController?.selectedIndex = 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewController.listName.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let result = viewController.listName[indexPath.row]
cell.textLabel?.text = ("\(String(result.listName!))")
return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
context!.delete(viewController.listName[indexPath.row])
viewController.listName.remove(at: indexPath.row)
viewController.saveList()
homeListsTableView.reloadData()
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
performSegue(withIdentifier: "items2", sender: self)
print("selected")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
viewController.loadList()
homeListsTableView.reloadData()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
homeListsTableView.reloadData()
}
}
ListNameViewController:
import UIKit
import CoreData
class ListNameViewController: UIViewController, UITableViewDelegate {
let context = (UIApplication.shared.delegate as? AppDelegate)?.persistentContainer.viewContext
var listName : [ListName] = []
override func viewDidLoad() {
super.viewDidLoad()
createButtonChange.isEnabled = false
//Objective-C Line used to keep checking if the text field is vaild before enabling the submit button
listNameValue.addTarget(self, action: #selector(textValidation), for: UIControl.Event.editingChanged)
}
#IBOutlet weak var listNameValue: UITextField!
#IBOutlet weak var locationOption: UITextField!
#IBOutlet weak var createButtonChange: UIButton!
#objc func textValidation() {
//Text Field Validation check before button is enabled
if listNameValue.text!.isEmpty {
createButtonChange.isEnabled = false
} else {
createButtonChange.isEnabled = true
}
}
// Create a new List
#IBAction func createButton(_ sender: Any) {
let newList = ListName(context: context!)
newList.listName = listNameValue.text
saveList()
self.navigationController!.popViewController(animated: true)
viewWillAppear(false)
}
func saveList() {
do {
try context!.save()
} catch {
print("Error saving context \(error)")
}
}
func loadList() {
let request : NSFetchRequest<ListName> = ListName.fetchRequest()
do{
listName = try context!.fetch(request)
} catch {
print("Error loading categories \(error)")
}
}
//Pass data to the HomeViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// let vc = segue.destination as! HomeViewController
}
}
// commented out core data and just used a normal array for testing.
Did you add segue in your storyboard for the tableview ? In this case the didSelect is not call but the prepare(for segue) of the tableview controller is called.
Ok solved it - There was a rouge tap gesture recognizer on the page. Removed it and works on one click. I have seen that if you wish to keep the gesture just add this line of code at the top of the function:
tap.cancelsTouchesInView = false
Took three days but I got there. Thanks for the help!

How to add delegate value to tableview in swift

Here I am sending secondVC textfield value to firstVC tableview but I am not receiving delegate value in tableview.
Here is my code:
In firstVC:
import UIKit
class CreateBusinessViewController: UIViewController, MyDataSendingDelegateProtocol, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var iteamsArray = [String]()
override func viewDidLoad() {
super.viewDidLoad()
}
func sendDataToFirstViewController(myData: String) {
self.iteamsArray.append(myData)
print(iteamsArray)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if (segue.identifier == "addSegue") {
let vc = segue.destination as! CreatePopUpViewController
vc.delegate = self
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return iteamsArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! BusinessTableViewCell
cell.nameLabel.text = iteamsArray[indexPath.row]
return cell
}
}
In secondVC:
protocol MyDataSendingDelegateProtocol {
func sendDataToFirstViewController(myData: String)
}
class CreatePopUpViewController: UIViewController {
var delegate: MyDataSendingDelegateProtocol?
#IBOutlet weak var addTf: UITextField!
#IBAction func saveButn(_ sender: Any) {
self.delegate?.sendDataToFirstViewController(myData: addTf.text!)
dismiss(animated: true, completion: nil)
}
}
How to add secondVC textfield data to firstVC array?
To Reflect the data to tableview cell you just need to reload the table view like i have updated your function check below code.
func sendDataToFirstViewController(myData: String) {
self.iteamsArray.append(myData)
tableView.reloadData()
print(iteamsArray)
}
Hope this way may help you.

How to recognize which cell was tapped once and which was tapped twice

there! I would like to get to know which cell is tapped once and which is tapped twice. I have two classes, one for TableViewController and the other one for TableViewCell. I would like to manipulate cells regarding the touch but I cannot get their indexPath.
TableViewController:
import UIKit
var elements: [[Int16]] = Array(repeating:Array(repeating:0, count:2), count:10)
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
if(elements[indexPath.row][1] == 1) //if red
{
cell.Label.text = String(elements[indexPath.row][0] * 3)
cell.Circle.backgroundColor = UIColor.red
}
else //if blue
{
cell.Label.text = String(elements[indexPath.row][0])
cell.Circle.backgroundColor = UIColor.blue
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
return UIScreen.main.bounds.height/10
}
override func viewWillAppear(_ animated: Bool)
{
for i in 0..<elements.count
{
elements[i][0] = Int16(Int(arc4random_uniform(10)))
elements[i][1] = Int16(Int(arc4random_uniform(2)))
}
Memory().save(entity: elements)
}
override func viewDidLoad()
{
super.viewDidLoad()
}
override func didReceiveMemoryWarning()
{
super.didReceiveMemoryWarning()
}
}
TableViewCell:
import UIKit
class TableViewCell: UITableViewCell
{
override func awakeFromNib()
{
super.awakeFromNib()
Circle.layer.cornerRadius = Circle.frame.width / 2
let singleTap = UITapGestureRecognizer(target: self, action: #selector(tappedOnce))
singleTap.numberOfTapsRequired = 1
addGestureRecognizer(singleTap)
let doubleTap = UITapGestureRecognizer(target: self, action: #selector(tappedTwice))
doubleTap.numberOfTapsRequired = 2
addGestureRecognizer(doubleTap)
singleTap.require(toFail: doubleTap)
singleTap.delaysTouchesBegan = true
doubleTap.delaysTouchesBegan = true
}
override func setSelected(_ selected: Bool, animated: Bool)
{
super.setSelected(selected, animated: animated)
}
#objc func tappedOnce(sender: AnyObject?)
{
print("1111111")
//Memory().reload(reload: x, I: x)
}
#objc func tappedTwice()
{
print("2222222")
}
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var Circle: UIView!
}
Inside the cells I have a label storing a random number (label) from 0 to 10 next to which there is a circle - blue or red (they are also random at start). If the circle is red, then the number (label) shows the number multiplied by three. All this is there.
Now... I want to change the number by touching on the cell once and make it 0 by touching on it twice
TableViewController:
var elements: [[Int16]] = Array(repeating: Array(repeating:0, count:2), count:10)
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//MARK: - UIViewController LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
for i in 0..<elements.count {
elements[i][0] = Int16(Int(arc4random_uniform(10)))
elements[i][1] = Int16(Int(arc4random_uniform(2)))
}
Memory().save(entity: elements)
}
//MARK: - UITableView Delegate & DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elements.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
if elements[indexPath.row][1] == 1 {
cell.Label.text = String(elements[indexPath.row][0] * 3)
cell.Circle.backgroundColor = UIColor.red
}
else {
cell.Label.text = String(elements[indexPath.row][0])
cell.Circle.backgroundColor = UIColor.blue
}
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UIScreen.main.bounds.height/10
}
}
TableViewCell:
class TableViewCell: UITableViewCell {
#IBOutlet weak var Label: UILabel!
#IBOutlet weak var Circle: UIView!
private var tapCounter = 0
override func awakeFromNib() {
super.awakeFromNib()
Circle.layer.cornerRadius = Circle.frame.width / 2
let tap = UITapGestureRecognizer(target: self, action: #selector(tapAction))
addGestureRecognizer(tap)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
#objc func tapAction() {
if tapCounter == 0 {
DispatchQueue.global(qos: .background).async {
usleep(250000)
if self.tapCounter > 1 {
self.tappedTwice()
}
else {
self.tappedOnce()
}
self.tapCounter = 0
}
}
tapCounter += 1
}
func tappedOnce() {
print("1111111")
}
func tappedTwice() {
print("2222222")
}
}
Take reference from here
Single and double taps on UITableViewCell in Swift 3

SSRadiobuttonsController button found nil while unwrapping

Hi I'm trying to add radiobuttons to my tableview. I have a tableviewcell class connected to the button in the tableview but when I try to add the button inside cellForRowAt indexpath function the app crash with error: unexpectedly found nil while unwrapping an Optional value
TableViewCell Code
import UIKit
class TableViewCell: UITableViewCell, SSRadioButtonControllerDelegate {
#objc func didSelectButton(selectedButton: UIButton?) {
NSLog(" \(selectedButton)" )
}
#IBOutlet var radioButton: UIButton!
#IBOutlet var taskText: UILabel!
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
}
TableViewController Code
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
self.title = "Today"
//Radio buttons
radioButtonController.delegate = self
radioButtonController.shouldLetDeSelect = true
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = TableViewCell(style: .default, reuseIdentifier: "Cell")
let task = tasks[indexPath.row]
radioButtonController.addButton(cell.radioButton)
if let myName = task.name {
cell.textLabel?.text = myName
}
return cell
}

Passing data from tableView to ViewController in Swift

I have an App that i'm trying to adapt exactly how i want
I have been following a Youtube tutorial of Seemu Apps to make it but I need to finish it adding an optional ViewController
This app has 2 tableViews showing vehicles and if we click in one row of the first tableView then second tableView will show us a list of selected vehicles.
Here is what we have until now: (image link , because i haven't got ten points reputation on stackOverFlow)
http://subefotos.com/ver/?65ba467040cb9280e8ec49644fd156afo.jpg
All is running perfect, but i want to be able to display information in an optional detailViewController (label with a detailed description of each vehicle and a bigger image of this ) depending of which vehicle we click in the secondTableViewControlle (or modelViewController in the App) exactly how i was following in the tutorial between tableViews
i know that we need to passing data through prepareForSegue method , i have understood this making the steps in the tutorial but when we have 2 tableviewControllers
For example : if we want to display a last viewController with information of Ferrari 458 and a great picture of this car
What do we need to do exactly to show information of each vehicle?
PD : I'm beginner in the programming world, maybe i would need to see it in a very simple way
The whole code:
ViewController.swift
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var selMake = String()
#IBOutlet var tableView : UITableView!
var transportData : [String] = ["Car", "Plane", "Motorcycle", "Truck" , "Train", "Bicycle" , "Helicopter"]
//////////////////////////////////////////
//viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
//Register custom cell
var nib = UINib(nibName: "customCell", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "cell")
}
//Numbers of rows in Section
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.transportData.count
}
//cellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
///// Static Cell (no valid for custom cells)
/*
var cell : UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.transportData[indexPath.row]
return cell
*/
var cell:customCellTableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as customCellTableViewCell
cell.lblTrans.text = transportData[indexPath.row]
cell.imgTrans.image = UIImage (named: transportData[indexPath.row])
return cell
}
//height
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 90
}
//didSelectRowAtIndexPath
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Fila \(transportData[indexPath.row]) seleccionada")
selMake = transportData[indexPath.row]
performSegueWithIdentifier("modelView", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "modelView") {
var vc = segue.destinationViewController as modelViewViewController
vc.selMake = selMake
}
}
import UIKit
class customCellTableViewCell: UITableViewCell {
#IBOutlet weak var imgTrans: UIImageView!
#IBOutlet weak var lblTrans: UILabel!
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
}
}
import UIKit
class modelViewViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
//////////////////////////////////
var selMake = String()
var tableData : [String] = []
#IBOutlet var tableView: UITableView!
//////////////////////////////////
override func viewDidLoad() {
super.viewDidLoad()
//Register custom cell
var nib = UINib(nibName: "customCell2", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "cell")
switch selMake {
case "Car" :
tableData = ["Ferrari 458", "La Ferrari"]
case "Plane" :
tableData = ["Iberia"]
case "Motorcycle" :
tableData = ["Kawasaki Ninja", "Yamaha Aerox"]
case "Truck" :
tableData = [ "Camion transporte"]
case "Train" :
tableData = [ "Ave" ]
case "Bicycle" :
tableData = ["BMX"]
case "Helicopter" :
tableData = ["HelicopteroCombate"]
default:
println("Sel Make \(selMake)")
}
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
/* var cell : UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.tableData[indexPath.row]
return cell*/
var cell:customCell2TableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as customCell2TableViewCell
cell.lbl2text.text = self.tableData[indexPath.row]
cell.img2image.image = UIImage (named: tableData[indexPath.row])
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Row \(indexPath.row)selected")
performSegueWithIdentifier("detailView", sender: self)
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 90
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detailView") {
var vc = segue.destinationViewController as DetailViewController
}
}
import UIKit
class customCell2TableViewCell: UITableViewCell {
#IBOutlet var lbl2text: UILabel!
#IBOutlet var img2image: 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
}
}
import UIKit
class DetailViewController: UIViewController {
#IBOutlet var imgDetail: UIImageView!
#IBOutlet var lblDetail: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
Try this.
ModelViewViewController
var selectedImage:String?
var selectedLabel:String?
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
println("Row \(indexPath.row)selected")
selectedImage = self.tableData[indexPath.row]
selectedLabel = self.tableData[indexPath.row]
performSegueWithIdentifier("detailView", sender: self)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if(segue.identifier == "detailView") {
var vc = segue.destinationViewController as DetailViewController
vc.img = selectedImage
vc.lblDetail = selectedLabel
}
}
class DetailViewController: UIViewController {
#IBOutlet var imgDetail: UIImage!
#IBOutlet var lblDetail: UILabel!
var img:String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
imgDetail = UIImage(named: img)
}
This should work.