How to call method
internal func segconChanged(segcon: UISegmentedControl, var text:String){
switch segcon.selectedSegmentIndex {
case 0:
print("whoo")
return text = "clicked Trainings"
case 1:
print("yeahh")
return text = "clicked Daily"
default:
break
}
}
from
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
?
I am beginner of swift.
I am using UISegmentedControl, and UITableView.
When I click UISegmentedControl, make it change to UITableViewCell.
Please look at inside of func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
I added segconChanged(UISegmentedControl(), text: "") to call method,
but I think this is wrong and actually doesnt work.
Please give me advice.
This is all code.
import UIKit
class TrainingLogViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var myTableView: UITableView!
#IBOutlet weak var segment: UISegmentedControl!
let tabLog: NSArray = ["Trainings", "Daily"]
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
segment.addTarget(self, action: "segconChanged:", forControlEvents: UIControlEvents.ValueChanged)
}
var text: String = ""
internal func segconChanged(segcon: UISegmentedControl, var text:String){
switch segcon.selectedSegmentIndex {
case 0:
print("whoo")
return text = "clicked Trainings"
case 1:
print("yeahh")
return text = "clicked Daily"
default:
break
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 10
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let text: String = ""
*segconChanged(UISegmentedControl(), text: "")
let cell = UITableViewCell(style: .Subtitle, reuseIdentifier: "LogTraining")
cell.textLabel?.text = text
cell.detailTextLabel?.text = "subtitle"
return cell
}
}
You dont need to call segconChanged() function manually as it will automatically be called when segment is changed. So just reload your tableview when segment is changed, check its index and populate data acccordingly i.e. in cellForRowAtIndexPath method.
Try this code :
import UIKit
class TrainingLogViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var myTableView: UITableView!
#IBOutlet weak var segment: UISegmentedControl!
let tabLog: NSArray = ["Trainings", "Daily"]
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
segment.addTarget(self, action: "segconChanged:", forControlEvents: UIControlEvents.ValueChanged)
}
func segconChanged(segcon: UISegmentedControl){
self.myTableView.reloadData()
switch segcon.selectedSegmentIndex {
case 0:
print("clicked Trainings")
case 1:
print("clicked Daily")
default:
break
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 10
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell = tableView.dequeueReusableCellWithIdentifier("LogTraining", forIndexPath: indexPath)
cell.textLabel?.text = (self.segment.selectedSegmentIndex == 0) ? tabLog[0] : tabLog[1]
cell.detailTextLabel?.text = "subtitle"
return cell
}
}
Related
I am having a weird issue where for some reason my UITableView is not being reloading after performing a search. The console prints out the correctly filtered data, but the table simply doesn't change. I have never encountered this issue, so I first attempted the solutions which naturally came to mind:
Tried tableView.reloadData() in the Main Queue
Quit Xcode, clean build, reinstall
Cleared out the derived data dir
I have found several similar issue in SO, but all of the solutions I've seen are things I've tried, mainly reloading tableview in main queue.
Hoping maybe I just simply have an issue in my code or something I'm missing.
I am running Xcode 8.3.3
import UIKit
class CategoriesViewController: UIViewController {
var isFiltering = false
var location = Location()
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var searchBar: UISearchBar!
var categoriesSearchResults = [Category]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
tableView.allowsSelection = true
tableView.keyboardDismissMode = .onDrag
let nib = UINib(nibName: "CategoryTableViewCell", bundle: nil)
self.tableView.register(nib, forCellReuseIdentifier:"CategoryTableViewCell");
searchBar.returnKeyType = UIReturnKeyType.done
searchBar.autocapitalizationType = .none
searchBar.delegate = self
}
extension CategoriesViewController : UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("HI")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering {
return self.categoriesSearchResults.count
}
return self.location.categories.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if let cell = self.tableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as? CategoryTableViewCell {
var category: Category
if isFiltering {
category = self.categoriesSearchResults[indexPath.row]
} else {
category = self.location.categories[indexPath.row]
}
cell.name.text = category.name
cell.status.textColor = UIColor.lightGray
cell.status.text = "Not Verified"
}
return cell
}
}
extension CategoriesViewController : UISearchBarDelegate {
func searchBarIsEmpty() -> Bool{
return self.searchBar.text?.isEmpty ?? true
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.isFiltering = true
self.categoriesSearchResults.removeAll()
tableView.reloadData()
self.view.endEditing(true)
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
if searchBarIsEmpty() {
self.view.endEditing(true)
self.isFiltering = false
} else {
self.isFiltering = true
self.categoriesSearchResults = self.location.categories.filter({ (category: Category) -> Bool in
return category.name.lowercased().contains(searchText.lowercased())
})
}
tableView.reloadData()
}
}
and my custom table view cell:
import UIKit
class CategoryTableViewCell: UITableViewCell {
#IBOutlet weak var name: UILabel!
#IBOutlet weak var status: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func prepareForReuse() {
super.prepareForReuse()
self.name.text = ""
self.status.text = ""
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Thank you in advance.
EDIT: Might also be worth mentioning, when I am actively searching, the function tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) is not called??
The scope of if let nests in its scope. In your code you are always returning let cell = UITableViewCell(). Try returning it inside the if let :
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
if let cell = self.tableView.dequeueReusableCell(withIdentifier: "CategoryTableViewCell", for: indexPath) as? CategoryTableViewCell {
var category: Category
if isFiltering {
category = self.categoriesSearchResults[indexPath.row]
} else {
category = self.location.categories[indexPath.row]
}
cell.name.text = category.name
cell.status.textColor = UIColor.lightGray
cell.status.text = "Not Verified"
/// RETURN CELL HERE
return cell
}
return cell
}
import UIKit
class ViewController: UITableViewController {
var animals = [Animal]()
override func viewDidLoad() {
super.viewDidLoad()
self.animals = [Animal(name: "개"),Animal(name: "강아지"),Animal(name: "고양이"),Animal(name: "멍멍이"),Animal(name: "물어")]
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
var animal = Animal.self
animal = animals[indexPath.row] //1
cell.textLabel?.text = animal.name //2
return cell //3
}
}
I am getting the following errors:
error is cannot assign value of type 'Animal' to type 'Animal Type'
error is instance member 'name' cannot be used on type 'Animal
unexpected non-void return value in void function
In your code above, "didSelectRowAtIndexPath" is called after you select certain cell, and it does not return anything. Instead, if you want to display the cell, use "cellForRowAtIndexPath".
class Animal {
var name: String
init(name: String) {
self.name = name
}
}
class ViewController: UIViewController {
var animals = [Animal]()
override func viewDidLoad() {
super.viewDidLoad()
self.animals = [Animal(name: "개"),Animal(name: "강아지"),Animal(name: "고양이"),Animal(name: "멍멍이"),Animal(name: "물어")]
}
}
extension ViewController: UITableViewDataSource {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 5
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
// This would works on your table view
var animal = animals[indexPath.row]
cell.textLabel?.text = animal.name
return cell
}
}
Specifically for a calculator app. I want to type in the textfield in the first row and have that change text in the other rows. Really, type in any row and change the value of the other rows.
I know I should be working with ints but I was going to worry about type converting later.
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
//label and text_field come from CustomTableViewCell.swift
cell.label.text = array[indexPath.row]
cell.text_field.text = array_values[indexPath.row]
return cell
}
This is inside my tableViewController class and thats the func that generates the rows from the arrays.
Im after something like when you type in a text field, hit a button, and it updates some label, but where theres no button and text fields update other text fields as the user types. Inside a table view.
Heres the rest of the code.
import UIKit
class TableViewController: UITableViewController {
#IBOutlet var table_view: UITableView!
var array = [String]()
var array_values = [String]()
override func viewDidLoad() {
super.viewDidLoad()
array = ["1", "2", "3", "4", "5"]
array_values = ["", "", "", "", ""]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return array.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomTableViewCell
cell.label.text = array[indexPath.row]
cell.text_field.text = array_values[indexPath.row]
return cell
}
}
import UIKit
class CustomTableViewCell: UITableViewCell {
#IBOutlet weak var text_field: UITextField!
#IBOutlet weak var label: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
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.
I have the following code to display two tables populated from two different arrays in one view:
#IBOutlet var RFTable: UITableView
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
}
override func viewDidLoad() {
super.viewDidLoad()
self.RFTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.RFArray.count;
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell:UITableViewCell = self.RFTable.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = String(self.RFArray[indexPath.row])
return cell
}
#IBOutlet var IMProdTable: UITableView
func tableView2(IMProdTable: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
}
override func viewDidLoad() {
super.viewDidLoad()
self.IMProdTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell2")
}
func tableView2(IMProdTable: UITableView!, numberOfRowsInSection section: Int) -> Int {
return self.IMProdArray.count;
}
func tableView2(IMProdTable: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell2:UITableViewCell = self.IMProdTable.dequeueReusableCellWithIdentifier("cell2") as UITableViewCell
cell2.textLabel.text = String(self.IMProdArray[indexPath.row])
return cell2
}
I got the first table working, and then copied and pasted the text, replacing the array names and tableview names, and have hooked up the delegate and datasource. However Xcode displays 'invalid redeclaration of viewdidload' on the second (pasted) code. If I replace this to 'fund loadView() {' instead of viewdidload the app builds. When I test it though, both tables view exactly the same data which is the data in 'RFArray.' I am VERY new to coding and cannot see what I have done, please help.
#IBOutlet var RFTable: UITableView
#IBOutlet var IMProdTable: UITableView
func tableView(tableView: UITableView!, didSelectRowAtIndexPath indexPath: NSIndexPath!) {
}
override func viewDidLoad() {
super.viewDidLoad()
self.RFTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
self.IMProdTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell2")
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
if tableView == RFTable {
return self.RFArray.count;
} else {
return self.IMProdArray.count;
}
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
if tableView == RFTable {
var cell:UITableViewCell = self.RFTable.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel.text = String(self.RFArray[indexPath.row])
return cell
} else {
var cell2:UITableViewCell = self.IMProdTable.dequeueReusableCellWithIdentifier("cell2") as UITableViewCell
cell2.textLabel.text = String(self.IMProdArray[indexPath.row])
return cell2
}
}
Just a quick edit. You need to keep the delegate and datasource methods same and check which TableView instance is actually sending the message.
You cannot override the same method twice in a derived class.
First create two DataSource implemented classes
First Data source
class FirstDataSouce: NSObject,UITableViewDataSource,UITableViewDelegate {
var items: [String] = []
override init(){
super.init()
}
func setData(items:[String]){
self.items = items
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RecentTableViewCell") as! RecentTableViewCell
cell.titleLabel.text = items[indexPath.row]
return cell
}
}
Second Data source
class SecondDataSouce: NSObject,UITableViewDataSource,UITableViewDelegate {
var items: [String] = []
override init(){
super.init()
}
func setData(items:[String]){
self.items = items
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "RecentTableViewCell") as! RecentTableViewCell
cell.titleLabel.text = items[indexPath.row]
return cell
}
}
Set datasource to tableview in ViewController
class ViewController: UIViewController{
#IBOutlet weak var tableView1: UITableView!
#IBOutlet weak var tableView2: UITableView!
var dataSource1: FirstDataSouce!
var dataSource2: SecondDataSouce!
func prepareTableViews(){
let items1 = [“a”,”b”,”c”]
dataSource1 = FirstDataSouce()
dataSource1.setData(items: items1)
self.tableView1.dataSource = dataSource1
self.tableView1.delegate = dataSource1
self.tableView1.register(SelectorTableViewCell.self,
forCellReuseIdentifier:
"TableViewCell")
self.tableView1.tableFooterView = UIView()
let items2 = [“1”,”2”,”3”]
dataSource2 = SecondDataSouce()
dataSource2.setData(items: items2)
self.recentTableView.dataSource = dataSource2
self.recentTableView.delegate = dataSource2
self.recentTableView.register(RecentTableViewCell.self,
forCellReuseIdentifier:
"TableViewCell")
self.recentTableView.tableFooterView = UIView()
}
}
Also Make Sure To reload each TableView After fetching data to TableviewCell.
e.g
#IBOutlet var RFTable: UITableView
#IBOutlet var IMProdTable: UITableView
override func viewDidLoad() {
super.viewDidLoad()
self.RFTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell1")
self.IMProdTable.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell2")
RFTable.reloadData()
IMProdTable.reloadData()
}