Swift CollectionView ReloadData Acting Weird - ios

I have a Collection View and a button at the top and that button goes through a list of days. For each day, the collection view should be different and I keep track of changes in a dictionary. However, at each press of the button, I want to reload the data, but it's selecting random cells. When data is reloaded, does it run the cellforitematindexpath over again; if not what exactly does it run?
Here's my CellForItem code:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("availability", forIndexPath: indexPath) as! AvailabilityCell
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
cell.timeInterval.text = timeIntervals[indexPath.row]
cell.timePeriod.text = timesForIntervals[indexPath.row]
cell.timeInterval.textColor = DARK_BLUE
cell.timePeriod.textColor = DARK_BLUE
cell.backView.layer.cornerRadius = 10
cell.backView.layer.masksToBounds = true
cell.backView.layer.borderColor = DARK_BLUE.CGColor
cell.backView.layer.borderWidth = 1
cell.selected = false
if (tempList[indexPath.row] == 1) {
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
}
return cell
}
Here's my Cell Did Select/Deselect:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = UIColor.whiteColor()
cell.backView.backgroundColor = DARK_BLUE
cell.timePeriod.textColor = UIColor.whiteColor()
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 1
self.availability[self.days[index]] = tempList
}
func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! AvailabilityCell
cell.timeInterval.textColor = DARK_BLUE
cell.backView.backgroundColor = UIColor.whiteColor()
cell.timePeriod.textColor = DARK_BLUE
var tempList: [Int]
tempList = self.availability[self.days[index]]! as! [Int]
tempList[indexPath.row] = 0
self.availability[self.days[index]] = tempList
}
Here's where data is reloaded:
#IBAction func decreaseDay(sender: AnyObject) {
index--
day.text = days[index]
dispatch_async(dispatch_get_main_queue()) {
self.timeCollection.reloadData()
}
if (index == 0) {
back.enabled = false
}
forward.enabled = true
}
Here's a view of what's happening:
How it starts:
When I reload:

I believe you should change the swift collection view to reload the page on the left hand corner. The data is reloaded to select the most prioritized item in the download list. Hope this helps!

Related

code being fetch from core data is not being displayed correctly in tableview cell label

I am fetching from core data and printing it on label. The problem what is being printed on the label has a lot of run off stuff. As you can see in the photo below. In each collection view cell I want it to print 1 element of the array. So if the array has [vanessa,taylor,bastista]. Collection view cell should print vanessa.
var people: [Jessica] = []
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = newCollection.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomeCell
cell.backgroundColor = .white
cell.layer.cornerRadius = 5
cell.layer.shadowOpacity = 3
cell.textLabel.text = people[indexPath.row].playName
return cell
}
MORE METHODS
override func viewWillAppear(_ animated: Bool) {
fetchData()
}
func fetchData() {
do {
items = try context.fetch(Jessica.fetchRequest())
DispatchQueue.main.async {
self.newCollection.reloadData()
}
} catch {
print("Couldn't Fetch Data")
}
}
link to Core Data Pic
pic of collection view cell
var people: [People] = [] //Any suitable variable
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = newCollection.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomeCell
cell.backgroundColor = .white
cell.layer.cornerRadius = 5
cell.layer.shadowOpacity = 3
cell.textLabel.text = people[indexPath.row].name //retrieve the name from your array
return cell
}
func fetchData() {
do {
people = fetchPeople()
DispatchQueue.main.async {
self.newCollection.reloadData()
}
} catch {
print("Couldn't Fetch Data")
}
}
func fetchPeople() -> [People] {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return [] }
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "PeopleEntity")
let items = try! context.fetch(fetchRequest)
var detail: [People] = []
for data in items as! [NSManagedObject] {
var p = People(name: (data.value(forKey: "name") as? String) ?? "N/A") //check for nil
detail.append(p)
}
return detail
}

How to handle two table views in single view controller by using xibs as cell

