How to add images one by one into tableviewcell by clicking addImage button in swift4 - swift4

import UIKit
class ViewController: UIViewController,UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var addImage: UIImage!
let animalNames = ["lion","monky","tiger"]
let animalImages = [UIImage(named: "lion"), UIImage(named: "monky"), UIImage(named: "tiger")]
override func viewDidLoad() {
super.viewDidLoad()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return animalImages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "mycell",for:indexPath) as! ImageWithTableViewCell
cell.image1.image=self.animalImages[indexPath .row]
cell.label1.text=self.animalNames[indexPath .row]
return cell
}
#IBAction func addingImages(_ sender: UIButton) {
//what code I have to write here
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

If you want array to mutable declare it as var instead of let. and Create 1 var numberOfRecordtoShow
var animalNames = ["lion","monky","tiger"]
var animalImages = [UIImage(named: "lion"), UIImage(named: "monky"), UIImage(named: "tiger")]
var numberOfRecordtoShow = 1
Increate numberOfRecordtoShow by 1 till array count.
#IBAction func addingImages(_ sender: UIButton) {
if numberOfRecordtoShow > animalNames.count{
return
}
numberOfRecordtoShow = numberOfRecordtoShow + 1
//reload table now
tableView.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return numberOfRecordtoShow
}

Related

TableView Inside tableView Cell In swift

In this image I have two section in this table view . In the second section there is a tableview inside the cell. i want to fetch the textfield data of the “inner table view” in the current class. How to do this? followings are the code for my tableview cell .I want to fetch "InerTableViewCell1" data in "outerTableView". How to do this?
//MARK- UITableViewDataSource
extension outerTableView: UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell1 = tableView.dequeueReusableCell(withIdentifier: "TableViewCell1", for: indexPath) as? TableViewCell1
return cell1!
}
else{
let cell2 = tableView.dequeueReusableCell(withIdentifier: "TableViewCell2", for: indexPath) as? TableViewCell2
cell2!.innerTableView.reloadData()
return cell2!
}
}
class TableViewCell2: UITableViewCell {
//MARK- IBOutlet
#IBOutlet weak var innerTableView: UITableView!
//MARK- Properties
var rowNumber = 1
//MARK- Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
innerTableView.dataSource = self
innerTableView.delegate = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
//MARK- UITableViewDataSource
extension TableViewCell2: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("row number is \(rowNumber)")
return rowNumber
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "InerTableViewCell1", for: indexPath) as? InerTableViewCell1
return cell!
}
}
}
class InerTableViewCell1: UITableViewCell {
//MARK- IBOutlet
#IBOutlet weak var firstUserNameTextField: UITextField!
#IBOutlet weak var firstAdressTextField: UITextField!
#IBOutlet weak var secondUserNameTextField: UITextField!
#IBOutlet weak var secondAdressTextField: UITextField!
//MARK- Lifecycle
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
}
}

UISwitches in UITableViewCell change states together

I have a very strange problem in my Swift project. I use UIswitch in my dynamic cells in my one-section uitable. Whenever I click on the 6th switch, the first one changes its state with it and vice versa. The .valueChanged function only works for the one that is clicked (correct behaviour).
I cannot figure out why the switches change state together.
This is the code for table cells:
import UIKit
class RoutineTableViewCell: UITableViewCell {
#IBOutlet weak var selectionSwitch: UISwitch!
#IBOutlet weak var title: UILabel!
#IBOutlet weak var previewImage: UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
and here is the code in my table view controller:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: RoutineTableReuseIdentifier, for: indexPath) as? RoutineTableViewCell
else{
return RoutineTableViewCell()
}
let exercise = section!.exercises[indexPath.row]
cell.title.text = exercise.title
cell.previewImage.image = UIImage(named: (exercise.gifName + ".gif"))
cell.selectionSwitch.addTarget(self, action: #selector(self.addRemoveExercise(_:)), for: .valueChanged)
return cell
}
#IBAction func addRemoveExercise(_ sender: UISwitch!) {
let buttonPosition:CGPoint = sender.convert(CGPoint.zero, to:self.tableView)
let indexPath = self.tableView.indexPathForRow(at: buttonPosition)
if(sender.isOn){
customizedSection?.exercises[indexPath!.row] = section!.exercises[indexPath!.row]
}
else{
customizedSection?.exercises[indexPath!.row] = ExerciseModel()
}
}
Your tableView:
import UIKit
class TableViewController: UITableViewController,switchValues {
func changed(_ cell: UITableViewCell, _ mySwitch: UISwitch) {
let index = tableView.indexPath(for: cell)
switchStates[(index?.row)!] = mySwitch.isOn
tableView.reloadData()
}
var switchStates : [Bool] = [false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return switchStates.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyTableViewCell
cell.mySwitch.isOn = switchStates[indexPath.row]
cell.delegate = self
return cell
}
Your cell:
import UIKit
protocol switchValues {
func changed(_ cell:UITableViewCell,_ mySwitch:UISwitch)
}
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var mySwitch: UISwitch!
var delegate:switchValues!
#IBAction func valueChanged(_ sender: UISwitch) {
delegate.changed(self, mySwitch)
}
}

