CollectionView in TableviewCell : Display data using Alamofire and SwiftyJSON with MVC model - ios

I have a Collectionview in Tableviewcell. Using Alamofire and SwiftJSON i download data and store in my model project. I have 2 model file one for tableview, and one for collectionview
Model Project for Tableview:
class Matchs {
var matchTime : String
var matchMbs : Int
var matchLeague : String
var matchCode : Int
var matchHomeTeam : String
var matchAwayTeam : String
init(time : String, mbs : Int, league : String, code : Int, homeTeam : String, awayTeam : String ) {
matchTime = time
matchMbs = mbs
matchLeague = league
matchCode = code
matchHomeTeam = homeTeam
matchAwayTeam = awayTeam
}
}
Model Project for Collectionview:
class MatchsOdds {
var homeWin : Double
var awayWin : Double
var draw : Double
var under : Double
var over : Double
var oddResult = ["1","0","2","Under","Over"]
init(homeWin: Double, awayWin : Double, draw : Double, under : Double, over : Double) {
self.homeWin = homeWin
self.awayWin = awayWin
self.draw = draw
self.under = under
self.over = over
}
}
And here is the Viewcontroller code :
class MainViewController: UIViewController {
#IBOutlet weak var tableview: UITableView!
let MATCH_URL = "somelink"
var match : [Matchs] = []
var matchOdd : [MatchsOdds] = []
#IBOutlet weak var totalMatchLabel: UILabel!
#IBOutlet weak var totalOddsLabel: UILabel!
fileprivate func getMatchData(url:String) {
Alamofire.request(url).responseJSON {
response in
if response.result.isSuccess {
print("I got the match data")
let matchJSON : JSON = JSON(response.result.value!)
self.getMatch(json: matchJSON)
}else {
print("Match Unavailable")
}
self.tableview.reloadData()
}
}
fileprivate func getMatch(json: JSON) {
if let matchs = json["data"]["b"]["f"]["list"].array {
matchs.forEach { (arg0) in
let events = arg0
let tournamentName = events["tournamentName"].stringValue
let homeTeam = events["homeTeam"].stringValue
let mbs = events["mbs"].intValue
let matchCode = events["matchCode"].intValue
let matchTime : String = events["eventHour"].stringValue
let awayTeam = events["awayTeam"].stringValue
let matchTimeFirst5 = matchTime.prefix(5)
let allMatch = Matchs(time: String(matchTimeFirst5), mbs: mbs, league: tournamentName, code: matchCode, homeTeam: homeTeam, awayTeam: awayTeam)
let homeWin = events["oddList"][0]["v"].doubleValue
let draw = events["oddList"][1]["v"].doubleValue
let awaywin = events["oddList"][2]["v"].doubleValue
let under = events["oddList"][3]["v"].doubleValue
let over = events["oddList"][4]["v"].doubleValue
let fiveOdds = MatchsOdds(homeWin: homeWin, awayWin: awaywin, draw: draw, under: under, over: over)
match.append(allMatch)
matchOdd.append(fiveOdds)
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
getMatchData(url: MATCH_URL)
}
override func viewDidAppear(_ animated: Bool) {
}
}
extension MainViewController: UITableViewDelegate,UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return match.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let matcCell = match[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "oddsCell") as! OddsTableViewCell
tableView.separatorStyle = .none
cell.matchToMatch(matcs: matcCell)
tableview.allowsSelection = false
cell.collectionview.tag = indexPath.row
cell.collectionview.reloadData()
cell.matchOddCV = matchOdd
return cell
}
}
No problem from here. I cat write data to Tableviewcell labels. But when i try the matchOdds data to Collectionview cell label. I only got first data which is repeating like this:
Here is the code for Tableviewcell :
class OddsTableViewCell: UITableViewCell {
#IBOutlet weak var reloadButton: RoundedButton!
#IBAction func reloadBottonPressed() {
print("reloadDataPressed")
}
var matchOddCV : [MatchsOdds]!
#IBOutlet weak var collectionview: UICollectionView!
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var mbsLabel: UILabel! {
didSet{
mbsLabel.layer.cornerRadius = 5
mbsLabel.layer.masksToBounds = true
}
}
#IBOutlet weak var leageLabel: UILabel!
#IBOutlet weak var matchCodeLabel: UILabel!
#IBOutlet weak var homeVsAwayLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
collectionview.dataSource = self
collectionview.delegate = self
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
func matchToMatch (matcs : Matchs) {
timeLabel.text = matcs.matchTime
mbsLabel.text = String(matcs.matchMbs)
leageLabel.text = matcs.matchLeague
matchCodeLabel.text = String(matcs.matchCode)
homeVsAwayLabel.text = "\(matcs.matchHomeTeam) - \(matcs.matchAwayTeam)"
}
}
extension OddsTableViewCell: UICollectionViewDataSource, UICollectionViewDelegate,UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.bounds.width/5, height: collectionView.bounds.height)
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "oddsCollectionViewCell", for: indexPath) as! OddsCollectionViewCell
let matchCell = matchOddCV[indexPath.row]
if indexPath.row == 0 {
cell.matchResultLabel.text = matchCell.oddResult[0]
cell.matchOddsLabel.text = String(matchCell.homeWin)
}else if indexPath.row == 1{
cell.matchResultLabel.text = matchCell.oddResult[1]
cell.matchOddsLabel.text = String(matchCell.draw)
}else if indexPath.row == 2 {
cell.matchResultLabel.text = matchCell.oddResult[2]
cell.matchOddsLabel.text = String(matchCell.awayWin)
}else if indexPath.row == 3 {
cell.matchResultLabel.text = matchCell.oddResult[3]
cell.matchOddsLabel.text = String(matchCell.under)
}else if indexPath.row == 4 {
cell.matchResultLabel.text = matchCell.oddResult[4]
cell.matchOddsLabel.text = String(matchCell.over)
}
cell.matchOddsLabel.layer.borderWidth = 0.5
cell.matchOddsLabel.layer.borderColor = UIColor.lightGray.cgColor
cell.matchResultLabel.layer.borderWidth = 0.5
cell.matchResultLabel.layer.borderColor = UIColor.lightGray.cgColor
return cell
}
}
Collectionviewcell code :
class OddsCollectionViewCell: UICollectionViewCell {
#IBOutlet weak var matchResultLabel: UILabel!
#IBOutlet weak var matchOddsLabel: UILabel!
}

