API to table view, Add columns and refresh - swift

Attaching the code here.
This is the API: " https://bittrex.com/api/v1.1/public/getmarketsummaries "
I am wanting to add the "High" and "Low" in columns beside "MarketName"
Also, I want to refresh this every 10 seconds.
The refresh part, I am getting error, for sendUpdateRequest().
The full code is:
import UIKit
var listData = [[String : AnyObject]]()
class DemoJsonTableViewController: UITableViewController {
var listData = [[String : AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
var timer : Timer? = nil
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: (#selector(self.sendUpdateRequest)), userInfo: nil, repeats: true)
func sendUpdateRequest(){
let url:String = "https://bittrex.com/api/v1.1/public/getmarketsummaries"
let urlRequest = URL(string: url)
URLSession.shared.dataTask(with: urlRequest!) { (data, response, error) in
if(error != nil){
print(error.debugDescription)
}
else{
do{
var response = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
self.listData = response["result"] as! [[String:AnyObject]]
DispatchQueue.main.async {
self.tableView.reloadData()
}
}catch let error as NSError{
print(error)
}
}
}.resume()
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
let item = self.listData[indexPath.row]
cell.textLabel?.text = item["MarketName"] as? String
let lastValue = item["Last"] as? NSNumber
cell.detailTextLabel?.text = lastValue?.stringValue
print(self.listData.count)
return cell
}

This is what you need. Copy paste the entire code.
import UIKit
class DemoJsonTableViewController: UITableViewController {
var listData = [[String : AnyObject]]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(DrawerCell.self, forCellReuseIdentifier: "Cell")
self.sendUpdateRequest()
Timer.scheduledTimer(timeInterval: 10, target: self, selector: (#selector(self.sendUpdateRequest)), userInfo: nil, repeats: true)
}
func sendUpdateRequest(){
let url:String = "https://bittrex.com/api/v1.1/public/getmarketsummaries"
let urlRequest = URL(string: url)
URLSession.shared.dataTask(with: urlRequest!) { (data, response, error) in
if(error != nil){
print(error.debugDescription)
}
else{
do{
var response = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
self.listData = response["result"] as! [[String:AnyObject]]
DispatchQueue.main.async {
self.tableView.reloadData()
}
}catch let error as NSError{
print(error)
}
}
}.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.listData.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! DrawerCell
let item = self.listData[indexPath.row]
cell.TitleLabel.text = item["MarketName"] as? String
cell.Description.text = String(describing: item["Last"] as? NSNumber)
cell.HighLabel.text = String(describing: item["High"] as! NSNumber)
cell.LowLabel.text = String(describing: item["Low"] as! NSNumber)
return cell
}
}
class DrawerCell: UITableViewCell {
var TitleLabel: UILabel = UILabel()
var Description: UILabel = UILabel()
var HighLabel: UILabel = UILabel()
var LowLabel: UILabel = UILabel()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
TitleLabel.textColor = UIColor.black
TitleLabel.font = UIFont.init(name: "AppleSDGothicNeo-Bold", size: 10)
TitleLabel.textAlignment = .left
contentView.addSubview(TitleLabel)
Description.textColor = UIColor.black
Description.font = UIFont.init(name: "AppleSDGothicNeo-Bold", size: 8)
Description.textAlignment = .left
contentView.addSubview(Description)
HighLabel.textColor = UIColor.black
HighLabel.font = UIFont.init(name: "AppleSDGothicNeo-Bold", size: 10)
HighLabel.textAlignment = .center
contentView.addSubview(HighLabel)
LowLabel.textColor = UIColor.black
LowLabel.font = UIFont.init(name: "AppleSDGothicNeo-Bold", size: 10)
LowLabel.textAlignment = .center
contentView.addSubview(LowLabel)
}
override func layoutSubviews() {
super.layoutSubviews()
TitleLabel.frame = CGRect(x: 10, y: 0, width: self.frame.size.width - 110, height: 20)
Description.frame = CGRect(x: 10, y: 20, width: self.frame.size.width - 110, height: 20)
HighLabel.frame = CGRect(x: self.frame.size.width - 110, y: 0, width: 100, height: 20)
LowLabel.frame = CGRect(x: self.frame.size.width - 110, y: 20, width: 100, height: 20)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override public func prepareForReuse() {
TitleLabel.text = nil
Description.text = nil
HighLabel.text = nil
LowLabel.text = nil
}
}

Couple of issues with the code here:
Firstly, you are defining sendUpdateRequest() inside viewDidLoad(). Move the whole function outside these enclosing braces to get rid of that error. Second, you don't need to define listData outside the class.
You can then use your existing code for the refresh functionality.
For the columns for High And Low, you will need to subclass a UITableViewCell and add extra labels.
Follow the steps outlined here: How to add more than two labels to prototype cell?.

Related

UITableView isn't appearing in view?

My tableview isn't loading once I press build, can anyone see what's wrong with the code as to why it's not showing up? In the console, it's printing the data from Firestore, but I can't see anything on the simulator but a white screen.
struct Posts {
var caption:String
}
class CoursesVC: UIViewController, UITableViewDelegate {
let tableView = UITableView()
var posts = [Posts]()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
self.tableView.dataSource = self
self.tableView.delegate = self
setupViews()
loadPosts()
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
func loadPosts() {
let dbUsers = Firestore.firestore().collection("Payouts")
dbUsers.addSnapshotListener { (querySnapshot, error) in
if let error = error {
print("\(error.localizedDescription)")
} else {
for document in (querySnapshot?.documents)! {
if let Caption = document.data()["amount"] as? String {
print(Caption)
var post = Posts(caption: "")
post.caption = Caption
self.posts.append(post)
}
}
DispatchQueue.main.async
{
self.tableView.reloadData()
}
print(self.posts)
}
}
}
private func setupViews() {
let stackView: UIStackView = {
let sv = UIStackView()
sv.translatesAutoresizingMaskIntoConstraints = false
sv.spacing = 28
sv.axis = .vertical
sv.distribution = .fill
sv.alignment = .fill
return sv
}()
view.addSubview(stackView)
view.addSubview(tableView)
}
}
extension CoursesVC: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let post = posts[indexPath.row]
cell.textLabel?.text = post.caption
return cell
}
}
You forgot to assign frame to your tableView. As you are adding your tableView programatically so, you have to set frame for your tableView. Write below code in your setupViews() method.
E.g. tableView.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 450.0)
Change tableView frame as per your requirement.

Custom UISearchBar using TextField

I need to make custom UISearchBar using UITextField.
I try to make it myself, but nothing works. Please, write a code for UITextField, which will work like UISearchBar
It's code where I use UISearchBar, but I need to change to UITextField
class FoodViewController: UIViewController {
override var preferredStatusBarStyle: UIStatusBarStyle { return .lightContent }
let tableView = UITableView()
var foods = [FoodModel]()
var searchedFoods = [FoodModel]()
var searching = false
override func viewDidLoad() {
super.viewDidLoad()
fetchFoods()
self.modalPresentationCapturesStatusBarAppearance = true
self.view.backgroundColor = UIColor.white
let controller = UIViewController()
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
self.view.addSubview(self.tableView)
tableView.delegate = self
tableView.dataSource = self
let searchBar = UISearchBar(frame: CGRect(x: 0, y: 5, width: 350, height: 40))
searchBar.searchBarStyle = .minimal
searchBar.barStyle = .black
searchBar.delegate = self
self.view.addSubview(searchBar)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
self.updateLayout(with: self.view.frame.size)
}
func updateLayout(with size: CGSize) {
self.tableView.frame = CGRect.init(x: 0, y: 45, width: size.width, height: 400)
}
func fetchFoods() {
Database.database().reference().child("food").observe(.childAdded) { (snapshot) in
if let dict = snapshot.value as? [String: AnyObject] {
let newTitle = dict["title"] as! String
let exCell = FoodModel(title: newTitle)
self.foods.append(exCell)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}
}
extension FoodViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
if searching {
let food = searchedFoods[indexPath.item]
cell.textLabel?.text = food.title
} else {
let food = foods[indexPath.item]
cell.textLabel?.text = food.title
}
return cell
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searching {
return searchedFoods.count
} else {
return foods.count
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
var titleOfFood = String()
if searching == true {
titleOfFood = searchedFoods[indexPath.row].title
print(titleOfFood)
} else {
titleOfFood = foods[indexPath.row].title
print(titleOfFood)
}
let alertController = UIAlertController(title: "Hello", message: "Message", preferredStyle: .alert)
let cancel = UIAlertAction(title: "Cancel", style: .default)
let save = UIAlertAction(title: "Save", style: .cancel) { (action) in
self.dismiss(animated: true, completion: nil)
}
alertController.addTextField { (textField) in
textField.keyboardType = .numberPad
textField.borderStyle = .roundedRect
textField.layer.borderColor = UIColor.clear.cgColor
textField.addConstraint(textField.heightAnchor.constraint(equalToConstant: 50))
textField.font = UIFont(name: "Roboto-Medium", size: 30)
// textField.cornerRadius = 8
}
alertController.addAction(save)
alertController.addAction(cancel)
self.present(alertController, animated: true)
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
}
}
extension FoodViewController: UITableViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView == self.tableView {
SPStorkController.scrollViewDidScroll(scrollView)
}
}
}
extension FoodViewController: UISearchBarDelegate {
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
searchedFoods = foods.filter({ $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() })
searching = true
tableView.isHidden = false
tableView.reloadData()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.customHeight = 620
transitionDelegate.showIndicator = false
}
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
searching = false
searchBar.text = ""
tableView.reloadData()
}
}
Basically (if i'm understanding you correctly) after you add your UITextField to the view, all you need to have is some method to trigger whenever the value of the UITextField changes.
Something like this:
textField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
And then:
func textFieldDidChange(_ textField: UITextField) {
let searchText = textField.text!
searchedFoods = foods.filter({ $0.title.lowercased().prefix(searchText.count) == searchText.lowercased() })
searching = true
tableView.isHidden = false
tableView.reloadData()
let transitionDelegate = SPStorkTransitioningDelegate()
transitionDelegate.customHeight = 620
transitionDelegate.showIndicator = false
}

display tableView count in UILabel [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I would like to pass the number of tableViewCells into a tableViewHeader UILabel. For example, the label should say "There are ## Rows" based on how many tableViewRows there are in the the tableView (based on Firebase data). Thanks in advance!
// tableViewHeaderClass
class Header: UITableViewHeaderFooterView {
var placeList = [Place]()
var placesDictionary = [String: Place]()
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let nameLabel: UILabel = {
let label = UILabel()
// display the number of tableView rows in UILabel-------
label.text = "## of Places"
label.translatesAutoresizingMaskIntoConstraints = false
label.font = UIFont.boldSystemFont(ofSize: 14)
return label
}()
func setupViews() {
addSubview(nameLabel)
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-16-[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[v0]|", options: NSLayoutFormatOptions(), metrics: nil, views: ["v0": nameLabel]))
}
}
// tableViewController class
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(Header.self, forHeaderFooterViewReuseIdentifier: "headerId")
tableView.sectionHeaderHeight = 50
ref = FIRDatabase.database().reference()
fetchPlaces()
placesClient = GMSPlacesClient.shared()
locationManager.requestAlwaysAuthorization()
navigationItem.title = "Places"
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "+ place", style: .plain, target: self, action: #selector(handleSearchPlaces))
tableView.allowsMultipleSelectionDuringEditing = true
}
var placeList = [Place]()
var placesDictionary = [String: Place]()
func fetchPlaces() {
let uid = FIRAuth.auth()?.currentUser?.uid
let ref = FIRDatabase.database().reference().child("users").child(uid!).child("Places")
ref.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let place = Place()
place.setValuesForKeys(dictionary)
if let addedBy = place.addedBy {
self.placesDictionary[addedBy] = place
self.placeList.insert(place, at: 0)
}
//this will crash because of background thread, so lets call this on dispatch_async main thread
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return placeList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .subtitle, reuseIdentifier: cellId)
cell.textLabel?.text = placeList[indexPath.row].place
return cell
}
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerId")
}
You need to do this
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let view = tableView.dequeueReusableHeaderFooterView(withIdentifier: "headerId") as? Header else { return nil }
// I didn't know what you were using for a count so replace placeList.count with the var you need to use
view.nameLabel.text = "\(placeList.count) of Places"
return view
}