How to delete a cell in the tableview from another View controller?

I am trying to delete a cell in the tableview from another view controller. I have modeled my code similar to the question posted below but I still can't seem to successfully delete the selected row/cell in the CalorieVC when the delete button is pressed in the DeleteVC
Deleting a row of a tableview from another viewcontroller
SideNote: there is button in the cells to popup the DeleteVC, I am also getting an error upon pressing the the deleteBtn in the CalorieVC: DeleteRowInTableviewDelegate on let picked saying Thread 1: Fatal error: Index out of range
import UIKit
class CalorieViewController: UIViewController {
var selectedFood: FoodList! // allows data to be passed into the CalorieVC
var deleteItems: CalorieItem? // passes data to DeleteVC
// allows data to be sepearted into sections
var calorieItems: [CalorieItem] = []
var groupedCalorieItems: [String: [CalorieItem]] = [:]
var dateSectionTitle: [String] = []
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView.dataSource = self
tableView.delegate = self
// Allows data in cells to seperate by section
groupedCalorieItems = Dictionary(grouping: calorieItems, by: {$0.foodList.date})
dateSectionTitle = groupedCalorieItems.map{$0.key}.sorted()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "DeleteSegue" {
let vc: DeleteViewController = segue.destination as! DeleteViewController
vc.deleteItems = self.deleteItems
// vc.delegate = self
}
}
}
extension CalorieViewController: UITableViewDelegate, UITableViewDataSource{
func numberOfSections(in tableView: UITableView) -> Int {
return dateSectionTitle.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let date = dateSectionTitle[section]
return groupedCalorieItems[date]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let calorieCell = tableView.dequeueReusableCell(withIdentifier: "CalorieCell") as! CalorieCell
let date = dateSectionTitle[indexPath.section]
let caloriesToDisplay = groupedCalorieItems[date]![indexPath.row]
calorieCell.configure(withCalorieItems: caloriesToDisplay.foodList)
return calorieCell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let calorieHeader = tableView.dequeueReusableCell(withIdentifier: "CalorieHeader") as! CalorieHeader
let headerTitle = dateSectionTitle[section]
calorieHeader.dateLbl.text = "Date: \(headerTitle)"
return calorieHeader
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 45
}
func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
let calorieFooter = tableView.dequeueReusableCell(withIdentifier: "CalorieFooter") as! CalorieFooter
//Cell Total Code
let date = dateSectionTitle[section]
let subtotal = groupedCalorieItems[dispensary]?.map { $0.getCalorieTotal() }.reduce(0, +) ?? 0
calorieFooter.calorieTotal.text = String(subtotal!)
return calorieFooter
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
return 150
}
}
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
let picked = dateSectionTitle[rowToDelete]
let selectedCell = groupedCalorieItems[dod]
delete(selectedCell)
// calorieItems.remove(at: rowToDelete) // tried using this and I get an error code upon segueing back to the CalorieVC
tableView.reloadData()
}
}
import UIKit
protocol DeleteRowInTableviewDelegate: NSObjectProtocol {
func deleteRow(inTableview rowToDelete: Int)
}
class DeleteViewController: UIViewController {
var modifyItems: CartItem!
var delegate: DeleteRowInTableviewDelegate?
#IBOutlet weak var deleteLbl: UILabel!
#IBOutlet weak var deleteBtn: UIButton!
#IBOutlet weak var cancelBtn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if isMovingFromParent {
delegate!.deleteRow(inTableview: 1)
}
deleteLbl.text = "Are you sure you want to delete this Food Item from your calorie List?"
}
#IBAction func decline(_ sender: Any) {
dismiss(animated: true)
delegate!.deleteRow(inTableview: 1)
print("Delete Item")
}
#IBAction func cancel(_ sender: Any) {
dismiss(animated: true)
print("Cancel Delete")
}
}
Remove the value from the dataSource
Remove the table cell
extension CalorieViewController: DeleteRowInTableviewDelegate {
func deleteRow(inTableview rowToDelete: Int) {
if caloriesItems.count > rowToDelete {
calorieItems.remove(at: rowToDelete)
tableView.deleteRows(at: [IndexPath(row: rowToDelete, section: 0)], with: .automatic)
} else {
print("index not present")
}
}
}
Do not call reloadData just to delete one row. This is a bad practice.
Use deleteRows instead.

