How to deselect all buttons when one of them is selected - swift

I have a tableview and inside one of my rows I have buttons. I want to deselect all buttons when one is selected and change the background color to the red when button is selected. I saw lots of example but I couldn't do it in my own code.
func configure(_ modelArray : [UnitAndColors], colorTitle:String, packingTitle:String) {
self.unitStackView.removeAllArrangedSubviews()
self.arrayUnitsAndColor?.removeAll()
self.arrayUnitsAndColor = modelArray
let filteredArray = self.arrayUnitsAndColor?.unique { $0.colorDesc }
var i : Int = 0
filteredArray?.forEach { units in
let vw = self.createUnits(units, tag: i)
self.unitStackView.addArrangedSubview(vw)
vw.snp.makeConstraints {
$0.size.equalTo(40.0)
}
i = i + 1
}
}
func createUnits(_ model : UnitAndColors, tag: Int) -> UIStackView {
let stackViewMain = UIStackView()
stackViewMain.axis = .horizontal
stackViewMain.spacing = 4
let labelPackingUnit = UIButton()
labelPackingUnit.backgroundColor = Colors().colorWhite
labelPackingUnit.tag = tag
labelPackingUnit.setTitleColor(Colors().colorRed, for: .normal)
labelPackingUnit.addTarget(self, action: #selector(selectUnit(_:)), for: .touchUpInside)
labelPackingUnit.titleLabel?.font = UIFont.fontBold16
labelPackingUnit.contentHorizontalAlignment = .center
labelPackingUnit.setBorder(width: 1, color: Colors().colorRed)
labelPackingUnit.setCornerRound(value: 20.0)
labelPackingUnit.setTitle(model.unitDesc, for: .normal)
stackViewMain.addArrangedSubview(labelPackingUnit)
labelPackingUnit.snp.makeConstraints {
$0.size.equalTo(40)
}
return stackViewMain
}
#objc private func selectButton(_ sender : UIButton) {
let tag : Int = sender.tag
guard let model : UnitAndColors = self.arrayUnitsAndColor?.filter({ $0.colorDesc == selectedColorName })[tag] else { return }
selectedUnit = model.unitDesc ?? ""
delegate?.changePrice(selectedPrice: model.modelPrice, arrayUnitsAndColor ?? [])
}

It's pretty frustrating to understand what's happening in your code, but I think that's what you're looking for:
#objc private func selectButton(_ sender : UIButton) {
let tag : Int = sender.tag
guard let model: UnitAndColors = self.arrayUnitsAndColor?.filter({ $0.colorDesc == selectedColorName })[tag] else { return }
selectedUnit = model.unitDesc ?? ""
for stackView in unitStackView.arrangedSubviews as? [UIStackView] ?? [] {
guard let button = stackView.arrangedSubviews.first as? UIButton else {
return
}
button.isSelected = false
button.backgroundColor = .clear
}
selectedUnit.isSelected = true
selectedUnit.backgroundColor = .red
delegate?.changePrice(selectedPrice: model.modelPrice, arrayUnitsAndColor ?? [])
}

var selectedRows: [Int] = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.allowMultipleSelection = true
}
func selectAll(){
for i in 0..<totalRows.count{
selectedRows.append(i)
let indexPath = IndexPath(row: i, section: 0)
self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
}
}
func deselectAll(){
for i in 0..<totalRows.count{
selectedRows.append(i)
let indexPath = IndexPath(row: i, section: 0)
self.tableView.deselectRow(at: indexPath, animated: true)
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath){
selectedRows.append(indexPath.row)
print(selectedRows)
}
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
if let index = selectedRows.firstIndex(of: indexPath.row) {
selectedRows.remove(at: index)
}
print(selectedRows)
if selectedRows.isEmpty{
}
}
}
class TableViewCell: UITableViewCell{
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if (selected) {
print("selected")
contentView.backgroundColor = .red
} else {
contentView.backgroundColor = .red
}
}
}

Related

Xcode Visual Memory Debugger. What does it mean if some object is not released and this object and is a not UIViewController