Error occurs on tvos 10.0

I am working on tvos application , it is working fine on 10.1 (newer version) but it gives the error when i am running on previous version (10.0)
after refresh(1 min).
error message is
my code is
NewsViewController
import UIKit
import Kingfisher
private let reuseIdentifier = "trenddingCell"
private let reuseIdentifierRegular = "regularCell"
class NewsViewController: UICollectionViewController {
#IBOutlet var mainCollectionView: UICollectionView!
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var backgroundMessageLabel:UILabel?
var focusFlag:Bool = false
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(NewsViewController.presentController(_:)), name: NSNotification.Name(rawValue: "videoInfo"), object: nil)
let menuPressRecognizer = UITapGestureRecognizer()
menuPressRecognizer.addTarget(self, action: #selector(NewsViewController.menuButtonAction(_:)))
menuPressRecognizer.allowedPressTypes = [NSNumber(value: UIPressType.menu.rawValue as Int)]
self.view.addGestureRecognizer(menuPressRecognizer)
self.tabBarController?.tabBar.preferredFocusedView
self.setNeedsFocusUpdate()
self.updateFocusIfNeeded()
}
func menuButtonAction(_ ges:UITapGestureRecognizer){
self.tabBarController?.tabBar.canBecomeFocused
self.tabBarController?.preferredFocusedView
self.tabBarController?.setNeedsFocusUpdate()
self.tabBarController?.updateFocusIfNeeded()
}
override func viewWillAppear(_ animated: Bool) {
if appDelegate.dataFeedDetail.feedType == "J" || appDelegate.dataFeedDetail.feedType == "L"{
self.title = "ON DEMAND"
}
else{
self.title = "ON DEMAND"
}
//WebTrends().eventForTabBarItemFocus("News", menu: "news")
WebTrends().eventForTabBarItemFocus("News", channelName: "", menu: "news")
appDelegate.viewController = self
appDelegate.playerViewController = self
if appDelegate.categoryNewsArray.count == 0{
addBackgroundMessageLabel()
}else{
removeBackgroundMessage()
mainCollectionView.isHidden = false
if !focusFlag{
mainCollectionView.reloadData()
}
}
focusFlag = false
}
func loadNewData() {
DispatchQueue.main.async(execute: { () -> Void in
if self.appDelegate.categoryNewsArray.count > 0 {
self.removeBackgroundMessage()
self.mainCollectionView.isHidden = false
self.mainCollectionView.reloadData()
}
})
}
// MARK: - Collection Data Source.
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
print("begin numberOfItemsInSection")
return appDelegate.categoryNewsArray.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print("begin cellForItemAt")
if indexPath.item == 0{
let cellTrendding = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! TrendingCollectionCell
let trindingValue = appDelegate.categoryNewsArray.object(at: indexPath.item) as! NSMutableDictionary
cellTrendding.trenddingLabelView.text = trindingValue.object(forKey: "title") as? String
print("end cellTrendding")
return cellTrendding
}else{
let cellRegular = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierRegular, for: indexPath) as! RegularCollectionCell
let trindingValue = appDelegate.categoryNewsArray.object(at: indexPath.item) as! NSMutableDictionary
cellRegular.categoryLabelView.text = trindingValue.object(forKey: "title") as? String
print("end cellRegular")
return cellRegular
}
}
// MARK: - CollectionViewDelegate.
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
print("begin willDisplay")
if indexPath.item == 0{
guard let cell = cell as? TrendingCollectionCell else { fatalError("Expected to display a `TrendingCollectionCell`.") }
let trending = appDelegate.categoryNewsArray.object(at: indexPath.item)
cell.configureWithDataItems(trending as! NSMutableDictionary, jIndex: indexPath.item)
}else{
guard let cell = cell as? RegularCollectionCell else { fatalError("Expected to display a `RegularCollectionCell`.") }
let trending = appDelegate.categoryNewsArray.object(at: indexPath.item) as! NSMutableDictionary
print("appDelegate.categoryNewsArray====================\(trending.count)")
cell.configureWithDataItems(trending, jIndex: indexPath.item)
}
print("end willDisplay")
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
print("begin layout")
if indexPath.item == 0 {
return CGSize(width: view.frame.width, height: 410)
}else{
return CGSize(width: view.frame.width, height: 320)
}
}
override func collectionView(_ collectionView: UICollectionView, canFocusItemAt indexPath: IndexPath) -> Bool{
print("begin canFocusItemAt\(indexPath.item)")
return false
}
override func didUpdateFocus(in context: UIFocusUpdateContext, with coordinator: UIFocusAnimationCoordinator) {
}
// MARK: - Present Controller.
func presentController(_ notification:Notification) {
print("begin presentController")
let notificationData:NSDictionary = NSDictionary(dictionary: notification.userInfo!)
focusFlag = true
let playerVC = self.storyboard?.instantiateViewController(withIdentifier: "VideoPlayerViewController") as! VideoPlayerViewController
playerVC.videoIdentifier = "NewsView"
playerVC.videoCategoryNameandTitle = notificationData.object(forKey: "channelname") as! String as NSString
playerVC.navigationName = "News/\(notificationData.object(forKey: "channelname") as! String)" as NSString
playerVC.indexPath = notificationData.object(forKey: "indexpath") as! Int
playerVC.seriesShowDfpUrl = notificationData.object(forKey: "dfptag") as! String as NSString!
playerVC.seriesShows_Array = notificationData.object(forKey: "metaData") as! NSArray
playerVC.videoMaxShow = notificationData.object(forKey: "max_show") as! String
playerVC.adInterval = notificationData.object(forKey: "adinterval") as! Int
playerVC.modalPresentationStyle = UIModalPresentationStyle.fullScreen
playerVC.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.view.window?.rootViewController?.present(playerVC, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
KingfisherManager.shared.cache.clearMemoryCache()
KingfisherManager.shared.cache.clearDiskCache()
}
func addBackgroundMessageLabel(){
if backgroundMessageLabel == nil {
backgroundMessageLabel = UILabel(frame: CGRect.zero)
backgroundMessageLabel!.center = view.center
backgroundMessageLabel! = backgroundMessageLabel!.setLabelView(backgroundMessageLabel!, message: kNoDataMessage )
self.view.addSubview(backgroundMessageLabel!)
NSLayoutConstraint(item: backgroundMessageLabel!, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: backgroundMessageLabel!, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: view, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0).isActive = true
}
}
func removeBackgroundMessage(){
if self.backgroundMessageLabel != nil {
self.backgroundMessageLabel!.removeFromSuperview()
self.backgroundMessageLabel = nil
}
}
}
extension UILabel {
func setLabelView(_ label:UILabel, message:String) -> UILabel {
let backgroundMessageLabel = label
backgroundMessageLabel.text = message
backgroundMessageLabel.textAlignment = .center
backgroundMessageLabel.font = UIFont(name: "SFUIDisplay-Regular", size: 32.0)
backgroundMessageLabel.textColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)//UIColor.whiteColor()
backgroundMessageLabel.backgroundColor = .clear
backgroundMessageLabel.translatesAutoresizingMaskIntoConstraints = false
return backgroundMessageLabel
}
}
RegularCollectionCell
import UIKit
import Kingfisher
private let cellId = "appCellId"
class RegularCollectionCell: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet var categoryCollectionView: UICollectionView!
#IBOutlet var categoryLabelView: UILabel!
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var dataItems = NSMutableDictionary()
var jsonIndex:Int!
// MARK: Configuration.
func configureWithDataItems(_ dataItems: NSMutableDictionary, jIndex:Int) {
self.dataItems = dataItems
categoryCollectionView.reloadData()
// categoryCollectionView.remembersLastFocusedIndexPath = true
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
let seriesShows_Array = self.dataItems.value(forKey: "max_shows") as? String
let topVideos = self.dataItems.value(forKey: "datafeed") as? NSArray
if seriesShows_Array != "" {
if topVideos!.count > Int(seriesShows_Array!)! {
return Int(seriesShows_Array!)! as Int
}
}
if topVideos != nil && topVideos!.count > 0{
print("Crash numberOfItemsInSection",topVideos!.count)
return topVideos!.count
}else{
return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
print("begin cellForItemAt")
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! CustomCollectionCell
let topVideos = (self.dataItems.value(forKey: "datafeed") as! NSArray).object(at: indexPath.item) as! JsonModel
cell.custom_LabelView.text = topVideos.videoTitle as String
let thumnailURL = topVideos.videoThumbnail as String
print("thumnailURL",thumnailURL)
let validUrl = thumnailURL.checkValidUrl(thumnailURL as String)
print("validUrl",validUrl)
let url = URL(string: validUrl)
print("url",url!)
cell.custom_ImageView.kf.setImage(with: url!, placeholder: UIImage(named: "not_found"), options: [.transition(ImageTransition.fade(0.5))], progressBlock: nil, completionHandler: nil)
cell.custom_LabelView.fadeLength = 100.0
cell.custom_LabelView.shutdownLabel()
print("end cellForItemAt")
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let dfpTag:String = self.dataItems.object(forKey: "dfp_tag") as! String
let adIntervalStr = self.dataItems.object(forKey: "ad_interval") as! String
let adInterval:Int!
if adIntervalStr == ""{
adInterval = 0
}else{
adInterval = Int(adIntervalStr)
}
let channelNameStr:NSString = self.dataItems.object(forKey: "title") as! String as NSString
let topVideos = self.dataItems.value(forKey: "datafeed") as! NSArray
let maxShow = self.dataItems.value(forKey: "max_shows") as! String
var tempDict: NSDictionary = [NSString:AnyObject]() as NSDictionary
tempDict = ["channelname": channelNameStr, "indexpath": indexPath.item, "dfptag": dfpTag, "adinterval": adInterval, "metaData": topVideos, "max_show": maxShow]
NotificationCenter.default.post(name: Notification.Name(rawValue: "videoInfo"), object: nil, userInfo:tempDict as? [AnyHashable: Any])
}
}
Finally I have resolved the problem.
Replace
self.mainCollectionView.reloadItems(at:
self.mainCollectionView.indexPathsForVisibleItems)
from
self.mainCollectionView.reloadata

