How to compare values of two different UIPickerView? - ios

I have custom UITableViewController with two custom UITableViewCell
Each of them contains UIPickerView
I want to compare values of these UIPickerViews
(I make the Maps App, and i wanna make the route, so i need do compare two points, and if they are different then "Make The Route" button will be set to Enabled State)
How can i do this? I tried to use didSet values, but it didn't work
Here are my classes:
class PlaceForRouteCell: UITableViewCell, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var picker: UIPickerView!
// Выбираем все места в базе данных
let places = realm.objects(Place.self)
var selectedPlace = Place()
func getSelectedPlace() -> Place {
return selectedPlace
}
//число "барабанов"
func numberOfComponents(in pickerView: UIPickerView) -> Int { return 1 }
//число элементов в "барабане"
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
//если БД пуста, то предупредить об этом
return places.count != 0 ? places.count : 1
}
//содержимое "барабанов"
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
if (places.count != 0) {
if (places.count == 1) { return "Добавьте еще одно место" }
return places[row].userName
}
return "Сохраненных мест нет"
}
//обрабатываем выбранный элемент
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if (places.count != 0) {
print(picker.tag)
selectedPlace = places[row]
// print("выделена строка №\(row), элемент \(places[row])'")
}
}
func setup() { picker.delegate = self }
}
And
class TableForRouteViewController: UIViewController, UITableViewDataSource, UIPickerViewDelegate{
// Выбираем все места в базе данных
let places = realm.objects(Place.self)
#IBOutlet weak var makeTheRouteButton: UIBarButtonItem!
#IBOutlet var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
tableView.tableFooterView = UIView(frame: CGRect(x: 0, y: 0,
width: tableView.frame.size.width, height: 1))
tableView.dataSource = self
let cell = tableView.cellForRow(at: IndexPath(row: 0, section: 1)) as! PlaceForRouteCell
cell.picker.selectRow(1, inComponent: 0, animated: true)
var cellA = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! PlaceForRouteCell {
didSet {
print("первая ячейка изменилось")
}
}
var cellB = tableView.cellForRow(at: IndexPath(row: 0, section: 1)) as! PlaceForRouteCell
// print("tag of A: \(cellA.picker)")
// print("tag of B: \(cellB.picker.tag)")
var valueOfA = cellA.getSelectedPlace() {
didSet {
print("значение в первой ячейке изменилось")
}
}
print(valueOfA.userName)
var valueOfB = cellB.getSelectedPlace() {
didSet {
print("значение в первой ячейке изменилось")
}
}
print(valueOfB.userName)
if (places.count < 2 ) { makeTheRouteButton.isEnabled = false }
}
#IBAction func makeTheRouteButtonPressed(_ sender: UIBarButtonItem) {
let cellA = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! PlaceForRouteCell
let pointA = cellA.selectedPlace
let cellB = tableView.cellForRow(at: IndexPath(row: 0, section: 1)) as! PlaceForRouteCell
let pointB = cellB.selectedPlace
print("point A: \(pointA.userName), point B: \(pointB.userName)")
}
// var arePlacesEqual : Bool = comparing() {
// didSet {
// print("значения поменялись")
// }
// }
func comparing() -> Bool {
let cellA = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as! PlaceForRouteCell
let cellB = tableView.cellForRow(at: IndexPath(row: 0, section: 1)) as! PlaceForRouteCell
let valueOfA = cellA.selectedPlace.userName
let valueOfB = cellB.selectedPlace.userName
if (valueOfA == valueOfB) { return true }
return false
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 1 }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "placeForRouteCell", for: indexPath) as! PlaceForRouteCell
cell.picker.tag = indexPath[0]
cell.setup()
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
switch(section) {
case 0:return "Точка А"
case 1:return "Точка Б"
default :return ""
}
}
// количество секциий
func numberOfSections(in tableView: UITableView) -> Int { return 2 }
}

