Segmented control and table view issue swift - swift

so I am creating a table view with segmented control. at first - I didn't do segmented control but modified some code to at it. When I add numbers to my array, it is not actually populating the cells of the table view. In the table view every time I click a button that appends an amount to the array, the lines increase, but no data is shown. So I know it is working, but it is just not actually displaying the numbers in the table view cells. is there a specific reason why my code will not populate the views?
class SpendingHistoryViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var savedInformation = false
var newDefault : Double?
var selectedSegment = 1
let array2 = ["1","2","3"]
let userDefaults = UserDefaults.standard
#IBOutlet weak var tableViewSpending: UITableView!
#IBOutlet weak var youSpentLabel: UILabel!
#IBOutlet weak var youSavedLabel: UILabel!
#IBOutlet weak var segmentControl: UISegmentedControl!
override func viewDidLoad() {
super.viewDidLoad()
self.tableViewSpending.delegate = self
self.tableViewSpending.dataSource = self
//GETS user defaults that was set in ADDSUBTRACTMONEY VC - and then sets the default to Array- then gets total
let moneySpentArray = UserDefaults.standard.array(forKey: "moneySpent") as? [Double] ?? [Double]()
AddSubtractMoneyController.moneySpentArray = moneySpentArray
let arraySum = moneySpentArray.reduce(0.0, +)
youSpentLabel.text = String(format: "%.2f", arraySum)
}
#IBAction func spentSavedAction(_ sender: UISegmentedControl) {
if sender.selectedSegmentIndex == 0 {
selectedSegment = 1
}
else {
selectedSegment = 2
}
self.tableViewSpending.reloadData()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if selectedSegment == 1 {
return(AddSubtractMoneyController.moneySpentArray.count)
}
else {
return array2.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
//let cell2 = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell2")
let cell2 = tableViewSpending.dequeueReusableCell(withIdentifier: "cell2")! as UITableViewCell
let cell = tableViewSpending.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell
cell.textLabel?.text = String(format: "%.2f", AddSubtractMoneyController.moneySpentArray[indexPath.row])
cell2.textLabel?.text = array2[indexPath.row]
self.tableViewSpending.reloadData()
if selectedSegment == 1 {
return cell
}
else {
return cell2
}
}
}

Related

Why is the data in the collection view cells gets changing when I scroll the table view or the collection view?