How do I filter data and return only the relevant users?

I have a tableView in my application that returns all of the users inside of my users node in my Firebase Database. I have a picture of my database tree below, along with the relevant code. How do I get the tableView to return only the users with the numberId set to 1. As I only have 2 users in my database, I want it to return that one user and not the user with the numberId set to 2. At the moment, it returns all of the users. I would appreciate any help. Thank you.
class User: NSObject {
var name: String?
var email: String?
var numberId: String?
var password: String?
var profileImageUrl: String?
}
class UsersController: UITableViewController {
let cellId = "cellId"
var users = [User]()
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel))
tableView.register(UserCell.self, forCellReuseIdentifier: "cellId")
tableView.tableFooterView = UIView()
fetchUser()
}
func fetchUser() {
FIRDatabase.database().reference().child("users").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = User()
user.setValuesForKeys(dictionary)
self.users.append(user)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
func handleCancel() {
dismiss(animated: true, completion: nil)
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return users.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! UserCell
let user = users[indexPath.row]
cell.textLabel?.text = user.name
cell .detailTextLabel?.text = user.email
if let profileImageUrl = user.profileImageUrl {
cell.profileImageView.loadImageUsingCachWithUrlString(urlString: profileImageUrl)
}
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 56
}
}
class UserCell: UITableViewCell {
override func layoutSubviews() {
super.layoutSubviews()
textLabel?.frame = CGRect(x: 58, y: (textLabel?.frame.origin.y)! - 2, width: (textLabel?.frame.width)!, height: (textLabel?.frame.height)!)
detailTextLabel?.frame = CGRect(x: 58, y: (detailTextLabel?.frame.origin.y)! + 2, width: (detailTextLabel?.frame.width)!, height: (detailTextLabel?.frame.height)!)
}
let profileImageView: UIImageView = {
let image = UIImageView()
image.contentMode = .scaleAspectFill
image.layer.masksToBounds = true
image.layer.cornerRadius = 20
image.translatesAutoresizingMaskIntoConstraints = false
return image
}()
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: .subtitle, reuseIdentifier: reuseIdentifier)
setupProfileImageView()
}
func setupProfileImageView() {
addSubview(profileImageView)
profileImageView.leftAnchor.constraint(equalTo: self.leftAnchor, constant: 8).isActive = true
profileImageView.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
profileImageView.widthAnchor.constraint(equalToConstant: 40).isActive = true
profileImageView.heightAnchor.constraint(equalToConstant: 40).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
You need to use queryOrderedByChild and queryEqualToValue.
func fetchUser() {
FIRDatabase.database().reference().child("users").queryOrderedByChild("numberId").queryEqualToValue(1).observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = User()
user.setValuesForKeys(dictionary)
self.users.append(user)
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}, withCancel: nil)
}
You can have idea from here, I don't know about swift how to write code in but.. you can have idea and hope you can write code like wise.