I am trying to use the segment controller with 3 segments. If I click on first segment, I should get one tableview. When I click on second segment, I should get second tableview and for third segment I should get 3rd table view. Here I am using XIB's for tableview cell. I tried something but I am not getting any data in the table. The table is loading. But the cell is not loading. I am giving my code below. If any one helps me, would be very great. Thanks in advance.
var arr1 = ["1","2","3","4"]
var imagesarray = [UIImage(named: "11.png")!, UIImage(named: "22.png")!, UIImage(named: "33.png")!,UIImage(named: "11.png")!,UIImage(named: "22.png")!, UIImage(named: "33.png")!]
override func viewDidLoad() {
super.viewDidLoad()
view_track.isHidden = false
view_watch.isHidden = true
view_ebooks.isHidden = true
table_track.register(UINib(nibName: "ProgramMListenTableViewCell", bundle: nil), forCellReuseIdentifier: "ProgramMListenTableViewCell")
table_watch.register(UINib(nibName: "ProgramMWatchTableViewCell", bundle: nil), forCellReuseIdentifier: "ProgramMWatchTableViewCell")
table_watch.register(UINib(nibName: "ProgramEbooksTableViewCell", bundle: nil), forCellReuseIdentifier: "ProgramEbooksTableViewCell")
table_ebooks.delegate = self
table_ebooks.dataSource = self
table_track.delegate = self
table_track.dataSource = self
table_watch.delegate = self
table_watch.dataSource = self
self.navigationController?.setNavigationBarHidden(true, animated: false)
}
#IBAction func Segment(_ sender: Any) {
switch segment_program.selectedSegmentIndex
{
case 0:
view_track.isHidden = false
view_watch.isHidden = true
view_ebooks.isHidden = true
self.table_track.reloadData()
break
case 1:
view_track.isHidden = true
view_watch.isHidden = false
view_ebooks.isHidden = true
self.table_watch.reloadData()
name_program.text = "Videos"
break
case 2:
view_track.isHidden = true
view_watch.isHidden = true
view_ebooks.isHidden = false
self.table_ebooks.reloadData()
name_ebooks.text = "Ebooks"
break
default:
break
}
}
}
extension ProgramMListenViewController: UITableViewDataSource,UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if tableView == table_track{
return self.arr1.count
}else if tableView == table_watch{
return self.imagesarray.count
}else{
return self.arr1.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table_track{
let cell = table_track.dequeueReusableCell(withIdentifier: "ProgramMListenTableViewCell") as! ProgramMListenTableViewCell
}else if tableView == table_watch{
let cell = table_watch.dequeueReusableCell(withIdentifier: "ProgramMWatchTableViewCell") as! ProgramMWatchTableViewCell
cell.img_watch.image = imagesarray[indexPath.row]
}else if tableView == table_ebooks{
let cell = table_ebooks.dequeueReusableCell(withIdentifier: "ProgramEbooksTableViewCell") as! ProgramEbooksTableViewCell
cell.image_ebooks.image = imagesarray[indexPath.row]
}
return UITableViewCell()
}
}
You have to return your cell, instead of always returning UITableViewCell()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if tableView == table_track{
let cell = table_track.dequeueReusableCell(withIdentifier: "ProgramMListenTableViewCell") as! ProgramMListenTableViewCell
return cell
}else if tableView == table_watch{
let cell = table_watch.dequeueReusableCell(withIdentifier: "ProgramMWatchTableViewCell") as! ProgramMWatchTableViewCell
cell.img_watch.image = imagesarray[indexPath.row]
return cell
}else if tableView == table_ebooks{
let cell = table_ebooks.dequeueReusableCell(withIdentifier: "ProgramEbooksTableViewCell") as! ProgramEbooksTableViewCell
cell.image_ebooks.image = imagesarray[indexPath.row]
return cell
}
return UITableViewCell()
}
As mentioned before you need to return the respective UITableViewCell, depending on the table in order for it to be shown. You should watch for errors in dequeueReusableCell(), thus I recommend the following implementation:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var returnCell = UITableViewCell()
if tableView == table_track{
guard let cell = table_track.dequeueReusableCell(withIdentifier: "ProgramMListenTableViewCell") as? ProgramMListenTableViewCell else {
print("Error getting cell as ProgramMListenTableViewCell")
return returnCell
}
/*Customize your cell*/
returnCell = cell
}else if tableView == table_watch{
guard let cell = table_watch.dequeueReusableCell(withIdentifier: "ProgramMListenTableViewCell") as? ProgramMWatchTableViewCell else {
print("Error getting cell as ProgramMWatchTableViewCell")
return returnCell
}
/*Customize your cell*/
cell.img_watch.image = imagesarray[indexPath.row]
returnCell = cell
}else if tableView == table_ebooks{
guard let cell = table_ebooks.dequeueReusableCell(withIdentifier: "ProgramMListenTableViewCell") as? ProgramEbooksTableViewCell else {
print("Error getting cell as ProgramEbooksTableViewCell")
return returnCell
}
cell.image_ebooks.image = imagesarray[indexPath.row]
returnCell = cell
}
return returnCell
}
This way you have a safe way of getting the correct type of your cell, editing it and returning it to the corresponding table.

UICollectionViewCell reuse causing incorrect UISwitch state