According to the table's cellForRowAt
cell.collectionview.reloadData()
cell.matchOddCV = matchOdd
you assign the same array for all the collections inside all the table cells , what you need is to create an array property inside each Matchs object and do
let matcCell = match[indexPath.row]
cell.matchOddCV = matcCell.odds // create odds array and assign data for each object
cell.collectionview.reloadData()

As I can see, you are reloading the collectionview before setting the new list matchOddCV.
So you should do:
// assign the new list
cell.matchOddCV = matchOdd
// reload colllectionview
cell.collectionview.reloadData()

Related

UICollectionView showing unloaded xib and not updating the content inside using swift

I have a collection view which is loaded from a .xib file. When the view opens sometimes the collection view will have loaded the content and other times it does not load any content into the cell causing just the .xib to be shown. Other times the .xib doesn't even show either. However, I don't understand why this is happening. When clicking on the cell, a new viewController opens with a detailed view which has the content loaded so the cell obviously knows what is suppose to be shown.
var currentUser: User!
var listCategories: [String] = ["Friends Lists", "Friends", "People"]
var lists = [Media]()
in viewDidLoad:
collectionView.register(UINib(nibName: "ListCell2.0", bundle: nil), forCellWithReuseIdentifier: Storyboard.listCell)
collectionView.reloadData()
observeMedia()
observeMedia():
func observeMedia() {
Media.observeNewMedia { (media) in
if !self.lists.contains(media) {
self.lists.insert(media, at: 0)
self.collectionView.reloadData()
}
}
}
viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
observeMedia()
}
collectionView Methods:
extension HomeViewController
{
func numberOfSections(in collectionView: UICollectionView) -> Int {
return listCategories.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if section == 0 {
return lists.count
}else{
return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Storyboard.listCell, for: indexPath) as! ListCell
cell.layer.applySketchShadow(color: UIColor.black, alpha: 0.08, x: 0, y: 0, blur: 10, spread: 0)
cell.layer.cornerRadius = 20
cell.layer.masksToBounds = false
cell.currentUser = self.currentUser
cell.media = self.lists[indexPath.item]
cell.mainView.setGradientBackground(colours: self.getColourFromTag(tag: self.lists[indexPath.item].tag))
return cell
}
//section header view
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView
{
let sectionHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Storyboard.sectionHeader, for: indexPath) as! SectionHeaderView
let category = listCategories[indexPath.section]
sectionHeaderView.sectionTitle = category
return sectionHeaderView
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.performSegue(withIdentifier: Storyboard.showListDetailSegue, sender: nil)
}
the CollectionView Cell
import UIKit
import Foundation
import SAMCache
class ListCell: UICollectionViewCell {
#IBOutlet weak var nameView: UIView!
#IBOutlet weak var mainView: UIView!
#IBOutlet weak var nameButton: UIButton!
#IBOutlet weak var profileImageView: UIImageView!
//#IBOutlet weak var tagLabel: UILabel!
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var listTitle: UILabel!
#IBOutlet weak var boughtLabel: UILabel!
#IBOutlet weak var boughtProgress: UIProgressView!
var numOfItems = 0
var numOfBought = 0
var counter: Double = 0{
didSet{
boughtProgress.isHidden = false
let fractionalProgress = Float(counter)
boughtProgress.setProgress(fractionalProgress, animated: true)
}
}
var currentUser: User!
var media: Media! {
didSet{
if currentUser != nil{
self.updateUI()
}
}
}
var cache = SAMCache.shared()
func updateUI(){
let profileImageKey = "\(media.createdBy.uid)-profileImage"
if let image = cache?.object(forKey: profileImageKey) as? UIImage {
self.profileImageView.image = image
}else{
media.createdBy.downloadProfilePicture { [weak self] (image, error) in
if let image = image {
self?.profileImageView.image = image
self?.cache?.setObject(image, forKey: profileImageKey)
}else if error != nil {
print(error)
}
}
}
mainView.layer.cornerRadius = 20
mainView.layer.masksToBounds = true
//profile image
profileImageView.layer.cornerRadius = profileImageView.bounds.height / 2.0
profileImageView.layer.masksToBounds = true
//name
nameButton.setTitle("\(media.createdBy.firstName) \(media.createdBy.lastName)", for: [])
nameView.layer.cornerRadius = 20
nameView.layer.masksToBounds = true
//date
dateLabel.text = "\(convertDateFormatter(theDate: media.dueAt))"
dateLabel.backgroundColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0.3)
dateLabel.textColor = UIColor.white
dateLabel.layer.cornerRadius = dateLabel.bounds.height / 2.0
dateLabel.layer.masksToBounds = true
//title
listTitle.text = "\(media.title)"
//progress
numOfItems = media.items.count
print("num of items \(media.items.count)")
counter = Double(numOfBought)/Double(numOfItems)
boughtLabel.text = "\(numOfBought)/\(numOfItems) Bought"
boughtProgress.layer.cornerRadius = boughtProgress.bounds.height / 2.0
boughtProgress.layer.masksToBounds = true
}
#IBAction func arrowDidTap(){
print("arrow tapped")
print(media.tag)
}
func convertDateFormatter(theDate: String) -> String
{
print(theDate)
let newFormat = DateFormatter()
newFormat.dateFormat = "dd/MM/yyyy"
let dueDate = newFormat.date(from: theDate)
newFormat.dateFormat = "dd MMM yy"
print(newFormat.string(from: dueDate!))
return newFormat.string(from: dueDate!)
}
The first image shows when the view first loads. this is just what is shown in the .xib, however, the gradient has loaded, not the content
the second image shows how it should look. This is after scrolling through the view

