I want to show different data in tableview on basis of selection from segmented control. Below is my code it only shows first TABLEVIEW DATASOURCE and for some reason segemented control doesn't work.
#IBOutlet weak var segementedControlAction: UISegmentedControl!
var Names = ["Name1", "Name2","Name3","Name4"]
var Images = ["1.jpg","2.jpg","5.jpg","8.jpg"]
var set = ["14","15","16","17"]
var Names1 = ["Name5", "Name6","Name7","Name8"]
var Images1 = ["6.jpg","4.jpg","7.jpg","9.jpg"]
var set1 = ["4","5","6","7"]
var Names2 = ["Name9", "Name12","Name13","Name14"]
var Images2 = ["11.jpg","21.jpg","51.jpg","81.jpg"]
var set2 = ["114","115","116","117"]
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var count: Int = 0
tableView.layer.cornerRadius = 10
tableView.layer.masksToBounds = true
if (tableView == self.d1) {
print("Monday")
count = self.Names.count
}
else if (tableView == self.d2) {
print("Tuesday")
count = self.Names1.count
}
else if (tableView == self.d3) {
print("Wednesday")
count = self.Names2.count
}
return count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->
UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath:
indexPath) as! CustomTableViewCell
if segementedControlAction.selectedSegmentIndex == 0 {
cell.nameLabel.text = Names[indexPath.row]
cell.thumbnailImageView.image = UIImage(named: Images[indexPath.row])
cell.setLabel.text = set[indexPath.row]
}
else if segementedControlAction.selectedSegmentIndex == 1 {
cell.nameLabel.text = Names1[indexPath.row]
cell.thumbnailImageView.image = UIImage(named: Images1[indexPath.row])
cell.setLabel.text = set1[indexPath.row]
}
else {segementedControlAction.selectedSegmentIndex == 2
cell.nameLabel.text = Names2[indexPath.row]
cell.thumbnailImageView.image = UIImage(named: Images2[indexPath.row])
cell.setLabel.text = set2[indexPath.row]
}
return cell }
#IBAction func segementedControlAction(sender: UISegmentedControl) {
switch sender.selectedSegmentIndex {
case 0:
self.d1.hidden = false
self.d2.hidden = true
self.d3.hidden = true
self.d1.reloadData()
case 1:
self.d1.hidden = true
self.d2.hidden = false
self.d3.hidden = true
self.d2.reloadData()
case 2:
self.d1.hidden = true
self.d2.hidden = true
self.d3.hidden = false
self.d3.reloadData()
default:
self.d1.hidden = false
self.d2.hidden = true
self.d3.hidden = true
self.d1.reloadData()
break;
}
Please ensure that segementedControlAction is connected properly from your view controller. Probably try with these steps:
Delete the earlier connected IBAction.
Connect your segmentedControl to Files Owner.
Connect your segementedControlAction: action and select "Value
Changed" NOT "Touch up Inside". THIS IS IMP.
Print a statement to check if segementedControlAction: is now
triggered.
try this:
In your viewDidLoad method, add this:
tableView.delegate = self
tableView.dataSource = self
Related
I have trying for sometime to make the "reloadData()" work but it is not working. I've even tried "DispatchQueue.main.async{self.tableView.reloadData()}"
Below is the code
import UIKit
import QuartzCore
import GameKit
enum Tags: Int {
case levelLabel = 100
case background = 101
case highScoreLabel = 102
case star1 = 201
case star2 = 202
case star3 = 203
}
let LightBlue = UIColor.systemBlue
let Green = UIColor.systemRed
let Purple = UIColor.systemPurple
let Pink = UIColor.systemPink
let Orange = UIColor.systemOrange
let OneStarScore = 5
let TwoStarScore = 10
let ThreeStarScore = 15
let NumLevels = 11
class HomeViewController: UIViewController, UITableViewDataSource,
UITableViewDelegate, GKGameCenterControllerDelegate {
#IBOutlet weak var tableView: UITableView!
var highScores: [Int] = [Int]()
var unlockedLevels = 0
let colors = [LightBlue, Green, Purple, Pink, Orange]
var tutorialPageVC: PageDataSourceViewController?
var gameVC: GameViewController?
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13.0, *) {
tableView.separatorColor = UIColor.systemBackground
} else {
// Fallback on earlier versions
}
let storyboard = self.storyboard
tutorialPageVC = storyboard?.instantiateViewController(withIdentifier: "PageDataSourceVC")
as? PageDataSourceViewController
gameVC = storyboard?.instantiateViewController(withIdentifier: "GameViewController")
as? GameViewController
// Trying to fix UITableView
/// Put code here
self.tableView.reloadData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(false)
let defaults = UserDefaults.standard
if let scoresArray = defaults.array(forKey: "highScores") {
highScores = scoresArray as! [Int]
unlockedLevels = highScores.count - 1 // Subtract one for tutorial
if highScores[unlockedLevels] >= 5 {
unlockedLevels += 1 // Unlock additional level if last high score is greater than 5
}
}
}
// MARK: - TableView data source methods
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return NumLevels
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LevelCell", for: indexPath)
cell.selectionStyle = UITableViewCell.SelectionStyle.none
let view = cell.viewWithTag(Tags.background.rawValue) as UIView?
let levelLabel = cell.viewWithTag(Tags.levelLabel.rawValue) as! UILabel
let scoreLabel = cell.viewWithTag(Tags.highScoreLabel.rawValue) as! UILabel
let star1 = cell.viewWithTag(Tags.star1.rawValue) as! UIImageView
let star2 = cell.viewWithTag(Tags.star2.rawValue) as! UIImageView
let star3 = cell.viewWithTag(Tags.star3.rawValue) as! UIImageView
view?.layer.borderColor = colors[indexPath.row % 5].cgColor
view?.layer.borderWidth = 6.0
if indexPath.row == 0 {
// Tutorial Level
view?.alpha = 1.0
levelLabel.text = "Tutorial"
star1.isHidden = true
star2.isHidden = true
star3.isHidden = true
scoreLabel.text = ""
} else if indexPath.row + 1 <= highScores.count {
// Levels that have been played
view?.alpha = 1.0
levelLabel.text = "Level \(indexPath.row)"
star1.isHidden = false
star2.isHidden = false
star3.isHidden = false
formatStars(highScores[indexPath.row], stars: [star1, star2, star3])
scoreLabel.text = "High Score: \(highScores[indexPath.row])"
} else {
// Levels that have NOT been played
view?.alpha = indexPath.row > unlockedLevels ? 0.5 : 1.0
levelLabel.text = "Level \(indexPath.row)"
star1.isHidden = true
star2.isHidden = true
star3.isHidden = true
scoreLabel.text = ""
}
return cell
}
/// Display stars for each level on homepage
func formatStars(_ score: Int, stars: [UIImageView]) {
switch score {
case 0..<OneStarScore:
stars[0].image = UIImage(named: "star-empty")
stars[1].image = UIImage(named: "star-empty")
stars[2].image = UIImage(named: "star-empty")
case OneStarScore..<TwoStarScore:
stars[0].image = UIImage(named: "star")
stars[1].image = UIImage(named: "star-empty")
stars[2].image = UIImage(named: "star-empty")
case TwoStarScore..<ThreeStarScore:
stars[0].image = UIImage(named: "star")
stars[1].image = UIImage(named: "star")
stars[2].image = UIImage(named: "star-empty")
default:
stars[0].image = UIImage(named: "star")
stars[1].image = UIImage(named: "star")
stars[2].image = UIImage(named: "star")
}
}
// MARK: - TableView delegate methods
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if indexPath.row == 0 {
self.present(tutorialPageVC!, animated: true, completion: nil)
} else if indexPath.row <= unlockedLevels {
gameVC!.level = indexPath.row
self.present(gameVC!, animated: true, completion: nil)
// performSegueWithIdentifier("LevelSegue", sender: self)
}
}
Maybe the connection between the UITableView and the delegate and data source are not set.
You could do this in the storyboard by ctrl+dragging from the table view to the view controller and setting the delegate and data source outlets.
Or you can do so in code, e.g. in viewDidLoad:
self.tableView.dataSource = self
self.tableView.delegate = self
You need to set dataSource and delegate to self
override func viewDidLoad() {
super.viewDidLoad()
tableView.delegate = self
tableView.datasource = self
}
And Assign values directly like this
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "LevelCell", for: indexPath) as? LevelCell
cell?.star1.isHidden = true
}
Basically I am using the pod M13Checkbox which works great when I do not incorporate my UISegmentedControl. I have two todo lists separated into two segments. As soon as I check a box on the first segment it is repeated on the second segment.
I'm not sure if this is because of the cell being reused or not. Using print statements I have figured out I am able to see the data of the indexpath.row disregarding what segment is currently showing. Just the checkmarks I cannot control.
Please disregard any "Firebase notes".
class ToDoList: UITableViewController {
#IBOutlet weak var segment: UISegmentedControl!
var selectedRow: Int = 0
let seg1 = ["first","tab","Index"]
let seg2 = ["second","segment","akjdhfajd"]
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
var returnValue = 0
switch(segment.selectedSegmentIndex) {
case 0: returnValue = seg1.count
case 1: returnValue = seg2.count
default: break
}
return returnValue
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ToDoCell", for: indexPath) as! ToDoCell
switch (segment.selectedSegmentIndex) {
case 0:
segment.selectedSegmentIndex = 0
selectedRow = 0
cell.item.text = seg1[indexPath.row]
cell.box.tag = indexPath.row
case 1:
segment.selectedSegmentIndex = 1
selectedRow = 1
cell.item.text = seg2[indexPath.row]
cell.box.tag = indexPath.row
print(cell.box.tag)
default:
break
}
cell.box.addTarget(self, action: Selector(("checkboxPressed")), for: UIControlEvents.touchUpInside)
return cell
}
#IBAction func checkboxPressed(_ sender: M13Checkbox) {
let buttonRow = sender.tag
let listItem = [buttonRow]
let todoDict = ["\(buttonRow)": "True"]
//need to individually checkbox the cases .. at moment if i check one it checks the other also
if sender.checkState == .checked || sender.checkedValue == nil {
print("\(buttonRow)")
if selectedRow == 0 {
let listArrayItem = seg1[buttonRow]
sender.checkedValue = listArrayItem
print(listArrayItem)
} else {
print("we are on segment 2")
}
} else if sender.checkState == .unchecked {
// if its unchecked. then u want to remove it from the checked item in firebase.. we will only load checked items obviosuly..
//remove from completed list
}
}
}
class CalenderCell: UITableViewCell {
#IBOutlet var lblDay: UILabel!
#IBOutlet var lblRest: UILabel!
#IBOutlet var imgCompleted: UIImageView!
override func awakeFromNib()
{
super.awakeFromNib()
}
func updateCell(exerciseobject : Exercise)
{
let resttext = NSLocalizedString("restday", comment: "")
let day = NSLocalizedString("day", comment: "")
let dayexercise = "\(day) \(exerciseobject.exerciseDayID)"
if !exerciseobject.exerciseRestDay
{
lblDay.text = dayexercise
if exerciseobject.exerciseDayStatus
{
imgCompleted.isHidden = false
}
else
{
imgCompleted.isHidden = true
}
lblRest.isHidden = true
}
else
{
lblDay.isHidden = true
imgCompleted.isHidden = true
lblRest.text = resttext
viewWithTag(100)?.backgroundColor = UIColor(red:1.00, green:0.21, blue:0.28, alpha:1.0)
}
}
}
The above is my custom cell class and the below is my tableview class.
When I try to build the app everything is working perfect but whenever I fast scroll the data is mismatching or same data appering in more cells.
I tried:
prepareforreuse()
{
//clearing label and images here
}
in my custom cell class but still getting the fast scrollview data mismatch
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if let cell = calenderTable.dequeueReusableCell(withIdentifier: "CalenderCell", for: indexPath) as? CalenderCell
{
cell.updateCell(exerciseobject: days[indexPath.row])
return cell
}
else
{
return UITableViewCell()
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return days.count
}
Either use prepareForReuse and reset your controls to default values or make sure to update all the state for every path in the updateCell method.
e.g.
func updateCell(exerciseobject : Exercise)
{
let resttext = NSLocalizedString("restday", comment: "")
let day = NSLocalizedString("day", comment: "")
let dayexercise = "\(day) \(exerciseobject.exerciseDayID)"
if !exerciseobject.exerciseRestDay
{
lblDay.text = dayexercise
lblDay.isHidden = false
if exerciseobject.exerciseDayStatus
{
imgCompleted.isHidden = false
}
else
{
imgCompleted.isHidden = true
}
lblRest.isHidden = true
viewWithTag(100)?.backgroundColor = nil
}
else
{
lblDay.isHidden = true
imgCompleted.isHidden = true
lblRest.text = resttext
lblRest.isHidden = false
viewWithTag(100)?.backgroundColor = UIColor(red:1.00, green:0.21, blue:0.28, alpha:1.0)
}
}
I am using a custom cell for my table view. I have a switch in my cell. When I toggle the switch for certain cells, my switch vanishes from random cells. This only happens if I give a target action to my switch. When I comment the addTarget code, the table view works fine. Can any one help please?
The snap shot of the custom cell is:
The code for my CellForRowAtIndexPath is:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = placesTableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! ApproveCustomCell
cell.placeType.text = places[indexPath.row].type
cell.placeName.text = places[indexPath.row].name
cell.placePhone.text = places[indexPath.row].phone
cell.placeWebsite.text = places[indexPath.row].website
cell.placeAddress.text = places[indexPath.row].address
cell.switchOutlet.tag = indexPath.row
cell.switchOutlet.addTarget(self, action: #selector(self.approveRejectPlace(_:)), forControlEvents: .TouchUpInside)
if places[indexPath.row].status! == "Approved" {
cell.switchOutlet.on = true
}else {
cell.switchOutlet.on = false
}
return cell
}
UPDATE
This is my Approve/reject method:
func approveRejectPlace(sender: UISwitch!){
var url = "\(baseUrl)\(approveRejectUrl)"
if sender.on == true {
url += ("Approved/\(places[sender.tag].id))")
}else {
url += ("Rejected/\(places[sender.tag].id)")
}
print(self.places[sender.tag].name)
let parameters = ["key" : encryptedKey , "salt" : encryptedSalt]
self.view.lock()
dataProvider.hitWebservice(url, parameters: parameters) { (jsonArray) in
self.view.unlock()
if let results = jsonArray[0] as? NSDictionary {
if let result = results.objectForKey("result") as? Bool {
if result {
if sender.on {
self.places[sender.tag].status = "Approved"
}else {
self.places[sender.tag].status = "Rejected"
}
// self.placesTableView.reloadData()
}else {
invokeAlertMethod("Error", msgBody: "Failed to approve the place", delegate: self)
sender.on = false
}
}
}
}
}
I am currently set up to transfer section 1 of my tableview to another tableView. This is done by moving the didSelectRow: rows. However, the issue is that when I attempt to move the section when every row is selected (and there is nothing in section 0) it crashes with an index is beyond bounds error.
I am using a boilerPlate code for my sectionHeaders due to section 1 header changing back to section 0 header when all items selected in section 1. I believe this is what is causing the index to be out of bounds error, but am not sure how to correct it.
My sections are set up as:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
let numberOfSections = frc.sections?.count
return numberOfSections!
}
//Table Section Headers
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String?{
let sectionHeader = "Items Needed - #\(frc.sections![section].numberOfObjects)"
let sectionHeader1 = "Items in Cart - #\(frc.sections![section].numberOfObjects)"
if (frc.sections!.count > 0) {
let sectionInfo = frc.sections![section]
if (sectionInfo.name == "0") {
return sectionHeader
} else {
return sectionHeader1
}
} else {
return nil
}
}
with my didSelectRow and cells as:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! SLTableViewCell
//assign delegate
cell.delegate = self
let items = frc.objectAtIndexPath(indexPath) as! List
cell.backgroundColor = UIColor.clearColor()
cell.tintColor = UIColor.grayColor()
cell.cellLabel.text = "\(items.slitem!) - Qty: \(items.slqty!)"
cell.cellLabel.font = UIFont.systemFontOfSize(25)
moveToPL.hidden = true
if (items.slcross == true) {
cell.accessoryType = .Checkmark
cell.cellLabel.textColor = UIColor.grayColor()
cell.cellLabel.font = UIFont.systemFontOfSize(20)
self.tableView.rowHeight = 50
moveToPL.hidden = false
} else {
cell.accessoryType = .None
cell.cellLabel.textColor = UIColor.blackColor()
cell.cellLabel.font = UIFont.systemFontOfSize(25)
self.tableView.rowHeight = 60
moveToPL.hidden = true
}
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let items = frc.objectAtIndexPath(indexPath) as! List
if (items.slcross == true) {
items.slcross = false
} else {
items.slcross = true
}
tableView.reloadData()
}
Is this my issue or is something else causing this?
Edit:
I tried changing my function in charge of moving items from this:
#IBAction func moveToPantry(sender: AnyObject) {
let sectionInfo = self.frc.sections![1]
let objectsToAppend = sectionInfo.objects as! [List]
for item in objectsToAppend {
item.slist = true
item.slcross = false
item.plist = false
item.slitem = item.pitem
item.slqty = item.pqty
item.sldesc = item.pdesc
item.slprice = item.pprice
item.slminqty = item.pminstepperlabel
}
}
to:
#IBAction func moveToSL(sender: AnyObject) {
if (frc.sections!.count > 0) {
let sectionInfo = self.frc.sections![1]
if (sectionInfo.name == "0") {
let objectsToAppend = sectionInfo.objects as! [List]
for item in objectsToAppend {
item.slist = true
item.slcross = false
item.plist = false
item.slitem = item.pitem
item.slqty = item.pqty
item.sldesc = item.pdesc
item.slprice = item.pprice
item.slminqty = item.pminstepperlabel
}
}
}
}
It is still throwing the error. It will move all the objects as long as section 0 isn't empty. Any more help in figuring this out would be appreciated! Thanks in advance.