I am having trouble finding a solution for this issue.
I am using UISwitch inside UICollectionViewCell and I am passing a boolean variable to set switch on or off.
The condition is only one switch has to be ON at a time from all cells.
But When I turn one switch on another random switch's tint color changes that means its state changed.
By default switch status is ON in storyboard and even if I set it OFF nothing changes.
I couldn't figure out why is this happening.
Here is my code for cellForItemAtIndexPath
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
cell.delegate = self
let currentDiscount = allDiscounts[indexPath.item]
let shouldApplyDiscount = updatedDiscountId == currentDiscount.id
cell.updateCellWith(data: currentDiscount, applyDiscount: shouldApplyDiscount)
return cell
}
And code for cell class
func updateCellWith(data: DiscountModel, applyDiscount: Bool) {
let name = data.title.replacingOccurrences(of: "Discount ", with: "")
self.titleLabel.text = String(format: "%# (%.2f%%)", name, data.value)
self.switchApply.isOn = applyDiscount
self.switchApply.tag = data.id
}
Data source contains objects of DiscountModel which look like this:
{
id: Int!
title: String!
value: Double!
}
Switch value changed method inside cell class:
#IBAction func switchValueChanged(_ sender: UISwitch) {
if sender.isOn {
self.delegate?.switchValueDidChangeAt(index: sender.tag)
}
else{
self.delegate?.switchValueDidChangeAt(index: 0)
}
}
Delegate method inside view controller class:
func switchValueDidChangeAt(index: Int) {
self.updatedDiscountId = index
self.discountCollectionView.reloadData()
}
There are a few improvements I would suggest to your code;
Reloading the entire collection view is a bit of a shotgun
Since it is possible for there to be no discount applied, you should probably use an optional for your selected discount, rather than "0"
Using Tag is often problematic
I would use something like:
var currentDiscount: DiscountModel? = nil
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
cell.delegate = self
let item = allDiscounts[indexPath.item]
self.configure(cell, forItem: item)
return cell
}
func configure(_ cell: DiscountCollectionViewCell, forItem item: DiscountModel) {
cell.switchApply.isOn = false
let name = item.title.replacingOccurrences(of: "Discount ", with: "")
self.titleLabel.text = String(format: "%# (%.2f%%)", name, item.value)
guard let selectedDiscount = self.currentDiscount else {
return
}
cell.switchApply.isOn = selectedDiscount.id == item.id
}
func switchValueDidChangeIn(cell: DiscountCollectionViewCell, to value: Bool) {
if value {
if let indexPath = collectionView.indexPath(for: cell) {
self.currentDiscount = self.allDiscounts[indexPath.item]
}
} else {
self.currentDiscount = nil
}
for indexPath in collectionView.indexPathsForVisibleItems {
if let cell = collectionView.cellForItem(at: indexPath) {
self.configure(cell, forItem: self.allDiscounts[indexPath.item])
}
}
}
In your cell:
#IBAction func switchValueChanged(_ sender: UISwitch) {
self.delegate?.switchValueDidChangeIn(cell:self, to: sender.isOn)
}

Transferring UITableView Section to Another TableView

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.

Video Plays in several uitableView Cells ios

I have a big issue with my UITableView. im trying to desplay a video when user tap on a perticular cell. but my problem is when i scroll the tableiew, the video is appered in other cells also. how can i prevent this ?
here is my code (Im Using BrihgtCove to show the Video)
class CatagoryOne: UITableViewController,BCOVPlaybackControllerDelegate {
// MARK: - BrightCove Properties
let catalogService = BCOVCatalogService(token:kViewControllerCatalogToken)
var playbackController :BCOVPlaybackController?
var avpvs : AVPlayerViewController?
static var selectedRow : Int?
required init?(coder aDecoder: NSCoder) {
let manager = BCOVPlayerSDKManager.sharedManager();
avpvs = AVPlayerViewController()
playbackController = manager.createPlaybackControllerWithViewStrategy(manager.defaultControlsViewStrategy())
super.init(coder: aDecoder)
playbackController!.analytics.account = kPublistherID
playbackController!.delegate = self
playbackController!.autoAdvance = true
playbackController!.autoPlay = true
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("VideoItemCell", forIndexPath: indexPath) as! NewVideoItemCell
print("indexPath on cellForRowAtIndexPath = " ,indexPath.row)
print("selectedRow on cellForRowAtIndexPath = " ,CellReUseModel.selectedRow)
// Configure the cell...
configureVideoListCell(cell, atRow: indexPath.row)
return cell
}
func configureVideoListCell (cell : NewVideoItemCell,atRow : Int) {
//cell.backgroundColor = Colors.videoListItemColor
cell.videoTitle.textColor = Colors.videoListTextColor
cell.videoTitle.text = videoModel.titleOfVideoList(atRow)
//cell.thumbNail.image = videoModel.thumbnailForVideoItem(atRow)
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as! NewVideoItemCell
print("indexpath Row = " ,indexPath.row)
CellReUseModel.selectedRow = indexPath.row
print("Selected Row = " ,CellReUseModel.selectedRow)
//self.tableView.reloadData()
// the Code that plays the video
self.addChildViewController(avpvs!)
avpvs!.view.frame = cell.contentView.bounds
avpvs!.view.autoresizingMask = [.None]
avpvs!.videoGravity = AVLayerVideoGravityResizeAspectFill
cell.contentView.addSubview(self.avpvs!.view)
avpvs!.didMoveToParentViewController(self)
requestContentFromCatalog()
}
}
Please help me with this :(

Resources