Initialization of UITableViewCell Fails (Swift)

I'm using a tableView and try to create my cells.. in vain.
I set all the things we have to do (created a prototype cell, gave an identifier ("CustomerCell"), set the delegate and dataSource in the storyBoard and inside the ViewDidLoad both, set the good class in the StoryBoard for the tableView, the cells, etc).
Here's my code:
override func viewDidLoad() {
self.tableView.delegate = self
self.tableView.dataSource = self
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let item = items[indexPath.section]
switch item.type {
case .customer:
if let cell = tableView.dequeueReusableCell(withIdentifier: "CustomerCell", for: indexPath) as? CustomerCellSetter {
cell.item = item as? Customer // THIS is never called, the cell return nil all the time
return cell
}
return UITableViewCell()
}
Is there an other parameter in the equation to get my cell?
Thanks in advance for your precious help !
EDIT:
here's my UITableViewCell classes:
class CustomerCellSetter: CustomerTableViewCell {
var item: Customer? {
didSet {
guard let item = item else {
return }
if let firstName = item.firstName {
fisrtName?.text = firstName
}
if let theLastName = item.lastName {
lastName.text = theLastName
}
if let theGsm = item.GSM {
gsm.text = theGsm
}
if let theMail = item.mail {
mail.text = theMail
}
if let theAdress = item.adress {
adress.text = theAdress
}
if let theNote = item.notes {
notes.text = theNote
}
}
}
}
class CustomerTableViewCell: UITableViewCell {
#IBOutlet var fisrtName : UILabel!
#IBOutlet var lastName : UILabel!
#IBOutlet var gsm : UILabel!
#IBOutlet var mail : UILabel!
#IBOutlet var adress : UILabel!
#IBOutlet var notes : UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
EDIT 2:
did you set the class for the cell as "CustomerCellSetter"?
This can be done in the identity inspector.
Did you have add "UITableViewDelegate, UITableViewDataSource" at class name ?
class ClassName: UITableViewDelegate, UITableViewDataSource {
}
and also you need to add more method of tableview
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1 // number of your rows
}
I needed to set CustomCellSetter, not CustomerTableViewCell in identity inspector. Thanks #OOPer for this simple answer.

Update initialized Data in array with variable then pass array to next view controller

I'm having issues moving the data from the selected cells from the (service2viewcontroller) to the (confirmorderviewcontroller). I am trying to move the cell data (cells with a stepper.value above 0(var quantity > 0.0 (in Service2ViewController))), I was told to pass the array to the next view controller, to do so for a stepper value above 0 I would need to also send the indexpath.row for the rows with a quantity variable above 0 correct? I don't know how to do this if anyone can help I would greatly appreciate it. also the label is not updating when I use the stepper it stays at 0, can I place the quantity variable inside of the array? the total price label in the view controller continues to function and the data is sent to the (confirmorderviewcontroller) with no issues.
first TableView (data is input and forwarded)
class Service2ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var service2Total: UILabel!
#IBOutlet weak var service2TableView: UITableView!
// service data
var Wash: [Service2] = []
//stepper and price calculation
var quantity = Double()
var totalPrice : Double = 0.0
var priceList = [Int : Double]()
var totalProductPrice = [Int : Double]()
var label : Int!
override func viewDidLoad() {
super.viewDidLoad()
Wash = Options2()
if Int(quantity) > 0{
service2TableView.reloadData()
}
priceList[0] = 3.51//price list
priceList[1] = 5.51
service2Total.text = "$0.00"
}
// create data array
func Options2() -> [Service2]{
var washOptions: [Service2] = []
let option1 = Service2(titled: "Test", pricing: "$3.51", image: #imageLiteral(resourceName: "Wash&Fold"), description:"Testing the description box", quantity: Int(quantity))
let option2 = Service2(titled: "Test", pricing: "$5.51", image: #imageLiteral(resourceName: "Wash&Fold"), description: "Testing the description box", quantity: Int(quantity))
washOptions.append(option1)
washOptions.append(option2)
return washOptions
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return Wash.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let Wash1 = Wash[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "Service2Cell", for: indexPath) as! Service2TableViewCell
cell.setService(Wash: Wash1)
cell.selectionStyle = .none
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 133
}
#IBAction func stepperAcn(_ sender: UIStepper) {
//change label value with stepper
let cellPosition = sender.convert(CGPoint.zero, to: service2TableView)
let indPath : IndexPath = service2TableView.indexPathForRow(at: cellPosition)!
quantity = sender.value
let getCurrentProductPrice : Double = priceList[indPath.row]! * sender.value
totalPrice = gettingPriceLabel(indPath: indPath, getCurrentProductPrice: getCurrentProductPrice)
if totalPrice == 0{
service2Total.text = ("$0.00")
}
else{
service2Total.text = ("$")+String(totalPrice)
}
print("total price",totalPrice)
print("quantity double",quantity)
service2TableView.reloadData()
}
func gettingPriceLabel(indPath: IndexPath, getCurrentProductPrice : Double) -> Double
{
totalProductPrice[indPath.row] = getCurrentProductPrice
var totalCost : Double = 0.0
let valuesArr = Array(totalProductPrice.values)
for i in 0..<valuesArr.count
{
totalCost = totalCost + valuesArr[i]
}
return totalCost
}
// add function to collect (didSelectRowAt) and send selected data to cart and prepare for segue
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
// change sender to
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let DestViewController: ConfirmorderViewController = segue.destination as! ConfirmorderViewController
if totalPrice > 0.00{
DestViewController.amount = totalPrice
}
}
}
service initializer
class Service2
{
var service2Title: String
var service2Image: UIImage
var Service2Pricing: String
var service2Description: String
var service2Quantity: Int
init(titled: String, pricing: String, image: UIImage, description: String, quantity: Int){
self.service2Title = titled
self.Service2Pricing = pricing
self.service2Image = image
self.service2Description = description
self.service2Quantity = quantity
}
}
Service 2 TableViewCell
class Service2TableViewCell: UITableViewCell {
#IBOutlet weak var service2Title: UILabel!
#IBOutlet weak var service2Stepper: UIStepper!
#IBOutlet weak var service2StepperLbl: UILabel!
#IBOutlet weak var service2Pricing: UILabel!
#IBOutlet weak var service2Image: UIImageView!
#IBOutlet weak var service2Description: UILabel!
func setService(Wash: Service2){
service2Image.image = Wash.service2Image
service2Pricing.text = Wash.Service2Pricing.description
service2Title.text = Wash.service2Title
service2Description.text = Wash.service2Description
service2StepperLbl.text = Wash.service2Quantity.description
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
Second TableView (receives data)
class ConfirmorderViewController: UIViewController{
#IBOutlet weak var Total: UILabel!
#IBOutlet weak var confirmOrderTableView: UITableView!
var titled = [String]()
var amount: String = ""
//var quantity = String()
var image1 = [UIImage]()
var Price = [Double]()
override func viewDidLoad() {
super.viewDidLoad()
Total.text = amount
confirmOrderTableView.reloadData()
}
}
extension ConfirmorderViewController: UITableViewDataSource, UITableViewDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return titled.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ConfirmOrderTableViewCell") as! ConfirmOrderTableViewCell
cell.coTitle?.text = titled[indexPath.row]
cell.coImg?.image = image1[indexPath.row]
//cell.coQuantity.text = quantity
cell.coPrice?.text = Price.description
return cell
}
}
I have tried here. I got list of row numbers having more than 0 order. I have it stored in whichRowToBeAdd. If user decreased to Zero, respective rows will removed from this array.
With the help of Singleton Class, we can store whatever we need to show in NextViewController
var whichRowToBeAdd = [Int]() // GLOBAL
#IBAction func stepperAcn(_ sender: UIStepper) {
//change label value with stepper
let cellPosition = sender.convert(CGPoint.zero, to: service2TableView)
let indPath : IndexPath = service2TableView.indexPathForRow(at: cellPosition)!
if Int(sender.value) == 0
{
if whichRowToBeAdd.contains(indPath.row)
{
whichRowToBeAdd.remove(at: whichRowToBeAdd.index(of: indPath.row)!)
}
else
{
}
}
else
{
if whichRowToBeAdd.contains(indPath.row)
{
}
else
{
whichRowToBeAdd.append(indPath.row)
}
}
//....
//..... Your Code in your answer
}
// After stepper Action, final click of Button, which moves to Next ViewController
#IBAction func goToConfirmOrder(_ sender: UIBarButtonItem) {
print("\n\n Val_ ", whichRowToBeAdd)
singleTon.sharedInstance.orderDict.removeAll()
for i in 0..<whichRowToBeAdd.count
{
let indPath = IndexPath(row: whichRowToBeAdd[i], section: 0)
let newCell = tblVw.cellForRow(at: indPath) as! Service2TableViewCell
print("qweqwe ",newCell.testLbl.text)
let name : String = newCell.service2Title.text!
let image : UIImage = newCell.service2Image.image
let quantity : Int = Int(newCell.service2StepperLbl.text!)!
getOrderOneByOne(productName: name, productImage: image, productQuantity: quantity)
if i == (whichRowToBeAdd.count - 1)
{
self.performSegue(withIdentifier: "confirmOrderVC", sender: nil)
}
}
}
func getOrderOneByOne(productName: String, productImage : UIImage, productQuantity: Int)
{
let createDict = ["productName" : productName, "productImage" : productImage, "productQuantity" : productQuantity] as [String : Any]
singleTon.sharedInstance.orderDict.append(createDict)
}
Singleton Class
class singleTon: NSObject {
static let sharedInstance = singleTon() // Singleton Instance
var orderDict = [[String : Any]]() // Dictionary Declaration
}
Next ViewController
class ConfirmOrderViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
print("\n\norderDict.coun ", singleTon.sharedInstance.orderDict)
}
}
With this, you can display datas in TableView in this ConfirmOrderViewController.