When I close all VC and go back to my root I see that some element views and cells, like HeaderViewNew, DisposalsShimmering, exist in a heap, these elements are declared like lazy var, why is this element not released from memory if I close VC that use it, it is normal, or I did some mistake?
I know that if I have a few examples of VC in memory this is a retail cycle, but with this element inside the heap hierarchy I am a little confused, and using info inside the Memory graph (main window) I can't solve this problem
Example of an object that has not been released:
import UIKit
protocol HeaderMenuOptionSelected: AnyObject {
func menuSelected(index: Int, title: String)
}
class HeadeViewMenu: UIView, UITableViewDelegate, UITableViewDataSource {
private var hiddenRows: Array<Int> = Array()
private var cellSize: CGFloat = 60
var selectedIndex: Int!
var tabBarHeight: CGFloat!
var tabBar: UIView!
let tabBarView = UIView()
var menuHeight: CGFloat = 0
var P_menuHeightConstraint: NSLayoutConstraint!
var menuArr: Array<HeaderMenuListOfOptions> = Array()
weak var delegate: HeaderMenuOptionSelected?
func clearMenuOptions() {
menuArr.removeAll()
P_menu.reloadData()
}
func setupListOfOptions(menuList: [HeaderMenuListOfOptions]) {
menuArr = menuList
P_menu.reloadData()
}
func setupMenuHeight(countOfElement: Int) {
menuHeight = cellSize * CGFloat(countOfElement)
}
// This trick need to use because if user open menu but user level not yet applied, after fetching setting from server need to update menu in menu open, but only ONE time
private var firstTimeOpen = true
func updateMenuHeight() {
guard firstTimeOpen != false else { return }
firstTimeOpen = false
if (P_menuHeightConstraint.constant != 0) {
menuHeight = cellSize * CGFloat(menuArr.count)
P_menuHeightConstraint.constant = menuHeight
UIView.animate(withDuration: 0.2) {
self.layoutIfNeeded()
} completion: { anim in
}
}
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
menuArr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HeaderMenuCell
// iOS way to set default text label
// var content = cell.defaultContentConfiguration()
// content.text = "test"
// cell.contentConfiguration = content
cell.P_label.text = menuArr[indexPath.row].title
cell.selectionStyle = .none
cell.P_label.isHidden = needHideElement(index: indexPath.row)
cell.P_img.isHidden = needHideElement(index: indexPath.row)
cell.P_countOfElements.isHidden = needHideElement(index: indexPath.row)
if selectedIndex == indexPath.row {
cell.P_img.image = UIImage(named: menuArr[indexPath.row].selectedImg)
cell.P_label.textColor = menuArr[indexPath.row].selectedColor
cell.initCount(count: menuArr[indexPath.row].count)
} else {
cell.P_img.image = UIImage(named: menuArr[indexPath.row].img)
cell.P_label.textColor = menuArr[indexPath.row].unselectedColor
cell.initCount(count: menuArr[indexPath.row].count)
}
return cell
}
func openPageByImitationGesture(index: Int) {
hideMenu()
delegate?.menuSelected(index: index, title: menuArr[index].title)
selectedIndex = index
P_menu.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("index menu \(indexPath.row)")
hideMenu()
// FeedbackGenerator.shared.interactionFeedback()
// guard selectedIndex != indexPath.row else { return }
delegate?.menuSelected(index: indexPath.row, title: menuArr[indexPath.row].title)
// let cell = tableView.cellForRow(at: indexPath) as! HeaderMenuCell
selectedIndex = indexPath.row
tableView.reloadData()
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return getRowHeight(index: indexPath.row)
}
func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath) {
print("index unhi....\(indexPath.row)")
}
lazy var P_menu: UITableView = {
let view = UITableView()
view.translatesAutoresizingMaskIntoConstraints = false
view.delegate = self
view.dataSource = self
view.register(HeaderMenuCell.self, forCellReuseIdentifier: "cell")
view.isScrollEnabled = false
view.separatorColor = .clear
view.separatorStyle = .none
return view
}()
lazy var P_menuView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.translatesAutoresizingMaskIntoConstraints = false
view.layer.shadowColor = UIColor.black.cgColor
view.layer.shadowOpacity = 0.2
view.layer.shadowOffset = CGSize(width: 0, height: 5)
view.layer.shadowRadius = 2
return view
}()
lazy var P_backgroundView: UIView = {
let view = UIView()
view.backgroundColor = .black
view.translatesAutoresizingMaskIntoConstraints = false
view.alpha = 0
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(clickAtBackgroundView))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
view.addGestureRecognizer(tapGesture)
view.isUserInteractionEnabled = true
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.translatesAutoresizingMaskIntoConstraints = false
setupView()
}
deinit {
print("deinit called NewHeaderMenu")
}
func setupView() {
self.isHidden = true
self.addSubview(P_backgroundView)
self.addSubview(P_menuView)
self.P_menuView.addSubview(P_menu)
P_backgroundView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
P_backgroundView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
P_backgroundView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
P_backgroundView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
P_menu.topAnchor.constraint(equalTo: P_menuView.topAnchor).isActive = true
P_menu.leadingAnchor.constraint(equalTo: P_menuView.leadingAnchor).isActive = true
P_menu.trailingAnchor.constraint(equalTo: P_menuView.trailingAnchor).isActive = true
P_menu.bottomAnchor.constraint(equalTo: P_menuView.bottomAnchor).isActive = true
P_menuView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
P_menuView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
P_menuView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
P_menuHeightConstraint = P_menuView.heightAnchor.constraint(equalToConstant: 0)
P_menuHeightConstraint.isActive = true
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func openMenu() {
self.isHidden = false
UIView.animate(withDuration: 0.1) {
self.P_backgroundView.alpha = 0.2
self.hideTabBar()
} completion: { anim in
if (anim == true) {
self.P_menuHeightConstraint.constant = self.menuHeight
UIView.animate(withDuration: 0.2) {
self.layoutIfNeeded()
} completion: { anim in
}
}
}
}
func hideMenu() {
P_menuHeightConstraint.constant = 0
UIView.animate(withDuration: 0.2) {
self.layoutIfNeeded()
} completion: { anim in
if (anim == true) {
UIView.animate(withDuration: 0.1) {
self.P_backgroundView.alpha = 0
self.showTabBar()
} completion: { anim in
if (anim == true) {
self.isHidden = true
}
}
}
}
}
func needToHideRows(rows: [Int]) {
hiddenRows = rows
let countOfElements = (menuArr.count - rows.count)
print("Menu count of elements \(countOfElements)")
setupMenuHeight(countOfElement: countOfElements)
P_menu.reloadData()
}
func unhideAllElements(count: Int) {
hiddenRows = []
setupMenuHeight(countOfElement: count)
P_menu.reloadData()
}
func getRowHeight(index: Int) -> CGFloat {
var size: CGFloat = menuHeight / CGFloat(menuArr.count - hiddenRows.count)
hiddenRows.forEach { obj in
if (index == obj) {
size = 0
}
}
return size
}
func needHideElement(index: Int) -> Bool {
var needToHide = false
hiddenRows.forEach { obj in
if (index == obj) {
needToHide = true
}
}
return needToHide
}
func setupTabBar(view: UIView) {
guard tabBarHeight != nil else {
return
}
tabBar = view
tabBar.addSubview(tabBarView)
tabBarView.translatesAutoresizingMaskIntoConstraints = false
tabBarView.backgroundColor = .black
tabBarView.heightAnchor.constraint(equalToConstant: tabBarHeight).isActive = true
tabBarView.leadingAnchor.constraint(equalTo: tabBar.leadingAnchor).isActive = true
tabBarView.trailingAnchor.constraint(equalTo: tabBar.trailingAnchor).isActive = true
tabBarView.bottomAnchor.constraint(equalTo: tabBar.bottomAnchor).isActive = true
tabBarView.alpha = 0
}
func hideTabBar() {
UIView.animate(withDuration: 0.1) {
self.tabBarView.alpha = 0.2
}
}
func showTabBar() {
UIView.animate(withDuration: 0.1) {
self.tabBarView.alpha = 0
}
}
#objc func clickAtBackgroundView() {
hideMenu()
delegate?.menuSelected(index: selectedIndex, title: menuArr[selectedIndex].title)
}
func selectOptionNonProgrammatically(index: Int) {
// This function need for fixind problem when user open app and app had list of sevec filters for disposal tab
hideMenu()
// delegate?.menuSelected(index: index, title: title)
delegate?.menuSelected(index: index, title: menuArr[index].title)
}
func updateCounter(index: Int, count: Int?) {
guard count != nil && count != 0 else { return }
menuArr[index].count = count
P_menu.reloadData()
}
}
Inside VC that contained this element I do next:
1. Init
lazy var P_headerViewNewMenu: HeadeViewMenu = {
let view = HeadeViewMenu()
view.delegate = self
return view
}()
2. Deinit
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
P_headerViewNewMenu.delegate = nil
}
3. Init constraints
self.view.addSubview(P_headerViewNewMenu)
P_headerViewNewMenu.topAnchor.constraint(equalTo: P_headerViewNew.bottomAnchor).isActive = true
P_headerViewNewMenu.leadingAnchor.constraint(equalTo: P_headerViewNew.leadingAnchor).isActive = true
P_headerViewNewMenu.trailingAnchor.constraint(equalTo: P_headerViewNew.trailingAnchor).isActive = true
P_headerViewNewMenu.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
P_headerViewNewMenu.tabBarHeight = self.tabBarController?.tabBar.frame.height
P_headerViewNewMenu.setupTabBar(view: (self.tabBarController?.view)!)
I found the problem with be help of matt, years of experience of asking the right question ;) Problem was inside P_headerViewNewMenu.setupTabBar(view: (self.tabBarController?.view)!)
link to the object was not released.
Because VC was deallocated, and all objects continue to be in the heap, I haven't been understood that these are all objects that not called deinit, but VC was released from memory

