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: ",")
Related
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
}
}
}
I have this UITableView that has xib files as cells and it all works as intended, however the last cell only when I scroll down doesn't have a background color. It only happens when I scroll down and then it pops back to normal position. I'm essentially wondering how I can change the color of that cell just to my background color. Thank you.
//
// BlogViewController.swift
// testAPI
//
// Created by Dilan Piscatello on 4/2/20.
// Copyright © 2020 Dilan Piscatello. All rights reserved.
//
import Foundation
import UIKit
import Firebase
class BlogViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
var x = 0
func numberOfSections(in tableView: UITableView) -> Int {
return 2
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0{
return 1
}else{
return posts.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if indexPath.section == 0{
let cell = Bundle.main.loadNibNamed("QuestionTableViewCell", owner: self, options: nil)?.first as! QuestionTableViewCell
print("this is how many times it ran")
cell.setPost(question: self.question)
return cell
}
else{
let cell = tableView.dequeueReusableCell(withIdentifier: "postcell", for: indexPath) as! PostTableViewCell
cell.setPost(post: posts[indexPath.row])
return cell
}
}
var question = "sdfsdfs"
var tableView:UITableView!
var lastUploadPostID:String?
var discussion:UILabel! = UILabel()
var posts = [Post]()
var fetchingMore = false
var endReached = false
let leadingScreensForBatching:CGFloat = 3.0
var cellHeights: [IndexPath:CGFloat] = [:]
var refreshControl:UIRefreshControl!
var postRef:DatabaseReference{
return Database.database().reference().child("posts")
}
var oldPostQuery:DatabaseQuery{
var queryRef:DatabaseQuery
let lastPost = self.posts.last
if lastPost == nil{
queryRef = postRef.queryOrdered(byChild: "timestamp")
}else{
let lastTimestamp = lastPost!.createdAt.timeIntervalSince1970*1000
queryRef = postRef.queryOrdered(byChild: "timestamp").queryEnding(atValue: lastTimestamp)
}
return queryRef
}
var newPostQuery:DatabaseQuery{
var queryRef:DatabaseQuery
let firstPost = self.posts.first
if firstPost == nil{
queryRef = postRef.queryOrdered(byChild: "timestamp")
}else{
let firstTimestamp = firstPost!.createdAt.timeIntervalSince1970*1000
queryRef = postRef.queryOrdered(byChild: "timestamp").queryStarting(atValue: firstTimestamp)
}
return queryRef
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func hi(){
let db = Firestore.firestore()
db.collection("blog").document("question").getDocument { (document,error) in
if error != nil{
print("cant get data")
}
if document != nil && document!.exists{
if let documentdata = document?.data() {
self.question = documentdata["question"] as! String
self.tableView.reloadData()
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
discussion.text = "Discussion"
//longTitleLabel.font = ................
discussion.font = UIFont(name: "HelveticaNeue-Bold", size: 31)
discussion.translatesAutoresizingMaskIntoConstraints = false
if let navigationBar = self.navigationController?.navigationBar {
navigationBar.addSubview(discussion)
//navigationBar.shadowImage = UIImage()
// navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
// navigationBar.isTranslucent = true
navigationBar.barTintColor = UIColor( red: 128/255, green: 117/255, blue: 255/255, alpha: 1)
discussion.leftAnchor.constraint(equalTo: navigationBar.leftAnchor, constant: 22).isActive = true
discussion.widthAnchor.constraint(equalToConstant: 300).isActive = true
tableView = UITableView()
tableView.translatesAutoresizingMaskIntoConstraints = false
self.tableView.separatorStyle = .none
view.addSubview(tableView)
hi()
print(question)
// Do any additional setup after loading the view.
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postcell")
var layoutGuide:UILayoutGuide!
layoutGuide = view.safeAreaLayoutGuide
tableView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 10).isActive = true
tableView.topAnchor.constraint(equalTo: view.topAnchor, constant: 40).isActive = true
tableView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -10).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.reloadData()
refreshControl = UIRefreshControl()
tableView.refreshControl = refreshControl
refreshControl.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
beginBatchFetch()
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// if let navigationController = navigationController as? ScrollingNavigationController {
// navigationController.followScrollView(tableView, delay: 0.0)
//}
listenForNewPosts()
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
stopListeningForNewPosts()
}
#objc func handleRefresh(){
print()
newPostQuery.queryLimited(toFirst: 20).observeSingleEvent(of: .value, with: { (snapshot) in
var tempPosts = [Post]()
let firstPost = self.posts.first
for child in snapshot.children{
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let post = Post.parse(childSnapshot.key, dict),
childSnapshot.key != firstPost?.id{
tempPosts.insert(post, at: 0)
}
}
self.posts.insert(contentsOf: tempPosts, at: 0)
self.tableView.reloadData()
self.refreshControl.endRefreshing()
//let newIndexPaths = (1..<tempPosts.count).map { i in
// return IndexPath(row: i, section: 1)
//}
//self.tableView.insertRows(at: newIndexPaths, with: .top)
// self.refreshControl.endRefreshing()
// self.tableView.scrollToRow(at: IndexPath(row:0,section: 0), at: .top, //animated:true)
//self.listenForNewPosts()
//return completion(tempPosts)
//self.posts = tempPosts
//self.tableView.reloadData()
})
}
func fetchPosts(completion: #escaping(_ posts:[Post])->()){
oldPostQuery.queryLimited(toLast: 20).observeSingleEvent(of: .value, with: { (snapshot) in
var tempPosts = [Post]()
let lastPost = self.posts.last
for child in snapshot.children{
if let childSnapshot = child as? DataSnapshot,
let dict = childSnapshot.value as? [String:Any],
let post = Post.parse(childSnapshot.key, dict),
childSnapshot.key != lastPost?.id{
tempPosts.insert(post, at: 0)
}
}
return completion(tempPosts)
//self.posts = tempPosts
//Zself.tableView.reloadData()
})
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
cell.selectionStyle = UITableViewCell.SelectionStyle.none
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeights[indexPath] ?? 72.0
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.size.height * leadingScreensForBatching {
if !fetchingMore && !endReached {
beginBatchFetch()
}
}
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
func beginBatchFetch(){
fetchingMore = true
fetchPosts{ newPosts in
self.posts.append(contentsOf: newPosts)
self.endReached = newPosts.count == 0
self.fetchingMore = false
UIView.performWithoutAnimation {
self.tableView.reloadData()
self.listenForNewPosts()
}
}
//fetch the post
}
var postListenerHandle:UInt?
func listenForNewPosts(){
guard !fetchingMore else{ return}
//to avoid the listeners twice (duplicate)
stopListeningForNewPosts()
postListenerHandle = newPostQuery.observe(.childAdded) { (snapshot) in
if snapshot.key != self.posts.first?.id {
if let data = snapshot.value as? [String:Any],
//let post = Post.parse(snapshot.key,data)
let _ = Post.parse(snapshot.key,data){
self.stopListeningForNewPosts()
if snapshot.key == self.lastUploadPostID{
self.handleRefresh()
self.lastUploadPostID = nil
}else{
}
}
}
}
}
func stopListeningForNewPosts(){
if let handle = postListenerHandle{
newPostQuery.removeObserver(withHandle: handle)
postListenerHandle = nil
}
}
// func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
//if let navigationController = navigationController as? //ScrollingNavigationController {
// navigationController.showNavbar(animated: true, scrollToTop: true)
//}
// return true
//}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let newPostNavBar = segue.destination as? UINavigationController,
let newPostVC = newPostNavBar.viewControllers[0] as? WritePostViewController{
newPostVC.delegate = self
}
}
}
extension BlogViewController: NewPostVCDelegate{
func didUploadPost(withID id: String) {
print("what up this is the id \(id)")
self.lastUploadPostID = id
}
}
In the storyboard add inside the tableView as last element a transparent view with height equal to 1
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
}
}
}
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
}
}
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!