UISearchController number of rows not getting called

I'm trying to send a request to search for movies, but when i tap on the search bar to write the text i get a crash in cellforrow and it's not calling numberofrows neither the request. Here's my code so far:
class InTheaters: UITableViewController, UISearchResultsUpdating, UISearchBarDelegate {
#IBOutlet weak var poster: UIImageView!
#IBOutlet weak var movieTitle: UILabel!
#IBOutlet weak var date: UILabel!
#IBOutlet weak var duration: UILabel!
#IBOutlet weak var rating: UILabel!
#IBOutlet var theatersTable: UITableView!
#IBOutlet weak var starsView: CosmosView!
var results = [Movie]()
var searchResults = [Search]()
var resultSearchController: UISearchController!
private let key = "qtqep7qydngcc7grk4r4hyd9"
override func viewDidLoad() {
super.viewDidLoad()
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self
self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()
self.resultSearchController.searchBar.placeholder = "Search for movies"
self.theatersTable.tableHeaderView = self.resultSearchController.searchBar
self.theatersTable.reloadData()
getMovieInfo()
customIndicator()
infiniteScroll()
}
func customIndicator() {
self.theatersTable.infiniteScrollIndicatorView = CustomInfiniteIndicator(frame: CGRectMake(0, 0, 24, 24))
self.theatersTable.infiniteScrollIndicatorMargin = 40
}
func infiniteScroll() {
self.theatersTable.infiniteScrollIndicatorStyle = .White
self.theatersTable.addInfiniteScrollWithHandler { (scrollView) -> Void in
self.getMovieInfo()
}
}
func getMovieInfo() {
Alamofire.request(.GET, "http://api.rottentomatoes.com/api/public/v1.0/lists/movies/in_theaters.json?page_limit=10&page=1&country=us&apikey=\(key)").responseJSON() {
(responseData) -> Void in
if let swiftyResponse = responseData.result.value {
let movies = Movies(JSONDecoder(swiftyResponse))
for movie in movies.allMovies {
self.results.append(movie)
}
}
self.theatersTable.reloadData()
self.theatersTable.finishInfiniteScroll()
}
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.searchResults.removeAll(keepCapacity: false)
if (searchController.searchBar.text?.characters.count > 0) {
Alamofire.request(.GET, "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=N&page_limit=10&page=1&apikey=\(key)").responseJSON() {
(responseData) -> Void in
print(responseData)
if let swiftyResponse = responseData.result.value {
let searches = Searches(JSONDecoder(swiftyResponse))
for search in searches.allSearches {
self.searchResults.append(search)
}
}
self.theatersTable.reloadData()
self.theatersTable.finishInfiniteScroll()
}
}
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.resultSearchController.active) {
return self.searchResults.count
} else {
return self.results.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath)
let titleLabel = cell.viewWithTag(1) as! UILabel
let yearLabel = cell.viewWithTag(2) as! UILabel
let durationLabel = cell.viewWithTag(3) as! UILabel
let posterImage = cell.viewWithTag(5) as! UIImageView
let starsTag = cell.viewWithTag(6) as! CosmosView
if (self.resultSearchController.active) {
titleLabel.text = searchResults[indexPath.row].titleMovie
yearLabel.text = searchResults[indexPath.row].yearMovie
durationLabel.text = searchResults[indexPath.row].durationMovie?.description
posterImage.sd_setImageWithURL(NSURL(string: searchResults[indexPath.row].posterMovie!))
starsTag.rating = searchResults[indexPath.row].ratingMovie!
starsTag.settings.updateOnTouch = false
} else {
titleLabel.text = results[indexPath.row].titleMovie
yearLabel.text = results[indexPath.row].yearMovie
durationLabel.text = results[indexPath.row].durationMovie?.description
posterImage.sd_setImageWithURL(NSURL(string: results[indexPath.row].posterMovie!))
starsTag.rating = results[indexPath.row].ratingMovie!
starsTag.settings.updateOnTouch = false
}
return cell
}
I also have some structs with information for the request tell me if you need something from that too.
Found the answer should have reloadData before the request.
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.searchResults.removeAll(keepCapacity: false)
self.theatersTable.reloadData()//should have added this before the request
if (searchController.searchBar.text?.characters.count > 0) {
Alamofire.request(.GET, "http://api.rottentomatoes.com/api/public/v1.0/movies.json?q=\(searchController.searchBar.text!)&page_limit=10&page=1&apikey=\(key)").responseJSON() {
(responseData) -> Void in
if let swiftyResponse = responseData.result.value {
let searches = Searches(JSONDecoder(swiftyResponse))
for search in searches.allSearches {
self.searchResults.append(search)
}
}
self.theatersTable.reloadData()
self.theatersTable.finishInfiniteScroll()
}
}
}