I am trying to embed the collection view in the table view. When the page gets loaded I will retrieve the data field by field from the database and reloads the data whenever I retrieve the single field from the database. Here while reloading the table view I need to check the value i.e "oneimage" so if that value is not empty it should set to the collection view cell. The problem is whenever I scroll the table view the data in the collection view cells get swapped. Here is the code below
import UIKit
import Firebase
import FirebaseFirestore
import FirebaseAuth
import SDWebImage
struct values {
var quesvalue: String
var answvalue: String
var ImageUrl = [String]()
}
class QuestionsCell: UITableViewCell,UICollectionViewDelegate {
#IBOutlet weak var collectionview: UICollectionView!
#IBOutlet weak var card: UIView!
#IBOutlet weak var question: UILabel!
#IBOutlet weak var answer: UILabel!
#IBOutlet weak var speakbutton: UIButton!
#IBOutlet weak var collectionviewh: NSLayoutConstraint!
var imageArray = [String] ()
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
extension QuestionsCell {
func setCollectionViewDataSourceDelegate<D: UICollectionViewDataSource &
UICollectionViewDelegate>(dataSourceDelegate: D, forRow row: Int) {
collectionview.delegate = dataSourceDelegate
collectionview.dataSource = dataSourceDelegate
print("collectionviee.tag",collectionview.tag,row)
collectionview.tag = row
collectionview.contentOffset = .zero // Stops collection view if it was scrolling.
}
}
class CollectionViewCell: UICollectionViewCell{
#IBOutlet weak var backcard: UIView!
#IBOutlet weak var imageview: UIImageView!
var task: URLSessionDataTask?
override func awakeFromNib() {
super.awakeFromNib()
}
override func prepareForReuse(){
imageview.image = nil
}
}
class ViewController: UIViewController ,UITableViewDelegate,
UITableViewDataSource,UICollectionViewDataSource,UICollectionViewDelegate {
#IBOutlet weak var tableview: UITableView!
var JSONArray = [String:Any]()
var quesArray = [String]()
var ansArray = [String]()
var answer : String!
var imagesarray = [String]()
var open : [values] = []
var oneimage = [String]()
var storedOffsets = [Int: CGFloat]()
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
tableview.rowHeight=UITableView.automaticDimension
tableview.estimatedRowHeight=150
Firestore.firestore().collection("User").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Popop").document("7ngPwZin2wg7j5JZtI0hKJO8uSA2").collection("Answers").document("Earlyyears").getDocument() { (document, error) in
if let document = document, document.exists {
self.open.removeAll()
self.imagesarray.removeAll()
self.oneimage.removeAll()
if let b1 = document.data()!["Name"] as? [String: Any] {
print("1",b1)
if let firstName = b1["Answer"] as? String {
print("firstName is",firstName)
if firstName != "No answer recorded"{
self.answer = firstName
self.ansArray.append(firstName)
if let imageurlarray = b1["ImageURL"] as? [String] {
self.imagesarray = imageurlarray
print("imageurl array in meaning feild is",imageurlarray)
self.open.insert(values(quesvalue: self.quesArray[0],answvalue: self.answer,ImageUrl: self.imagesarray), at: 0)
self.tableview.reloadData()
}
}
}
}
if let b2 = document.data()!["Meaning"] as? [String: Any] {
print("1")
if let firstName = b2["Answer"] as? String {
print("firstName is",firstName)
if firstName != "No answer recorded"{
self.answer = firstName
self.ansArray.append(firstName)
if let imageurlarray = b2["ImageURL"] as? [String] {
self.imagesarray = imageurlarray
print("imageurl array in meaning feild is",imageurlarray)
self.open.insert(values(quesvalue: self.quesArray[1],answvalue: self.answer,ImageUrl: self.imagesarray), at: 1)
self.tableview.reloadData()
}
}
}
}
} else {
print("Document does not exist")
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("ansArry.count is",open.count)
return open.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("entered into cellfor row at")
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! QuestionsCell
print("quesrray,ansArray are",quesArray,ansArray,open)
if open.count > indexPath.row{
cell.question.text = open[indexPath.row].quesvalue
cell.answer.text = open[indexPath.row].answvalue
print("cell.ques.text",cell.question.text)
oneimage = open[indexPath.row].ImageUrl
print("onimage before checking",oneimage)
if !oneimage.isEmpty{
print("entered into oneimage not empty",oneimage)
cell.collectionview.isHidden = false
cell.collectionviewh.constant = 160
cell.setCollectionViewDataSourceDelegate(dataSourceDelegate: self, forRow: indexPath.row)
}
else{
print("dont show collection view")
cell.collectionview.isHidden = true
cell.collectionviewh.constant = 0
}
}
else{
print("<")
}
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("imagesarray.count is",oneimage.count)
print("oneimage.count")
return oneimage.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: CollectionViewCell = (collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionCell", for: indexPath) as? CollectionViewCell)!
if oneimage.count > indexPath.row{
if oneimage != [""] {
let image = oneimage[indexPath.row]
print("oneimage is",image)
print("entered into oneimage not empty")
cell.imageview.sd_setImage(with: URL(string: image))
}
}
return cell
}
Here are the screenshots of my output.
As I mentioned in the comments, this is because of the reusability. That means when a cell goes out from bottom/top, the same cell (containing the previous setup) comes in from top/bottom. So if you set something async, like a remote image on it, it may be visible on incorrect cell. You should make sure you are selecting correct cell when you are about to set the image on it.
For example you should change this:
cell.imageview.sd_setImage(with: URL(string: image))
to something like this:
(collectionView.cellForItem(at: indexPath) as? CollectionViewCell)?.imageview.sd_setImage(with: URL(string: image))
This will ask the collectionView for the real cell instead of the reused one. I don't know how sd library works, but you may want to do this in the completionHandler of the library.
Maybe this article could help you.

how to search data from model in swift?

I want to search for some data in the table view using the search bar, but when I try to find data in my model, I'm not able to search that data.I made a expand table view cell and created a search bar for searching data, but still I can't search the data in the model. How can I achieve that?
here is my code:
import UIKit
class FAQViewController: UIViewController, UITableViewDataSource {
var dataFaq = [modelFAQ]()
let items = [
modelFAQ(name: "1. search box", description: "The design led users to instinctively search for their question first before clicking the FAQs"),
modelFAQ(name: "2.list of FAQs ", description: "Customers clicked around on the FAQs first."),
modelFAQ(name: "3. customers", description: "top issues first and then use the search for the questions instead of browsing and yielding more relevant results")
]
#IBOutlet fileprivate weak var tableView: UITableView!
#IBOutlet weak var searchDataBar: UISearchBar!
fileprivate var indexPaths: Set<IndexPath> = []
var cellIdentifier = "dataSourceFAQ"
var searchData = [String]()
var searching = false
override var preferredStatusBarStyle: UIStatusBarStyle{
return .lightContent
}
override func viewDidLoad() {
super.viewDidLoad()
setupTableView()
searchDataBar.delegate = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchData.count
}else {
return items.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! FAQTableViewCell
if searching{
cell.titleLabel.text = searchData[indexPath.row]
}else{
cell.titleLabel.text = items[indexPath.row].name
}
let nameDetail = self[indexPath].name as? String
let description = self[indexPath].description
cell.update(name: nameDetail ?? "0", description: description)
cell.state = cellIsExpanded(at: indexPath) ? .expanded : .collapsed
return cell
}
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = true
}
private func setupTableView(){
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 200.0
tableView.separatorStyle = .none
}
}
extension FAQViewController: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as!FAQTableViewCell
cell.state = .expanded
self.addExpandedIndexPath(indexPath)
tableView.beginUpdates()
tableView.endUpdates()
print("1")
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! FAQTableViewCell
cell.state = .collapsed
self.removeExpandedIndexPath(indexPath)
tableView.beginUpdates()
tableView.endUpdates()
print("2")
}
}
extension FAQViewController {
func cellIsExpanded(at indexPath: IndexPath) -> Bool {
return indexPaths.contains(indexPath)
}
func addExpandedIndexPath(_ indexPath: IndexPath) {
indexPaths.insert(indexPath)
}
func removeExpandedIndexPath(_ indexPath: IndexPath) {
indexPaths.remove(indexPath)
}
}
extension FAQViewController {
subscript(indexPath: IndexPath) -> modelFAQ {
return items[indexPath.row]
}
}
extension FAQViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchData = searchText.isEmpty ? items: items.filter{ $0.name(searchText)}
searching = true
tableView.reloadData()
}
}
here is my table view cell
import UIKit
class FAQTableViewCell: UITableViewCell {
enum cellState{
case collapsed
case expanded
var carretImage: UIImage {
switch self {
case .collapsed:
return UIImage(named: "ic_arrow_down")!
case .expanded:
return UIImage(named: "ic_arrow_up")!
}
}
}
#IBOutlet private weak var stackView: UIStackView!
#IBOutlet private weak var containerView: UIView!
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet private weak var carret: UIImageView!
#IBOutlet private weak var descriptionLabel: UILabel!
private let expandedViewIndex: Int = 1
var state: cellState = .expanded {
didSet{
toggle()
}
}
override func awakeFromNib() {
selectionStyle = .none
containerView.layer.cornerRadius = 5.0
}
private func toggle(){
stackView.arrangedSubviews[expandedViewIndex].isHidden = stateIsCollapsed()
carret.image = state.carretImage
}
private func stateIsCollapsed() -> Bool{
return state == .collapsed
}
func update(name: String, description: String){
titleLabel.text = name
descriptionLabel.text = description
}
}
here is my model
struct modelFAQ {
var name: String
var description: String
}
Two issues:
You have to declare searchData as the same type as the main data.
By the way according to the naming convention struct and class names start with a capital letter
var searchData = [ModelFAQ]()
The search filter closure is wrong. Write
searchData = searchText.isEmpty ? items : items.filter{ $0.name.contains(searchText)}
or if you want to search case insensitive
searchData = searchText.isEmpty ? items : items.filter{ $0.name.range(of: searchText, options: .caseInsensitive) != nil }
And you have to change in cellForRowAt
cell.titleLabel.text = searchData[indexPath.row].name
NOTE: Always start class/struct name with CAPITAL LETTER
Wrong: modelFAQ
correct: ModelFAQ
You have made one mistake, you have to declare your searchData Array like below
var searchData = [ModelFAQ]()
and while in datasource method you have to get name from the ModelFAQ object and assign it to your label.
Hope it will help you.