I created tableView with pickerView in cell.
In didSelectRow method i added NotificationCenter sender
My tableViewCell class:
let picker_array = ["one", "two", "three"]
class TableViewCell: UITableViewCell, UIPickerViewDelegate, UIPickerViewDataSource {
#IBOutlet weak var picker: UIPickerView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.picker.delegate = self
self.picker.dataSource = self
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return picker_array.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return "\(picker_array[row])"
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
NotificationCenter.default.post(name: Notification.Name("Notification"), object: nil)
}
}
In viewDidLoad i added NotificationCenter listener.
My ViewController class:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let dummy_data = [1,2]
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(methodOfReceivedNotification(notification:)), name: Notification.Name("Notification"), object: nil)
}
#objc func methodOfReceivedNotification(notification: Notification) {
for index in dummy_data {
let indexPath = IndexPath(row: index - 1, section: 0)
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
let selectRow = picker_array[cell.picker.selectedRow(inComponent: 0)]
print(selectRow)
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dummy_data.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
return cell
}
}
When i change pickerView, console print current value from cells
I think it will help

Related

PickerView not getting the updated value from Array

First of all please correct my topic subject or suggest an edit for the taggin in case if I mentioned somthing wrong.
I'm working on a store App project and I stuck in the selecting subSection VC because of the UIPickerView not getting the updated value from the array of target!
Here below is my code
class SelectSectionVC : UIViewController, UITextFieldDelegate {
var delegate : SelectSectionDelegate!
var staticVariable = SelectionCell.shared
override func viewDidLoad() {
super.viewDidLoad()
getSection()
setupCell()
self.pickertextField.alpha = 0
self.DoneBtn.isHidden = true
self.pickerView.isHidden = true
pickertextField.addTarget(self, action: #selector(textField_CatchedData(_:)), for: .editingDidEnd )
}
#IBOutlet weak var CollectionView: UICollectionView!
#IBOutlet weak var pickerView: UIPickerView!{
didSet{ pickerView.delegate = self ; pickerView.dataSource = self }}
var selectedSection : SectionsObject?
var sectionsArray : [SectionsObject] = []
func getSection(){
SectionsAPI.getAllsections { (section) in
self.sectionsArray.append(section)
DispatchQueue.main.async {
self.CollectionView.reloadData()
}
}
}
// Products type Arrays
var type_FP : [String] = ["FP1", "FP2"]
var type_TP : [String] = ["TP1", "TP2"]
var type_JW = ["Rings", "Necklace", "Collar", "Bracelet", "Earring"]
var type_ACS = ["Hair Wrap", "Ring", "Strap", "Sunglasses", "Crown"]
var type_LP = ["Waist belt", "Wallet", "Handbag", "Suitcase", "Face Mask"]
var type_Watches = ["classic", "Leather", "Smart", "Digital"]
var generatedTypes : [String] = [] { didSet{print("# Types updated ==> ( \(generatedTypes) )")} }
func updateTypesarray(){
if selectedSection?.name == "Trending Products" {
self.generatedTypes = type_TP
}
else if selectedSection?.name == "Accessories" {
self.generatedTypes = type_ACS
}
else if selectedSection?.name == "Featured Products" {
self.generatedTypes = type_FP
}
else if selectedSection?.name == "Watches" {
self.generatedTypes = type_Watches
}
else if selectedSection?.name == "Jewellery Products" {
self.generatedTypes = type_JW
}
else if selectedSection?.name == "Leather Products" {
self.generatedTypes = type_LP
}else { print("# ((Nothing Happaned!!))") }
}
#IBOutlet weak var pickertextField: UITextField!{
didSet{
pickertextField.inputView = UIView() //what a Magic!!!... This code solved Keyboard dismiss problem after assign the textField as FirstResponder!
pickertextField.delegate = self
pickertextField.allowsEditingTextAttributes = false
pickertextField.becomeFirstResponder()
}
}
#objc func textField_CatchedData(_ sender : UITextField) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "Type Name"), object: nil, userInfo: ["text" : sender.text!])
}
var productsList: [productObject] = []
var RecommendedArray: [String] = ["TH-1791721_side","Image-2","touq2","TH-1791349","watch2","eswara","Image-1",] //to be updated later!
}
extension SelectSectionVC : UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout {
func setupCell() {
CollectionView.delegate = self; CollectionView.dataSource = self
CollectionView.register(UINib(nibName: "SelectionCell", bundle: nil), forCellWithReuseIdentifier: "cell")
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.CollectionView.frame.size.width - 25, height: self.CollectionView.frame.size.height/4 - 0.5)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { // make spacing between each cell
return 2
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
sectionsArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = CollectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SelectionCell
cell.isSelected = false
pickertextField.text = "Select product type" // Reset text to "Select product type" when press new cell"
cell.sectionName.text = sectionsArray[indexPath.row].name
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("# secArray Count = \(sectionsArray.count)")
self.selectedSection = sectionsArray[indexPath.row]
updateTypesarray()
print("# //Selected cell => TypesArray => \(generatedTypes)")
pickertextField.becomeFirstResponder()
}
}
The problem is: title & number Of Rows In Component are not getting the value from (generatedTypes) array after it get updated when cell did selected!
extension SelectSectionVC : UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return generatedTypes.count
}
func pickerView(_ pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
return NSAttributedString(string: self.generatedTypes[row], attributes: [NSAttributedString.Key.foregroundColor: UIColor.yellow])
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return generatedTypes[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.pickertextField?.text = generatedTypes[row]
self.pickerView.isHidden = true
self.DoneBtn.isHidden = false
self.pickertextField.endEditing(true)
print("# pickerTextField... has ended editing!")
}
I did many many breakpoints and I'm sure that [generatedTypes] array has a value..but I don't know why it always called inside pickerView before ti get updated!
please help me
Thank you in advance
You may need to reload the picker end of updateTypesarray
func updateTypesarray(){
......
self.pickerView.reloadAllComponents()
}

How to delete a section and a row from a TableView with Realm and Swift?

ableView. I'm currently working on this gym app and I'm hoping to get a little bit of guidance here.
Basically what I want is to be able to swipe the cell and delete the row and the section associated with that row.
When I run my code, this is the error I get
'attempt to delete row 0 from section 1, but there are only 1 sections before the update'
Any help would be much appreciated.
class WorkoutsViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, SwipeTableViewCellDelegate, CollapsibleTableSectionDelegate {
let realm = try! Realm()
var workouts : Results<Workouts>?
var days : Results<WeekDays>!
var daysOfWeek : [String] = ["Monday", "Tuesday", "Wednsday", "Thursday", "Friday", "Saturday", "Sunday"]
let picker = UIPickerView()
#IBOutlet weak var WorkoutsTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
WorkoutsTableView.delegate = self
WorkoutsTableView.dataSource = self
picker.delegate = self
picker.dataSource = self
loadCategories()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
tableView.rowHeight = 80.0
//Populate based on the # of workouts in each day.
let day = days[section]
return day.workouts.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return days[section].day
}
func numberOfSections(in tableView: UITableView) -> Int {
return days.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! SwipeTableViewCell
cell.delegate = self
if (days?[indexPath.section]) != nil {
cell.accessoryType = .disclosureIndicator
//Populate with titles of workouts based on section/day of the week.
//cell.textLabel?.text = days?[indexPath.row].workouts[indexPath.row].name
cell.textLabel?.text = days[indexPath.section].workouts[indexPath.row].name
}
return cell
}
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
guard orientation == .right else { return nil }
let deleteAction = SwipeAction(style: .destructive, title: "Delete") { action, indexPath in
self.updateModel(at: indexPath)
}
// customize the action appearance
deleteAction.image = UIImage(named: "delete-icon")
return [deleteAction]
}
func tableView(_ tableView: UITableView, editActionsOptionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> SwipeOptions {
var options = SwipeOptions()
options.expansionStyle = .destructive
return options
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
#IBAction func AddWorkoutButton(_ sender: UIButton) {
var textField = UITextField()
textField.becomeFirstResponder()
let alert = UIAlertController(title: "New Workout", message: "Please name your workout...", preferredStyle: .alert)
let addAction = UIAlertAction(title: "Add Workout", style: .default) { (UIAlertAction) in
//Add workout to database
//Create a two dimensional array object in Realm with numbers corresponding to each day of the week.
//Append workouts to the day in the dictionary that the user selects.
let newWorkout = Workouts()
let dow = WeekDays()
dow.day = self.daysOfWeek[self.picker.selectedRow(inComponent: 0)]
newWorkout.name = textField.text!
dow.workouts.append(newWorkout)
self.save(newDay: dow)
}
alert.addTextField { (alertTextField) in
alertTextField.placeholder = "Muscle Group"
textField = alertTextField
alertTextField.inputView = self.picker
}
alert.addAction(addAction)
present(alert, animated: true, completion: nil)
}
func save(newDay: WeekDays){
do {
try realm.write {
realm.add(newDay)
}
} catch {
print("Error saving workout \(error)")
}
WorkoutsTableView.reloadData()
}
func updateModel(at indexPath: IndexPath){
if let workoutForDeletion = self.days?[indexPath.section]{
do {
try self.realm.write {
self.realm.delete(workoutForDeletion)
}
} catch {
print("Error deleting workout, \(error)")
}
}
self.WorkoutsTableView.reloadData()
}
func loadCategories(){
days = realm.objects(WeekDays.self)
WorkoutsTableView.reloadData()
}
#IBAction func EditWorkout(_ sender: UIBarButtonItem) {
}
}
extension WorkoutsViewController : UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return 7
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return daysOfWeek[row]
}
}
class WeekDays : Object {
#objc dynamic var day : String = ""
let workouts = List<Workouts>()
}
class Workouts : Object {
#objc dynamic var name : String = ""
var parentDay = LinkingObjects(fromType: WeekDays.self, property: "workouts")
}
If you are trying to delete a whole section, then your code is correct. Try calling loadCategories instead of reloading your tableView to see if that helps. See updated code below:
Change that line to this instead:
func updateModel(at indexPath: IndexPath){
if let workoutForDeletion = self.days?[indexPath.section] {
do {
try self.realm.write {
self.realm.delete(workoutForDeletion)
}
} catch {
print("Error deleting workout, \(error)")
}
}
self.loadCategories()
}