XCode7: "Failed to render instance of" affects all UICollectionViewCells

I currently always get an error when using UICollectionViewCells in a Storyboard. No other Controls show this behavior. How can I get rid of them?
This is how one of the affected CollectionViewCells looks like:
This is how I defined it:
Here is the code of the CategoryCollectionCell
import UIKit
import Foundation
#IBDesignable class CategoryCollectionCell : UICollectionViewCell {
#IBOutlet private weak var imageView: UIImageView!
#IBOutlet private weak var label: UILabel!
internal var id : Int?
override var highlighted : Bool {
didSet {
label.textColor = highlighted ? UIColor.greenColor() : UIColor.whiteColor()
}
}
#IBInspectable var text : String? {
get { return label.text }
set(value) { label.text = value }
}
#IBInspectable var image : UIImage? {
get { return imageView.image }
set(value) { imageView.image = value }
}
}
And this is the code of the CollectionViewController:
extension CategoryViewController : UICollectionViewController {
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = self.collectionView?.dequeueReusableCellWithReuseIdentifier(kReuseCellIdentifier, forIndexPath: indexPath)
var categoryCollectionCell = cell as? CategoryCollectionCell
if categoryCollectionCell == nil {
categoryCollectionCell = CategoryCollectionCell()
}
let data = getDataForIndexPath(indexPath)
if data != nil {
categoryCollectionCell?.id = data!.id
categoryCollectionCell!.text = data!.category
categoryCollectionCell!.image = data!.image
}
return categoryCollectionCell!
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 8
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
}
extension CategoryViewController : UICollectionViewDelegateFlowLayout {
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else {
return CGSize()
}
let width = CGRectGetWidth(collectionView.bounds)
let padding = flowLayout.sectionInset.left + flowLayout.sectionInset.right
let itemSpacing = flowLayout.minimumInteritemSpacing
let size = (width - padding - itemSpacing) / 2
return CGSize(width: size, height: size)
}
}
Ok. I found that the errors displayed by XCode had nothing to do with the actual problem.
The directory /Users/{Username}/Library/Logs/DiagnosticReports should contain files with names like this: IBDesignablesAgentCocoaTouch[...].crash
Inside them I found stacktraces which led me to the real problem:
The problem lied inside the code of a custom UITableViewCell instead of a UICollectionViewCell
class FooTableCell : UITableViewCell {
#IBOutlet private weak var checkmarkImageView: UIImageView!
override internal var selected : Bool {
didSet {
checkmarkImageView.hidden = !selected
}
}
}
The checkmarkImageView was nil when using the designer. Because of this the Cocoa Storyboard Agent crashed.
I fixed it by adding a guard statement:
class FooTableCell : UITableViewCell {
#IBOutlet private weak var checkmarkImageView: UIImageView!
override internal var selected : Bool {
didSet {
guard let imageView = checkmarkImageView else {
return
}
imageView.hidden = !selected
}
}
}

Resources