Expand Cell at selectedIndex

Updated Code Below
I am working on comment cells who are limited to 100 characters and if they contain more a "show more button" will show up.
If pressed, the exact cell should reload itself with the number of lines changed to 0 and fully display the cell, no matter how big.
What I have achieved is that cells reload, but not the selected one and kinda arbitrary.
Below is my code for the enlarging process
NOTE: Updatet Code for My Function
Problem: I have to press the button twice to get the result, to minimize and to maximize the cell
#IBAction func readMore(_ sender: UIButton) {
self.state = !self.state
print("state" , state)
self.tapMore.setTitle(self.state ? self.decreaseState: self.expandState, for: .normal)
self.commentLabel.numberOfLines = (self.state ? self.expandedLines: self.numberOfLines)
print(self.commentLabel.numberOfLines)
let myIndexPath = IndexPath(row: sender.tag, section: 0)
UIView.animate(withDuration: 0.3, animations: {
self.parentViewControllerCommentCell?.tableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
})
}
The index comes from
extension CommentTableViewCell {
var indexPath: IndexPath? {
return (superview as? UITableView)?.indexPath(for: self)
}
}
Note
The print statement prints out the chosen cell ( e.g. [0, 1] or [0,0] but it doesn't change then.
Whereas I hardcode my code and change
let myIndexPath = IndexPath(row: indexPath!.row, section: 0)
to
let myIndexPath = IndexPath(row: 0, section: 0)
The feature works, but arbitrarily reloads some cells and arbitrarily enlarges and decreases the cell.
In the variable version with row: indexPath!.row the lines state doesn't change as well, whereas with hardcoded the lines change between 3 and 0.
Thanks for your help :)
Addition
my commentCell
class CommentTableViewCell: UITableViewCell {
#IBOutlet weak var likeCountButton: UIButton!
#IBOutlet weak var profileImageView: UIImageView!
#IBOutlet weak var commentLabel: KILabel!
#IBOutlet weak var nameLabel: UILabel!
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var likeImageView: UIImageView!
#IBOutlet weak var tapMore: UIButton!
#IBOutlet weak var tapMoreButton: UIButton!
var delegate: CommentTableViewCellDelegate?
var postId : String!
Here is a better approach to get you the correct index path. First, in your cellForRow method, add the current index row as tag to your show more button, and then add click action to your button handler function.
Add an outlet of UIButton in you custom UITableViewCell class as
class CustomCell: UITableViewCell {
#IBOutlet var moreButton: UIButton! // Connect your button from storyboard
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCell
cell.moreButton.tag = indexPath.row
/* Just add action normally from storyboard. No need to add target. cell.moreButton.addTarget(self, action:#selector(buttonUp(sender:)), for: .touchUpInside) */
return cell
}
Then in your handler function, you can get the correct index path by reading this tag
func tapForMore(sender: UIButton) {
let myIndexPath = IndexPath(row: sender.tag, section: 0)
print("myindex", myIndexPath)
//... other code here
}
You take class variable and track tap counts. Depending on these variables you can increase or decrease size of cell and reload it.
In YOURViewController declare variables as:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var CommentsTableView: UITableView!
var defaultSizeOfCell = 60.0
var newSize = 80.0
var selectedIndex = -1
var isExpanded = false
var expandCounter = 0
override func viewDidLoad() { ...
Connect button in cell to this action:
#IBAction func moreButtonAction(_ sender: UIButton) {
if !isExpanded {
if expandCounter == 0 {
expandCounter = expandCounter + 1
} else if expandCounter == 1 {
expandCounter = 0
isExpanded = true
selectedIndex = sender.tag
let myIndexPath = IndexPath(row: sender.tag, section: 0)
UIView.animate(withDuration: 0.3, animations: {
self.CommentsTableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
})
print("Increase")
}
} else if isExpanded {
if expandCounter == 0 {
expandCounter = expandCounter + 1
} else if expandCounter == 1 {
expandCounter = 0
isExpanded = false
selectedIndex = -1
let myIndexPath = IndexPath(row: sender.tag, section: 0)
UIView.animate(withDuration: 0.3, animations: {
self.CommentsTableView.reloadRows(at: [myIndexPath], with: UITableViewRowAnimation(rawValue: Int(UITableViewAutomaticDimension))!)
})
print("Decrease")
}
}
}
In tableview datasource function add tag to button:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "testCell", for: indexPath) as! TestTableViewCell
cell.moreButton.tag = indexPath.row
return cell
}
And finally add this delegate method for height of cells:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if selectedIndex == indexPath.row {
return CGFloat(newSize)
} else {
return CGFloat(defaultSizeOfCell)
}
}
Not to mention, button should be in cell and connected to YOURCustomTableViewCell class as:
class TestTableViewCell: UITableViewCell {
#IBOutlet weak var moreButton: UIButton!
I have tested it against your requirements.

UITableview and UICollectionView inside UIScrollView - Swift

Can Anyone Suggest me an idea to create a UI like the below screenshot
https://drive.google.com/open?id=0B2JNfyRRcL0Gb2huQ3ZTV2N6Q1E
I used
ScrollView
imageView
Lable
TableView
Lable
Button
UiView
CollectionView
ImageView
Button
labels…
with this when I’m trying to scroll to down, only the UIScrollView is Scrolling not the UICollectionView.
I Also try to give the UiCollectionView height to its content height and made the scrollview height to fit that. Once i did this the collection view’s datasource and delegate methods are not calling when i use to scroll (means the first time when viewDidLoad - it loads the collection view cell) with the below below scene example the datasource and delegate methods are called only for the first two cells, since it is visible on the screen without scrolling whereas the others are not.
Im thinking to try it with tableview but i don’t know how…. because
the first content which is the banner image may not be in all categories (it may be in JSon response or may not be)
The Explore more label is static lable
The third thing “ Clothing, Bags belts and Wallets “ are the tableviewView Cells (cell count may be differ based on categories)
the forth is a Uiview which has the filter and sorting buttons and its a static one
the last is a collectionView cells (cell count may be differ based on categories)
So, Please Suggest me an Idea or an example or a sample code are highly welcomed….. thanks in Advance….!
Finally I found an idea,
I kept all within a TableView,
The first two (the banner image and the explore lable are the first cell of my tableview)
The second PrototypeCell is the category Titles(where the cloths, bags and belts)
The Third Prototype cell is a what with the filter and sort buttons and I used this cell as section Header View
And finally the last prototype cell is a one which have the collection View and its cell (I just design it and add it into a cell)
And sample code is as follows,
My CollectionViewCell
import UIKit
class CollectionViewCell: UICollectionViewCell {
#IBOutlet weak var imgFav: UIImageView!
#IBOutlet weak var title: UILabel!
#IBOutlet weak var pinImage: UIImageView!
#IBOutlet weak var priceLbl: UILabel!
#IBOutlet var splPriceLbl: UILabel!
#IBOutlet weak var addToFav: UIButton!
override func awakeFromNib()
{
super.awakeFromNib()
self.contentView.autoresizingMask = [UIViewAutoresizing.flexibleRightMargin, UIViewAutoresizing.flexibleLeftMargin, UIViewAutoresizing.flexibleBottomMargin, UIViewAutoresizing.flexibleTopMargin]
self.contentView.translatesAutoresizingMaskIntoConstraints = true
}
}
My TableViewCell
import UIKit
class SubCategoryTableViewCell: UITableViewCell {
#IBOutlet weak var productListCollectVw: UICollectionView!
#IBOutlet weak var btnSort: UIButton!
#IBOutlet weak var btnFilter: UIButton!
#IBOutlet weak var subCategryTitle: UILabel!
#IBOutlet weak var lblExplore: UILabel!
#IBOutlet weak var imgBanner: UIImageView!
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
}
}
And Finally My ViewController
#IBOutlet weak var mainTableView: UITableView!
var subCategoryAry2 = NSMutableArray()
var imageUrl:URL!
var imageUrlStr:String = ""
var productListAry:NSMutableArray = []
func numberOfSections(in tableView: UITableView) -> Int
{
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
if section == 0
{
return subCategoryAry2.count + 1
}
else
{
return 1
}
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
{
if section == 0
{
return nil
}
else
{
let CellIdentifier: String = "section2Cell"
let headerView: SubCategoryTableViewCell? = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! SubCategoryTableViewCell?
headerView?.btnFilter.addTarget(self, action: #selector(self.filterAction(_:)), for: .touchUpInside)
headerView?.btnSort.addTarget(self, action: #selector(self.sortAction(_:)), for: .touchUpInside)
if headerView == nil
{
print("No cells with matching CellIdentifier loaded from your storyboard")
}
return headerView!
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
{
if indexPath.section == 0
{
if indexPath.row == 0
{
let cell:SubCategoryTableViewCell = self.mainTableView.dequeueReusableCell(withIdentifier: "bannerCell") as! SubCategoryTableViewCell!
if self.imageUrlStr == "no_image.png" || self.imageUrlStr == ""
{
cell.imgBanner.isHidden = true
cell.imgBanner.frame.size.height = 0
cell.lblExplore.frame.origin.y = 0
}
else
{
cell.imgBanner.isHidden = false
let imageUrl1 = "\(self.imageUrl!)"
let trimmedUrl = imageUrl1.trimmingCharacters(in: CharacterSet(charactersIn: "")).replacingOccurrences(of: " ", with: "%20") as String
cell.imgBanner.sd_setImage(with: URL(string: trimmedUrl), completed: { (image, error, imageCacheType, imageUrl) in
if image != nil
{
}
else
{
cell.imgBanner.isHidden = true
cell.imgBanner.frame.size.height = 0
cell.lblExplore.frame.origin.y = 0
}
})
}
return cell
}
else //if indexPath.row == 1
{
let cell:SubCategoryTableViewCell = self.mainTableView.dequeueReusableCell(withIdentifier: "listCell") as! SubCategoryTableViewCell!
cell.subCategryTitle.text = (subCategoryAry2.object(at: (indexPath as NSIndexPath).row - 1) as AnyObject).value(forKey: "name") as? String
return cell
}
}
else
{
let cell:SubCategoryTableViewCell = (self.mainTableView.dequeueReusableCell(withIdentifier: "collectionCell") as? SubCategoryTableViewCell!)!
// Load Your CollectionView
cell.productListCollectVw.dataSource = self
cell.productListCollectVw.delegate = self
cell.productListCollectVw.reloadData()
return cell
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
if indexPath.section == 0
{
if indexPath.row != 0
{
//***************** Do whatever you need to do if user did selected the row but remain the indexpath.row or indexpath.row - 1 *****************//
subCategoryID = ((subCategoryAry2.object(at: (indexPath as NSIndexPath).row - 1) as! NSObject).value(forKey: "category_id") as? String)! as NSString
print("tableView - didSelectRowAt \(indexPath.row)")
}
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
{
if indexPath.section == 0
{
var height = CGFloat()
if indexPath.row == 0
{
if self.imageUrlStr == "no_image.png" || self.imageUrlStr == ""
{
//***************** Reduce banner image height if it is nil *****************//
height = 38
}
else
{
height = 175 + 38
}
}
else
{
height = 44
}
return height
}
else
{
let height = (255 * self.productListAry.count/2) + (2 * (self.productListAry.count) + 4)
//***************** increase height as per your need *****************//
return CGFloat(height)
}
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
{
if section == 0
{
return 0
}
else
{
return 44
}
}
func collectionView(_ collectionView: UICollectionView,
numberOfItemsInSection section: Int) -> Int
{
return self.productListAry.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifier, for: indexPath) as! CollectionViewCell
cell.title.text = (self.productListAry.object(at: (indexPath as NSIndexPath).row) as! NSDictionary).value(forKey: "name") as? String
//***************** Load your cell as per your need *****************//
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
{
print("didSelectItemAt \(indexPath.row)")
}
My Storyboard will look like the screenshot added
https://drive.google.com/file/d/0B2JNfyRRcL0GYjJsckpyaGpoMkE/view?usp=sharing

Xcode Swift Table View: Use of Slider and SegmentedControl as custom cells

I am currently using numerous custom cells in a tableview, of which consist of sliders and segmented controls. My issue is that in the simulator, when these rows are selected, the values of the sliders and pickers are reset to default. So for example, if I changed the value of the slider to 10, and then selected the row of the slider, the slider's value would reset to 0. I am trying to diagnose this issue so when the row is selected, the value remains the same; however, I am not sure where this problem arises. I have a hunch that it has something to do with .dequeueReusableCell or .reloadData, but I do not have a great grasp of what they do to start debugging.
Below is my code for cellForRowAt indexPath:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let currentCellDescriptor = getCellDescriptorForIndexPath(indexPath)
let cell = tableView.dequeueReusableCell(withIdentifier: currentCellDescriptor["cellIdentifier"] as! String, for: indexPath) as! CustomCell
// I am using identifiers to set Titles within the TableView
if currentCellDescriptor["cellIdentifier"] as! String == "idCellNormal" {
if let primaryTitle = currentCellDescriptor["primaryTitle"] {
cell.textLabel?.text = primaryTitle as? String
}
eventType = ((cellDescriptors[0] as! NSMutableArray)[0] as! NSDictionary)["primaryTitle"]! as! String
if let secondaryTitle = currentCellDescriptor["secondaryTitle"] {
cell.detailTextLabel?.text = secondaryTitle as? String
}
}
else if currentCellDescriptor["cellIdentifier"] as! String == "idCellTextfield" {
cell.textField.placeholder = currentCellDescriptor["primaryTitle"] as? String
}
else if currentCellDescriptor["cellIdentifier"] as! String == "idCellValuePicker" {
cell.textLabel?.text = currentCellDescriptor["primaryTitle"] as? String
}
cell.delegate = self
return cell
}
Code from CustomCell, my class for all my cells
//outlet properties
#IBOutlet weak var moneyLabel: UILabel!
#IBOutlet weak var moneySlider: UISlider!
#IBOutlet weak var privacy: UISegmentedControl!
#IBAction func sliderValueChanged(_ sender: UISlider) {
moneyValue = Int(sender.value)
moneyLabel.text = String(moneyValue)
moneyAmount = moneyLabel.text!
}
#IBAction func privacyChanged(_ sender: AnyObject) {
switch privacy.selectedSegmentIndex
{
case 0:
print("public")
privacyDescription = "public"
case 1:
print("private")
privacyDescription = "private"
default:
break;
}
}