UIPickerView only populates with "?"

So I'm trying to populate my two pickerViews from arrays, but only coming up with "?" I've tried some of the fixes for similar types on here but none of them have worked.
#IBOutlet var startPickerView: UIPickerView!
#IBOutlet var endPickerView: UIPickerView!
var startPickerData: [Int] = []
var endPickerData: [Int] = []
let startArray = (1...999).map { $0 }
let endArray = (2...1000).map { $0 }
let startPickerCellIndexPath = IndexPath(row: 1, section: 1)
let endPickerCellIndexPath = IndexPath(row: 1, section: 2)
var isStartPickerShown: Bool = false {
didSet {
startPickerView.isHidden = !isStartPickerShown
}
}
var isEndPickerShown: Bool = false {
didSet {
endPickerView.isHidden = !isEndPickerShown
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.startPickerView.delegate = self
self.startPickerView.dataSource = self
self.endPickerView.delegate = self
self.endPickerView.dataSource = self
startPickerData = startArray
endPickerData = endArray
self.startPickerView.reloadAllComponents()
self.endPickerView.reloadAllComponents()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 2
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return 1
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
switch indexPath {
case startPickerCellIndexPath:
if isStartPickerShown {
return 216.0
} else {
return 0.0
}
case endPickerCellIndexPath:
if isEndPickerShown {
return 216.0
} else {
return 0.0
}
default:
return 44.0
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
switch indexPath {
case startPickerCellIndexPath:
if isStartPickerShown {
isStartPickerShown = false
} else if isStartPickerShown {
isStartPickerShown = false
isStartPickerShown = true
} else {
isStartPickerShown = true
}
tableView.beginUpdates()
tableView.endUpdates()
case endPickerCellIndexPath:
if isEndPickerShown {
isEndPickerShown = false
} else if isEndPickerShown {
isEndPickerShown = false
isEndPickerShown = true
} else {
isEndPickerShown = true
}
tableView.beginUpdates()
tableView.endUpdates()
default:
break
}
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
// The number of rows of data
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
if pickerView.tag == 1 {
return startPickerData.count
} else {
return endPickerData.count
}
}
// The data to return fopr the row and component (column) that's being passed in
private func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> Int? {
let startView: Int = startPickerData[row]
let endView: Int = endPickerData[row]
if pickerView.tag == 1 {
return startView
} else {
return endView
}
}
}
I've been working on this for a day and a half and haven't been able to figure out why it won't work and I've already tried several fixes from here.
You need to change your private method at the very bottom to this:
// The data to return fopr the row and component (column) that's being passed in
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
let startView: Int = startPickerData[row]
let endView: Int = endPickerData[row]
if pickerView.tag == 1 {
return String(format: "%d", startView)
} else {
return String(format: "%d", endView)
}
}