Swift MapKit Autocomplete

I am trying to set an address autocomplete in my view controller so users do not have to type the whole address and instead select it from below the search textfield. This is how my controller looks like:
import Foundation
import UIKit
import MapKit
extension AddNewAddressViewController: MKLocalSearchCompleterDelegate {
func completerDidUpdateResults(_ completer: MKLocalSearchCompleter) {
searchResults = completer.results
searchResultsTableView.reloadData()
}
func completer(_ completer: MKLocalSearchCompleter, didFailWithError error: Error) {
// handle error
}
}
class AddNewAddressViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var searchCompleter = MKLocalSearchCompleter()
var searchResults = [MKLocalSearchCompletion]()
override func viewDidLoad() {
searchCompleter.delegate = self
searchCompleter.queryFragment = addressSearch.text!
searchResultsTableView.dataSource = self
super.viewDidLoad()
}
#IBOutlet weak var addressSearch: UITextField!
#IBOutlet weak var searchResultsTableView: UITableView!
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let searchResultsCount = searchResults.count
return searchResultsCount
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let searchResult = searchResults[indexPath.row]
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: nil)
cell.textLabel?.text = searchResult.title
cell.detailTextLabel?.text = searchResult.subtitle
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
#IBAction func defaultAddressButton(_ sender: Any) {
}
#IBAction func addAddressButton(_ sender: Any) {
}
}
I am getting an error that says:
Type AddNewAddressViewController does not conform to protocol 'UITableViewDataSource'
What am I missing?
Thanks in advance.
You left out the underscore for first parameter of the cellForRowAtIndexPath declaration, which is required under swift 3.0:
func tableView(_ tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
[etc.]
As a result, you don't have a required function matching the expected signature.

Call dictionary in tableView of swift

How to call Dictionary values in tableView..
Getting error
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet var tblView: UITableView!
var AnimalName = ["e":["Elephant","EEE"","l":["Lion","LL"],h":["Horse",huh"]]
var initial = Array(AnimalName.alKeys) //error in this line
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return AnimalName.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
cell.textLabel?.text = AnimalName[indexPath.row] //how to call the cell
return cell
}
func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
return initial // not getting output
}
func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return index // How to select
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate{
#IBOutlet var tblView: UITableView!
var AnimalName = ["e":["Elephant","EEE"], "l":["Lion","LL"], "h":["Horse", "huh"]]
var initial: [String] = [] //error in this line
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return self.initial.count
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if let animalsOfSection = self.AnimalName[self.initial[section]] {
return animalsOfSection.count
}
return 0
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell")! as UITableViewCell
if let animal = self.AnimalName[self.initial[indexPath.section]]?[indexPath.row] {
cell.textLabel?.text = animal //how to call the cell
}
return cell
}
func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
return self.initial // not getting output
}
func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
if let index = self.initial.indexOf(title) {
return index // How to select
}
return 0
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.initial = Array(self.AnimalName.keys).sort(<)
}
}
["Horse",huh"] should be ["Horse","huh"]
"EEE"" should be "EEE"]
"LL"],h" should be "LL"],"h"
var initial = Array(AnimalName.alKeys)
should be
var initial = Array(AnimalName.keys)
You shouldn't need SO to find and fix typos. Also, try Ctrl+Space after a period, it will propose the appropriate function names and help you avoid misnaming them.