want to display data on Home screen from searched data coming from api

I am making an app in which i have a home screen which lists categories and store data into tableview. in tableview i have a search button which navigates me to search screen when clicked and on search screen i have taken custom textfield to search. Now i want that when i search something and it shows in result then when i click on searched result then it should show data of the category or store selected on previous home screen. And the search result is category data and store data. All data is coming from api and am using tableview to show search data
screenshot for coupons api in which search data will be display:
screenshot for search api:
code for my search screen is as below:
class SearchPageController: UIViewController {
#IBOutlet weak var searchTxtBar: UITextField!
#IBOutlet weak var searchTblView: UITableView!
var searchData = [ModelSearched]()
override func viewDidLoad() {
super.viewDidLoad()
self.hideKeyboardWhenTappedAround()
// Do any additional setup after loading the view.
searchTxtBar.delegate = self
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
//MARK: IBActions
#IBAction func toHomeScreen(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
func getSearchList(){
let params: Parameters=[
"search":searchTxtBar.text!,
]
if ApiUtillity.sharedInstance.isReachable()
{
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseSearchList>().API_GET(Url: SD_GET_SearchList, Params: params as [String:AnyObject], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
self.searchData.removeAll()
let resul_array_tmp_new = modelResponse.searched! as NSArray
if resul_array_tmp_new.count > 0 {
for i in modelResponse.searched! {
self.searchData.append(i)
}
}
}
else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.searchTblView.reloadData()
}) { (failed) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.view.makeToast(failed.localizedDescription)
}
}
else
{
self.view.makeToast("No Internet Connection..")
}
}
#IBAction func clearSearchData(_ sender: UIButton) {
self.searchData.removeAll()
self.searchTxtBar.text = ""
searchTblView.reloadData()
}
}
//MARK: Tableview delegates and datasource methods
extension SearchPageController: UITableViewDelegate, UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return searchData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "catstoredata")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "catstoredata")
}
let dict = searchData[indexPath.row]
cell?.selectionStyle = .none
cell?.textLabel?.text = dict.name
return cell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.navigationController?.popViewController(animated: true)
}
}
//MARK: textfield delegates method
extension SearchPageController: UITextFieldDelegate{
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
self.searchTxtBar.resignFirstResponder()
self.searchTblView.reloadData()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.getSearchList()
}
}
code for my home screen is as below:
class HomeViewController: UIViewController {
var couponsData = [ModelCoupons]()
var colorList = [UIColor]()
var selectedIds = [Int]()
#IBOutlet var logoutPopup: UIView!
#IBOutlet weak var homeTblView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
//append colors
colorList.append(UIColor(rgb: 0xdd191d))
colorList.append(UIColor(rgb: 0xd81b60))
colorList.append(UIColor(rgb: 0x8e24aa))
colorList.append(UIColor(rgb: 0x5e35b1))
colorList.append(UIColor(rgb: 0x3949ab))
colorList.append(UIColor(rgb: 0x4e6cef))
colorList.append(UIColor(rgb: 0x00acc1))
colorList.append(UIColor(rgb: 0x00897b))
colorList.append(UIColor(rgb: 0x0a8f08))
colorList.append(UIColor(rgb: 0x7cb342))
colorList.append(UIColor(rgb: 0xc0ca33))
colorList.append(UIColor(rgb: 0xfdd835))
colorList.append(UIColor(rgb: 0xfb8c00))
colorList.append(UIColor(rgb: 0xf4511e))
colorList.append(UIColor(rgb: 0xf4511e))
colorList.append(UIColor(rgb: 0x757575))
colorList.append(UIColor(rgb: 0x546e7a))
self.homeTblView.register(UINib(nibName: "HomeCell", bundle: nil), forCellReuseIdentifier: "HomeCell")
self.homeTblView.register(UINib(nibName: "Home1Cell", bundle: nil), forCellReuseIdentifier: "Home1Cell")
self.post_CouponsData()
self.homeTblView.reloadData()
print(selectedIds)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
func changeDateForamte(dateString: String, currentDateFormate: String, newDateFormate: String) -> String
{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = currentDateFormate
let newDate = dateFormatter.date(from: dateString)
dateFormatter.dateFormat = newDateFormate
return dateFormatter.string(from: newDate!)
}
#IBAction func logout_yes(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginViewController") as! LoginViewController
self.navigationController?.pushViewController(vc, animated: true)
}
#IBAction func logout_no(_ sender: Any) {
self.logoutPopup.removeFromSuperview()
}
#objc func openDeals(sender: UIButton) {
let svc = SFSafariViewController(url: URL(string: couponsData[sender.tag].guid!)!)
self.present(svc, animated: true, completion: nil)
}
//MARK: IBActions
#IBAction func toCategoryScreen(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func toSearchPage(_ sender: UIButtonX) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SearchPageController") as! SearchPageController
self.navigationController?.pushViewController(vc, animated: true)
}
#IBAction func logoutBtnPressed(_ sender: Any) {
ApiUtillity.sharedInstance.AddSubViewtoParentView(parentview: self.view, subview: logoutPopup)
}
func post_CouponsData() {
if ApiUtillity.sharedInstance.isReachable() {
var params = [String : String]()
params ["term_ids"] = "\(self.selectedIds.map(String.init).joined(separator: ","))"
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseCouponsList>().API_POST(Url: SD_POST_CouponsList, Params: params as [String:AnyObject], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
ApiUtillity.sharedInstance.StopProgress(view: self.view)
let dict = modelResponse.coupons
for i in dict! {
self.couponsData.append(i)
}
}else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.homeTblView.reloadData()
}) { (failed) in
self.view.makeToast(failed.localizedDescription)
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}else {
self.view.makeToast("No internet connection...")
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return couponsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if !couponsData[indexPath.row].postImage!.isEmpty {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeCell
let dict = couponsData[indexPath.row]
if let postTitle = dict.postTitle, postTitle.count != 0 {
cell.ticket_postTitle.text = postTitle
}
if let postContent = dict.postContent, postContent.count != 0 {
cell.ticket_postContent.text = postContent
}
if let storeName = dict.stores, storeName.count != 0 {
cell.storename.text = storeName
}
cell.home_image.image = UIImage(named: dict.postImage!)
cell.ticketImageView.tintColor = colorList[indexPath.row]
cell.ticket_ValidDate.text = self.changeDateForamte(dateString: dict.validTill!, currentDateFormate: "yyyy-MM-dd", newDateFormate: "dd MMMM yyyy")
// cell.ticketImageView.tintColor = .random()
cell.goToDealBtn.tag = indexPath.row
cell.goToDealBtn.addTarget(self, action: #selector(self.openDeals), for: .touchUpInside)
return cell
}else {
let cell = tableView.dequeueReusableCell(withIdentifier: "Home1Cell", for: indexPath) as! Home1Cell
let dict = couponsData[indexPath.row]
if let postTitle = dict.postTitle, postTitle.count != 0 {
cell.ticket_postTitle.text = postTitle
}
if let postContent = dict.postContent, postContent.count != 0 {
cell.ticket_postContent.text = postContent
}
if let storeName = dict.stores, storeName.count != 0 {
cell.storename.text = storeName
}
cell.ticketImageView.tintColor = colorList[indexPath.row]
cell.ticket_ValidDate.text = self.changeDateForamte(dateString: dict.validTill!, currentDateFormate: "yyyy-MM-dd", newDateFormate: "dd MMMM yyyy")
// cell.ticketImageView.tintColor = .random()
cell.goToDealBtn.tag = indexPath.row
cell.goToDealBtn.addTarget(self, action: #selector(self.openDeals), for: .touchUpInside)
return cell
}
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if !couponsData[indexPath.row].postImage!.isEmpty {
return 339.0
}else {
return 234.0
}
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if !couponsData[indexPath.row].postImage!.isEmpty {
return 339.0
}else {
return 234.0
}
}
}

show data into tableview from api when category cell and store cell is selected or only one from previous controller in swift

I am creating an app in which i have a controller in which i have a tableview which will show data from previous screen when cell from c ategory section or cell from store section are selected or only one is selected then when i click the double arrow button shown in app then it should navigate to tableview screen and should show all the data from category or store or both into tableview. in tableview controller i have an API which is POST and has a body parameter of 'term_ids' which contains value as 556,574 which is comma seperated means the former one is for category and latter one is for store or both ids contains category data or store data. Means i have to pass two ids and make them comma seperated and then pass to tableview controller
lets say in category screenshot i have selected first two cells and when i tap on double arrow button the selected cell data should pass to another screen whose screenshot is as below:
api link for category data: https://api.myjson.com/bins/wggld
api link for store data: https://api.myjson.com/bins/1fc46p
api link for coupons which i need to populate into tableview based on ID from category and store api link: https://api.myjson.com/bins/1c4dip
my app screenshot for better understanding:
code for my category screen and main home view screen where i want to populate data is as below:
code for categoryViewController is as below:
class CategoryViewController: UIViewController {
//MARK: IBOutlets
#IBOutlet weak var store_bar: UIViewX!
#IBOutlet weak var store_title: UIButton!
#IBOutlet weak var category_title: UIButton!
#IBOutlet weak var category_bar: UIViewX!
#IBOutlet weak var categoryColView: UICollectionView!
var selectedBtnIndex:Int = 1
var selectedIndexPaths = [Int]()
var tempStoreIndexPaths = [Int]()
var categoryData = [ModelCategories]()
var storeData = [ModelStore]()
var arrCategoryImages = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
// register collectionview cell
self.categoryColView.register(UINib(nibName: "CategoryCell1", bundle: nil), forCellWithReuseIdentifier: "CategoryCell1")
self.categoryColView.register(UINib(nibName: "StoresCell", bundle: nil), forCellWithReuseIdentifier: "StoresCell")
self.store_bar.isHidden = true
self.getCategoriesList()
self.getStoreList()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
#objc func click_Category(sender: UIButton!) {
if sender.isSelected == true {
selectedIndexPaths.append(sender.tag)
sender.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
sender.isSelected = false
}else {
selectedIndexPaths = selectedIndexPaths.filter{ $0 != sender.tag }
sender.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
sender.isSelected = true
}
}
#objc func click_store(sender: UIButton!) {
if sender.isSelected == true {
tempStoreIndexPaths.append(sender.tag)
sender.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
sender.isSelected = false
}else {
tempStoreIndexPaths = tempStoreIndexPaths.filter{ $0 != sender.tag }
sender.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
sender.isSelected = true
}
}
//MARK: IBActions
#IBAction func categoriesData(_ sender: UIButton) {
selectedBtnIndex = 1
self.categoryColView.isHidden = false
self.store_bar.isHidden = true
self.category_title.setTitleColor(UIColor.black, for: .normal)
self.category_bar.isHidden = false
self.store_title.setTitleColor(UIColor(rgb: 0xAAAAAA), for: .normal)
self.categoryColView.reloadData()
}
#IBAction func storeData(_ sender: UIButton) {
selectedBtnIndex = 2
self.categoryColView.isHidden = false
self.store_bar.isHidden = false
self.store_title.setTitleColor(UIColor.black, for: .normal)
self.category_bar.isHidden = true
self.category_title.setTitleColor(UIColor(rgb: 0xAAAAAA), for: .normal)
self.categoryColView.reloadData()
}
#IBAction func showHomeScreen(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
if selectedBtnIndex == 1 {
vc.couponId = categoryData[sender.tag].ID!
}else {
vc.couponId = storeData[sender.tag].ID!
}
self.navigationController?.pushViewController(vc, animated:true)
}
#IBAction func toSearchPage(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SearchPageController") as! SearchPageController
self.navigationController?.pushViewController(vc, animated:true)
}
func getCategoriesList() {
if ApiUtillity.sharedInstance.isReachable() {
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseCategoryList>().API_GET(Url: SD_GET_CategoriesList, Params: [:], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
self.categoryData.removeAll()
let resul_array_tmp_new = modelResponse.categories! as NSArray
if resul_array_tmp_new.count > 0 {
for i in modelResponse.categories! {
if i.count != 0 {
if let image = UIImage(named: "\(i.slug!.uppercased())") {
self.arrCategoryImages.append(image)
self.categoryData.append(i)
}else {
self.arrCategoryImages.append(UIImage(named: "tickets")!)
self.categoryData.append(i)
}
}
}
}
}
else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.categoryColView.reloadData()
}) { (failed) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.view.makeToast(failed.localizedDescription)
}
}
else
{
self.view.makeToast("No Internet Connection..")
}
}
func getStoreList() {
if ApiUtillity.sharedInstance.isReachable() {
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseStoreList>().API_GET(Url: SD_GET_StoreList, Params: [:], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
self.storeData.removeAll()
let resul_array_tmp_new = modelResponse.store! as NSArray
if resul_array_tmp_new.count > 0 {
for i in modelResponse.store! {
if i.count != 0 {
self.storeData.append(i)
}
}
}
}
else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.categoryColView.reloadData()
}) { (failed) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.view.makeToast(failed.localizedDescription)
}
}
else
{
self.view.makeToast("No Internet Connection..")
}
}
}
//MARK: Delegate and Data Source Methods
extension CategoryViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if selectedBtnIndex == 1{
return categoryData.count
}else {
return storeData.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if selectedBtnIndex == 1{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell1", for: indexPath) as! CategoryCell1
let dict = categoryData[indexPath.row]
if let catName = dict.name, catName.count != 0 {
cell.categoryName.text = catName
}
if let catOffersCount = dict.count {
if catOffersCount == 1 {
cell.catOfferCount.text = "\(catOffersCount)"+" "+"Offer"
}else {
cell.catOfferCount.text = "\(catOffersCount)"+" "+"Offers"
}
}
cell.categoryImage.image = arrCategoryImages[indexPath.row]
cell.btn_click.tag = indexPath.row
cell.btn_click.addTarget(self, action: #selector(self.click_Category), for: .touchUpInside)
if selectedIndexPaths.contains(indexPath.row) {
cell.btn_click.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
cell.btn_click.isSelected = true
}else {
cell.btn_click.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
cell.btn_click.isSelected = false
}
return cell
}else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoresCell", for: indexPath) as! StoresCell
let dict = storeData[indexPath.row]
if let storeName = dict.name, storeName.count != 0 {
cell.storeName.text = storeName
}
if let storeOfferCount = dict.count {
cell.storeOfferCount.text = "\(storeOfferCount)"+" "+"Offers"
}
cell.store_btn_click.tag = indexPath.row
cell.store_btn_click.addTarget(self, action: #selector(self.click_store), for: .touchUpInside)
if tempStoreIndexPaths.contains(indexPath.row) {
cell.store_btn_click.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
cell.store_btn_click.isSelected = true
}else {
cell.store_btn_click.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
cell.store_btn_click.isSelected = false
}
return cell
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if selectedBtnIndex == 1{
return CGSize(width: (UIScreen.main.bounds.width) / 3, height: 93)
}else {
return CGSize(width: (UIScreen.main.bounds.width) / 2, height: 48)
}
}
code for homeView COntroller is as below:
import UIKit
class HomeViewController: UIViewController {
var couponsData = [ModelCoupons]()
var couponId = Int()
#IBOutlet weak var homeTblView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.homeTblView.register(UINib(nibName: "HomeCell", bundle: nil), forCellReuseIdentifier: "HomeCell")
self.post_CouponsData()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
//MARK: IBActions
#IBAction func toCategoryScreen(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func toSearchPage(_ sender: UIButtonX) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SearchPageController") as! SearchPageController
self.navigationController?.pushViewController(vc, animated: true)
}
func post_CouponsData() {
if ApiUtillity.sharedInstance.isReachable() {
var params = [String : String]()
params ["term_ids"] = "\(self.couponId)"
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseCouponsList>().API_POST(Url: SD_POST_CouponsList, Params: params as [String:AnyObject], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
ApiUtillity.sharedInstance.StopProgress(view: self.view)
let dict = modelResponse.coupons
for i in dict! {
self.couponsData.append(i)
}
}else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.homeTblView.reloadData()
}) { (failed) in
self.view.makeToast(failed.localizedDescription)
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}else {
self.view.makeToast("No internet connection...")
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return couponsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeCell
let dict = couponsData[indexPath.row]
if let postTitle = dict.postTitle, postTitle.count != 0 {
cell.ticket_postTitle.text = postTitle
}
if let postContent = dict.postContent, postContent.count != 0 {
cell.ticket_postContent.text = postContent
}
if let storeName = dict.stores, storeName.count != 0 {
cell.storename.text = storeName
}
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd"
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "dd MMMM yyyy"
let datee = ApiUtillity.sharedInstance.ConvertStingTodate(forApp: dict.validTill!)
cell.ticket_ValidDate.text = dateFormatterPrint.string(from: datee)
cell.ticketImageView.tintColor = .random()
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 339.0
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 339.0
}
}

how to convert int array into comma seperated in swift [duplicate]

This question already has an answer here:
Convert an array of Ints to a comma separated string [duplicate]
(1 answer)
Closed 3 years ago.
in my app i have taken an object, lets say var selectedIds = Int. i want this selectedIds to be comma seperated. because i need to send selectedids to next screen in which api calling has parameters which is comma seperated. i should get ids like 556,573 so that i can pass into parameters of receiving controller
the viewcontroller file from which i want to send selectedIds array:
class CategoryViewController: UIViewController {
//MARK: IBOutlets
#IBOutlet weak var store_bar: UIViewX!
#IBOutlet weak var store_title: UIButton!
#IBOutlet weak var category_title: UIButton!
#IBOutlet weak var category_bar: UIViewX!
#IBOutlet weak var categoryColView: UICollectionView!
var selectedBtnIndex:Int = 1
var selectedIds = [Int]()
var storeIds = [Int]()
var categoryData = [ModelCategories]()
var storeData = [ModelStore]()
var arrCategoryImages = [UIImage]()
override func viewDidLoad() {
super.viewDidLoad()
// register collectionview cell
self.categoryColView.register(UINib(nibName: "CategoryCell1", bundle: nil), forCellWithReuseIdentifier: "CategoryCell1")
self.categoryColView.register(UINib(nibName: "StoresCell", bundle: nil), forCellWithReuseIdentifier: "StoresCell")
self.store_bar.isHidden = true
self.getCategoriesList()
self.getStoreList()
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
#objc func click_Category(sender: UIButton!) {
if sender.isSelected == true {
selectedIds.append(categoryData[sender.tag].ID!)
sender.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
sender.isSelected = false
}else {
selectedIds = selectedIds.filter{ $0 != sender.tag }
sender.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
sender.isSelected = true
}
}
#objc func click_store(sender: UIButton!) {
if sender.isSelected == true {
selectedIds.append(storeData[sender.tag].ID!)
sender.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
sender.isSelected = false
}else {
selectedIds = selectedIds.filter{ $0 != sender.tag }
sender.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
sender.isSelected = true
}
}
//MARK: IBActions
#IBAction func categoriesData(_ sender: UIButton) {
selectedBtnIndex = 1
self.categoryColView.isHidden = false
self.store_bar.isHidden = true
self.category_title.setTitleColor(UIColor.black, for: .normal)
self.category_bar.isHidden = false
self.store_title.setTitleColor(UIColor(rgb: 0xAAAAAA), for: .normal)
self.categoryColView.reloadData()
}
#IBAction func storeData(_ sender: UIButton) {
selectedBtnIndex = 2
self.categoryColView.isHidden = false
self.store_bar.isHidden = false
self.store_title.setTitleColor(UIColor.black, for: .normal)
self.category_bar.isHidden = true
self.category_title.setTitleColor(UIColor(rgb: 0xAAAAAA), for: .normal)
self.categoryColView.reloadData()
}
#IBAction func showHomeScreen(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "HomeViewController") as! HomeViewController
if selectedBtnIndex == 1 {
vc.selectedIds = self.selectedIds
// vc.couponId = categoryData[sender.tag].ID!
}else {
vc.selectedIds = self.selectedIds
}
self.navigationController?.pushViewController(vc, animated:true)
}
#IBAction func toSearchPage(_ sender: UIButton) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SearchPageController") as! SearchPageController
self.navigationController?.pushViewController(vc, animated:true)
}
func getCategoriesList() {
if ApiUtillity.sharedInstance.isReachable() {
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseCategoryList>().API_GET(Url: SD_GET_CategoriesList, Params: [:], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
self.categoryData.removeAll()
let resul_array_tmp_new = modelResponse.categories! as NSArray
if resul_array_tmp_new.count > 0 {
for i in modelResponse.categories! {
if i.count != 0 {
if let image = UIImage(named: "\(i.slug!.uppercased())") {
self.arrCategoryImages.append(image)
self.categoryData.append(i)
}else {
self.arrCategoryImages.append(UIImage(named: "tickets")!)
self.categoryData.append(i)
}
}
}
}
}
else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.categoryColView.reloadData()
}) { (failed) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.view.makeToast(failed.localizedDescription)
}
}
else
{
self.view.makeToast("No Internet Connection..")
}
}
func getStoreList() {
if ApiUtillity.sharedInstance.isReachable() {
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseStoreList>().API_GET(Url: SD_GET_StoreList, Params: [:], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
self.storeData.removeAll()
let resul_array_tmp_new = modelResponse.store! as NSArray
if resul_array_tmp_new.count > 0 {
for i in modelResponse.store! {
if i.count != 0 {
self.storeData.append(i)
}
}
}
}
else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.categoryColView.reloadData()
}) { (failed) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.view.makeToast(failed.localizedDescription)
}
}
else
{
self.view.makeToast("No Internet Connection..")
}
}
}
//MARK: Delegate and Data Source Methods
extension CategoryViewController: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if selectedBtnIndex == 1{
return categoryData.count
}else {
return storeData.count
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if selectedBtnIndex == 1{
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CategoryCell1", for: indexPath) as! CategoryCell1
let dict = categoryData[indexPath.row]
if let catName = dict.name, catName.count != 0 {
cell.categoryName.text = catName
}
if let catOffersCount = dict.count {
if catOffersCount == 1 {
cell.catOfferCount.text = "\(catOffersCount)"+" "+"Offer"
}else {
cell.catOfferCount.text = "\(catOffersCount)"+" "+"Offers"
}
}
cell.categoryImage.image = arrCategoryImages[indexPath.row]
cell.btn_click.tag = indexPath.row
cell.btn_click.addTarget(self, action: #selector(self.click_Category), for: .touchUpInside)
if selectedIds.contains(categoryData[indexPath.row].ID!) {
cell.btn_click.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
cell.btn_click.isSelected = true
}else {
cell.btn_click.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
cell.btn_click.isSelected = false
}
return cell
}else {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "StoresCell", for: indexPath) as! StoresCell
let dict = storeData[indexPath.row]
if let storeName = dict.name, storeName.count != 0 {
cell.storeName.text = storeName
}
if let storeOfferCount = dict.count {
cell.storeOfferCount.text = "\(storeOfferCount)"+" "+"Offers"
}
cell.store_btn_click.tag = indexPath.row
cell.store_btn_click.addTarget(self, action: #selector(self.click_store), for: .touchUpInside)
if selectedIds.contains(storeData[indexPath.row].ID!) {
cell.store_btn_click.setImage(#imageLiteral(resourceName: "image_checked"), for: .normal)
cell.store_btn_click.isSelected = true
}else {
cell.store_btn_click.setImage(#imageLiteral(resourceName: "image_unchecked"), for: .normal)
cell.store_btn_click.isSelected = false
}
return cell
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
if selectedBtnIndex == 1{
return CGSize(width: (UIScreen.main.bounds.width) / 3, height: 93)
}else {
return CGSize(width: (UIScreen.main.bounds.width) / 2, height: 48)
}
}
The viewcontroller file in which i want selectedIds array:
class HomeViewController: UIViewController {
var couponsData = [ModelCoupons]()
var couponId = Int()
var selectedIds = [Int]()
#IBOutlet weak var homeTblView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
self.homeTblView.register(UINib(nibName: "HomeCell", bundle: nil), forCellReuseIdentifier: "HomeCell")
self.post_CouponsData()
print(selectedIds)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
//MARK: IBActions
#IBAction func toCategoryScreen(_ sender: UIButton) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func toSearchPage(_ sender: UIButtonX) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SearchPageController") as! SearchPageController
self.navigationController?.pushViewController(vc, animated: true)
}
func post_CouponsData() {
if ApiUtillity.sharedInstance.isReachable() {
var params = [String : String]()
params ["term_ids"] = "\(self.selectedIds)"
ApiUtillity.sharedInstance.StartProgress(view: self.view)
APIClient<ModelBaseCouponsList>().API_POST(Url: SD_POST_CouponsList, Params: params as [String:AnyObject], Authentication: true, Progress: true, Alert: true, Offline: false, SuperVC: self, completionSuccess: { (modelResponse) in
ApiUtillity.sharedInstance.StopProgress(view: self.view)
if(modelResponse.success == true) {
ApiUtillity.sharedInstance.StopProgress(view: self.view)
let dict = modelResponse.coupons
for i in dict! {
self.couponsData.append(i)
}
}else {
self.view.makeToast(modelResponse.message)
}
ApiUtillity.sharedInstance.StopProgress(view: self.view)
self.homeTblView.reloadData()
}) { (failed) in
self.view.makeToast(failed.localizedDescription)
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}else {
self.view.makeToast("No internet connection...")
ApiUtillity.sharedInstance.StopProgress(view: self.view)
}
}
}
extension HomeViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return couponsData.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "HomeCell", for: indexPath) as! HomeCell
let dict = couponsData[indexPath.row]
if let postTitle = dict.postTitle, postTitle.count != 0 {
cell.ticket_postTitle.text = postTitle
}
if let postContent = dict.postContent, postContent.count != 0 {
cell.ticket_postContent.text = postContent
}
if let storeName = dict.stores, storeName.count != 0 {
cell.storename.text = storeName
}
let dateFormatterGet = DateFormatter()
dateFormatterGet.dateFormat = "yyyy-MM-dd"
let dateFormatterPrint = DateFormatter()
dateFormatterPrint.dateFormat = "dd MMMM yyyy"
let datee = ApiUtillity.sharedInstance.ConvertStingTodate(forApp: dict.validTill!)
cell.ticket_ValidDate.text = dateFormatterPrint.string(from: datee)
cell.ticketImageView.tintColor = .random()
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 339.0
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return 339.0
}
}
You can convert an array of Ints to an array of strings using
selectedIds.map(String.init)
and then convert that array of strings into a single string like this
selectedIds.map(String.init).joined(separator: ",")
You have to map the Int array to String array and then join the array with separator comma to get a comma separated string.
params["term_ids"] = self.selectedIds.map(String.init).joined(separator: ",")

Autolayout Contraints Changing When View Is Reloaded - Swift

recently in the search VC of my app I have been having a major problem with the contraints for weeks. I've redone them 4 times now with no improvement. My tableview cell is not complex -- an imageView located at the left and two labels on top of each other. Most cells size fine. The only thing is that(without pattern) two cells are randomly messed up(the labels and imageView move way out of place). You can see here:
Here is a picture of the constraints for the vc:
The strange thing is that this sometimes occurs when I toggle the scopeButtons up top. I looked in my code to see if I could fix this when the scopeButton reloads the tableview, but I could not find a problematic instance. My code is below:
import UIKit
import Firebase
import Kingfisher
class SearchPostsController: UIViewController, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var searchBar: UISearchBar!
#IBOutlet weak var tableView: UITableView!
var idArray:[String] = []
var detailViewController: DetailViewController? = nil
var candies = [Person]()
var filteredCandies = [Person]()
let searchController = UISearchController(searchResultsController: nil)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if #available(iOS 11.0, *) {
navigationItem.hidesSearchBarWhenScrolling = false
//initiate the search bar that appears up top when view is segued to
}
if let selectionIndexPath = self.tableView.indexPathForSelectedRow {
self.tableView.deselectRow(at: selectionIndexPath, animated: animated)
}
self.tableView.reloadData()
super.viewWillAppear(animated)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if #available(iOS 11.0, *) {
navigationItem.hidesSearchBarWhenScrolling = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
Database.database().reference()
.child("\(UserData().mySchool!)/posts")
.queryOrderedByKey()//keys were out of order, so we have to use this to help
.observeSingleEvent(of: .value, with: { (snapshot) in
print(snapshot.childrenCount)
for child in snapshot.children.allObjects as! [DataSnapshot] {
print(child.key)
self.idArray.append(child.key)
}
var reversedNames = [String]()
for arrayIndex in 0..<self.idArray.count {
reversedNames.append(self.idArray[(self.idArray.count - 1) - arrayIndex])
//reverse names so we dont have to sort the cells by date
}
for x in reversedNames{
self.searchNames(id: x)//get names from the ids here, tada!!!
self.tableView.reloadData()
}
})
//self.tableView.reloadData()//without this, the results wouldnt show up right away
searchController.searchBar.setScopeBarButtonTitleTextAttributes([NSAttributedStringKey.foregroundColor.rawValue: UIColor.white], for: .normal)
searchController.searchBar.scopeButtonTitles = ["Posts", "Users"]
searchController.searchBar.delegate = self
searchController.searchResultsUpdater = self
searchController.obscuresBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search posts or usernames"
searchController.searchBar.showsScopeBar = true
navigationItem.searchController = searchController
definesPresentationContext = true
if let splitViewController = splitViewController {
let controllers = splitViewController.viewControllers
detailViewController = (controllers[controllers.count-1] as! UINavigationController).topViewController as? DetailViewController
}
tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 74
}
// override func viewWillDisappear(_ animated: Bool) {
// candies.removeAll()
// }
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "DAY69:GRADUATION DAY", for: indexPath) as! SeachCell
cell.cellImageVIew.frame.size.width = 48
cell.cellImageVIew.frame.size.height = 48
let personUser: Person
if isFiltering() {
personUser = filteredCandies[indexPath.row]
} else {
personUser = candies[indexPath.row]
}
//PERSON USER IS IMPORTANT!!!!! ^^^
cell.nameLabel.text = personUser.name.removingPercentEncoding
cell.messageLabel.text = personUser.category.removingPercentEncoding
let name = personUser.name
Database.database().reference().child("users/\(name)/profileImageURL").observe(.value, with: { (snapshot) in
let profURL = "\(snapshot.value!)"
let profIRL = URL(string: profURL)
//set up imageview
cell.cellImageVIew.layer.borderWidth = 1
cell.cellImageVIew.layer.masksToBounds = false
cell.cellImageVIew.layer.borderColor = UIColor.black.cgColor
cell.cellImageVIew.layer.cornerRadius = cell.cellImageVIew.frame.height/2
cell.cellImageVIew.clipsToBounds = true
cell.cellImageVIew.contentMode = .scaleAspectFill
cell.cellImageVIew.kf.indicatorType = .activity
cell.cellImageVIew.kf.setImage(with: profIRL)
})
//TODO: make an extension of imageview to do all this for me. It's getting to be ridiculous
return cell
}
func searchNames(id: String){
// var message = String()
// var name = String()
Database.database().reference().child("\(UserData().mySchool!)/posts/\(id)/message").observe(.value, with: { (snapshot) in
// message = snapshot.value as! String
Database.database().reference().child("\(UserData().mySchool!)/posts").child("\(id)/username").observe(.value, with: { (username) in
// name = username.value as! String
let user = Person(category: "\(snapshot.value!)", name: "\(username.value!)", id: id)
self.candies.append(user)
print( "\(snapshot.value!)", "\(username.value!)")
self.tableView.reloadData()
})
})
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
return filteredCandies.count
}
return candies.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
tableView.estimatedRowHeight = 74.0
tableView.rowHeight = UITableViewAutomaticDimension
return UITableViewAutomaticDimension
}
// func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
// return 74
// }
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.dequeueReusableCell(withIdentifier: "DAY69:GRADUATION DAY", for: indexPath) as! SeachCell
cell.cellImageVIew.frame.size.width = 48
cell.cellImageVIew.frame.size.height = 48
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles?[searchBar.selectedScopeButtonIndex]
if scope == "Users"{
let username = candies[indexPath.row].name
print(username)
self.tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "userClicked", sender: username)
}
if scope == "Posts"{
let post = candies[indexPath.row].category
let user = candies[indexPath.row].name
let id = candies[indexPath.row].id
print(post)
let defaults = UserDefaults.standard
defaults.set(id, forKey: "ID")
let def2 = UserDefaults.standard
def2.set(post, forKey: "Post")
def2.set(user, forKey: "USER")
self.tableView.deselectRow(at: indexPath, animated: true)
performSegue(withIdentifier: "postCellTapped", sender: nil)
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
//__________tbv methods above________________________________________________
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String, scope: String = "All") {
filteredCandies = candies.filter({(candy : Person) -> Bool in
let doesCategoryMatch = (scope == "Posts") || (scope == "Users")
print(searchText)
if searchBarIsEmpty() {
return doesCategoryMatch
}
if scope == "Users"{
return doesCategoryMatch && candy.name.lowercased().contains(searchText.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!.lowercased())
}
else{
return doesCategoryMatch && candy.category.lowercased().contains(searchText.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!.lowercased())
}
})
tableView.reloadData()
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let personalUser: Person
if isFiltering() {
personalUser = filteredCandies[indexPath.row]
} else {
personalUser = candies[indexPath.row]
}
}
}
if segue.identifier == "userClicked" {
if let nextView = segue.destination as? UserProfileController {
nextView.selectedUser = "\(sender!)"
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func isFiltering() -> Bool {
let searchBarScopeIsFiltering = searchController.searchBar.selectedScopeButtonIndex != 0
return searchController.isActive && (!searchBarIsEmpty() || searchBarScopeIsFiltering)
}
}
extension SearchPostsController: UISearchResultsUpdating {
// MARK: - UISearchResultsUpdating Delegate
func updateSearchResults(for searchController: UISearchController) {
let searchBar = searchController.searchBar
let scope = searchBar.scopeButtonTitles![searchBar.selectedScopeButtonIndex]
filterContentForSearchText(searchController.searchBar.text!, scope: scope)
}
}
extension SearchPostsController: UISearchBarDelegate {
// MARK: - UISearchBar Delegate
func searchBar(_ searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
filterContentForSearchText(searchBar.text!, scope: searchBar.scopeButtonTitles![selectedScope])
}
}
Any help would be greatly appreciated in trying to fix the constraints! Thanks!