How to pass data between custom table view cells?

I have two custom table views (not table view controller) with custom
cells. I want to select a second cell from MainViewcontroller
and selected
title and price of cell info pass to the second view as
DetailViewController's first and second index labels.
This is my MainViewController.swift
Edit: Here is the answer
import UIKit
class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate,
UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var mainTableView: UITableView!
var imageNames = [ImageNames]()
var searchFoods: [String]!
var priceFood: [Double]!
var searching = false
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.tabBarController?.tabBar.isHidden = false
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.isHidden = true
let foodCell = Food(name: ["Hamburger big mac",
"Patates",
"Whopper",
"Steakhouse"], price: [15.0, 20.0, 25.0, 30.0])
searchBar.delegate = self
searchFoods = foodCell.name
priceFood = foodCell.price
imageNames = [
ImageNames(name: "images"),
ImageNames(name: "unnamed"),
ImageNames(name: "unnamed")
]
}
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return section == 0 ? 1 : searchFoods.count
// return section == 0 ? 1 : foodNames.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.section == 0 ? 130 : 65
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return indexPath.section == 0 ? 100 : 65
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0 {
let cell = tableView.dequeueReusableCell(withIdentifier: "MainFoodTableViewCell", for: indexPath) as! MainFoodTableViewCell
cell.mainFoodCollectionView.delegate = self
cell.mainFoodCollectionView.dataSource = self
cell.mainFoodCollectionView.reloadData()
cell.mainFoodCollectionView.tag = indexPath.row
return cell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellForFood", for: indexPath) as! MainFoodTitleTableViewCell
cell.titleLabel?.text = searchFoods[indexPath.row]
cell.priceLabel?.text = priceFood[indexPath.row].description
return cell
}
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "cellForFoodSegue" {
if let destinationViewController = segue.destination as? DetailViewController
{
let indexPath = self.mainTableView.indexPathForSelectedRow!
var foodNameArray: [String]
var foodPriceArray: [Double]
foodNameArray = [searchFoods[indexPath.row]]
foodPriceArray = [priceFood[indexPath.row]]
destinationViewController.detailFoodName = foodNameArray
destinationViewController.detailFoodPrice = foodPriceArray
}
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return imageNames.count
}
//MARK:- collection view cell size
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let width = UIScreen.main.bounds.width
return CGSize(width: width, height: 130)
}
//MARK:- //collection view cell data
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MainFoodCollectionViewCell", for: indexPath) as! MainFoodCollectionViewCell
let img = imageNames[indexPath.row]
cell.mainFoodImage.image = UIImage(named: img.name)
return cell
}
}
//MARK:- SearchBar data
extension MainViewController : UISearchBarDelegate {
func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
self.searchBar.showsCancelButton = true
mainTableView.reloadData()
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
mainTableView.reloadData()
searchBar.showsCancelButton = false
searchBar.text = ""
searchBar.resignFirstResponder()
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchFoods = searchText.isEmpty ? searchFoods : searchFoods.filter { (item: String) -> Bool in
return item.range(of: searchText, options: .caseInsensitive, range: nil, locale: nil) != nil
}
mainTableView.reloadData()
}
}
Edit: Here is my DetailViewController
import UIKit
class DetailViewController: UIViewController {
#IBOutlet weak var foodTitle: UILabel!
#IBOutlet weak var foodSubTitle: UILabel!
#IBOutlet weak var foodPiece: UILabel!
#IBOutlet weak var foodPrice: UILabel!
#IBOutlet weak var drinkPicker: UITextField!
#IBOutlet weak var menuPieceStepper: UIStepper!
var drinkPickerView = UIPickerView()
var selectDrinkType: [String] = []
var detailFoodName : [String] = []
var detailFoodPrice : [Double] = [0.0]
let foods = Food(name: ["Hamburger big mac",
"Patates",
"Whopper",
"Steakhouse"], price: [15.0, 20.0, 25.0, 30.0])
#IBAction func foodPieceStepper(_ sender: Any) {
}
#objc func foodPieceChangeStepper() {
let res = menuPieceStepper.value + foods.price.first!
foodPrice.text = "\(res)"
}
#IBAction func addBasket(_ sender: Any) {
let destinationVC = MyCartViewController()
destinationVC.fromDetailFoodNames = foods.name
destinationVC.fromDetailFoodPrices = foods.price
dismiss(animated: true)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if(segue.identifier == "addToCartSegue") {
if let addToCartVC = segue.destination as? MyCartViewController {
addToCartVC.fromDetailFoodNames = [foodTitle.text]
addToCartVC.fromDetailFoodPrices = foods.price
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
menuPieceStepper.value = 0.0
menuPieceStepper.minimumValue = 0.0
menuPieceStepper.maximumValue = 30.0
menuPieceStepper.stepValue = foods.price.first!
menuPieceStepper.addTarget(self, action: #selector(foodPieceChangeStepper), for: .valueChanged)
drinkPickerView.delegate = self
drinkPicker.inputView = drinkPickerView
selectDrinkType = ["Ayran", "Kola", "Su", "Fanta", "Şalgam", "Sprite"]
foodTitle.text = detailFoodName.description
foodPrice.text = detailFoodPrice.description
self.navigationController?.navigationItem.title = "Sipariş Detayı"
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)
}
#objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
drinkPicker.resignFirstResponder()
}
override func viewWillAppear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = false
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.navigationBar.isHidden = true
}
}
extension DetailViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return selectDrinkType.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return selectDrinkType[row]
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
let selectedDrink = selectDrinkType[row]
drinkPicker.text = selectedDrink
}
}
Aren't you looking for prepare(for segue: sender:) method? Usually you need to bind a cell prototype to a detail view with a segue, and when the cell is selected the segue is followed just after that method is called to prepare data injection to the detail view.

PickerView inside tableView cell

I have created a tableview which takes date difference and create that number of tableview cell, each table view cell consist of textview and and picker view against textview to pick value. The problem is when i pick value for the 1 position using PickerView then the selected value is also reflected on the other cell
code for the contorller
here hfDetailsArr contains total number of days difference
--function for getting date difference count {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/yyyy"
let currentCalendar = NSCalendar.current
dateFormatter.date(from: dateFormatter.string(from:date1 as Date))
let temp = currentCalendar.dateComponents([.day], from: dateFormatter.date(from: dateFormatter.string(from:date1 as Date))!, to: dateFormatter.date(from: dateFormatter.string(from:date2 as Date))!)
hfDetailsArr.removeAllObjects();
//print(temp.day!)
if !(temp.day! < 0) && (temp.day! != 0) {
for i in 0 ..< (temp.day! + 1){
let HFDetailsDates = currentCalendar.date(byAdding: .day, value: i, to: date1 as Date)
DataDetails = dateFormatter.string(from: HFDetailsDates!)
hfDetailsArr.add(DataDetails)
ApplyForDate.append( dateFormatter.string(from: HFDetailsDates!) + ",")
}
//print(ApplyForDate)
}
HFDEtailsTable.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if hfDetailsArr.count < 0 && hfDetailsArr.count != 0 {
return 0
}else{
return hfDetailsArr.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : HFDetailsCell! = tableView.dequeueReusableCell(withIdentifier: "cell") as! HFDetailsCell
cell.txtHFDateFeild.text = hfDetailsArr[indexPath.row] as? String
cell.cellDelegate = self
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("indeddsdsd \(indexPath.row)")
}
code for UITableview cell with pickerview inside it
protocol HFDetailsCellDelegate : class {
func ValueSelectedChage(sender:HFDetailsCell ,Id:String ,selectedCell:String)
}
class HFDetailsCell: UITableViewCell,UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource{
#IBOutlet var txtHFPicker: UITextField!
#IBOutlet var txtHFDateFeild: UITextField!
#IBOutlet var pickerView: UIPickerView! = UIPickerView()
var HfDtailsOneArr = ["Select","Full Day Leave","Half Day Leave"]
var position = 0
//var intHFStatusDetail = ""
/// internal static var HFtableView = UITableView()
weak var cellDelegate: HFDetailsCellDelegate?
//var LeaveDataIDArr = [String?]()
override func awakeFromNib() {
txtHFDateFeild.delegate = self
pickerView.delegate = self
txtHFPicker.inputView = pickerView
pickerView.backgroundColor = UIColor.white
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 txtleaveType(_ sender: UITextField) {
}
//print("buttonclick")
// //UIpickerView
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
//Set number of rows in components
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.HfDtailsOneArr.count
}
//Set title for each row
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return HfDtailsOneArr[row]
}
// Update textfield text when row is selected
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
// self.cellDelegate?.ValueSelectedChage(sender:self, Id: HFDetailsLeaveCount(position: row), selectedCell: "")
txtHFPicker.text = HfDtailsOneArr[row]
print("pickerText:\(txtHFPicker.text!)")
}
func HFDetailsLeaveCount(position:Int)-> String {
switch position {
case 0:
return "0"
case 1:
return "8"
case 2:
return "4"
default:
return "nil"
}
}
}
in above image if i select value for date 04/08 then the same value is reflected for 12/08
-- any kind of help will be appreciated. Thank you
in table cell, on picker selection call ValueSelectedChage delegate method
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.cellDelegate?.ValueSelectedChage(sender:self, Id: HFDetailsLeaveCount(position: row), selectedCell: HfDtailsOneArr[row])
txtHFPicker.text = HfDtailsOneArr[row]
print("pickerText:\(txtHFPicker.text!)")
}
create a variable in viewcontroller to keep selected value
var hfSelectedDetails: [String: String?]?
in viewcontroller implement the delegate method
func ValueSelectedChage(sender:HFDetailsCell ,Id:String ,selectedCell:String) {
let indexpath = self.tableView.indexPathForRowAtPoint(cell.center)
let key = "\(indexpath.row)"
hfSelectedDetails[key] = selectedCell
....//other code if any
}
and in cellForRow add
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : HFDetailsCell! = tableView.dequeueReusableCell(withIdentifier: "cell") as! HFDetailsCell
cell.txtHFDateFeild.text = hfDetailsArr[indexPath.row] as? String
cell.cellDelegate = self
let key = "\(indexPath.row)"
if let selectedValue = hfSelectedDetails[key] {
cell.txtHFPicker.text = selectedValue
} else {
cell.txtHFPicker.text = nil
}
return cell
}

Resources