append all textfields in tableview cells to array - arrays

I want my swift code to take the characters in each textfield and convert then into a array when func append is called. You can see the comment in the func as well. The user when the func is called will take all of the textfields in class customtv and add them to array empty. Assume that every textfield contains a int.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var empty = [Int]()
var appended = UIButton()
var tableView = UITableView()
var arr = [0,1,2,3,4]
#objc func append(){
///append all of the textfiels into array empty. All of the textfiels are in customtv
}
override func viewDidLoad() {
super.viewDidLoad()
appended.backgroundColor = .orange
view.addSubview(appended)
let VCframe = view.frame
let height = VCframe.height * 0.8
let height2 = VCframe.height * 0.2
let widthx = VCframe.width
appended.frame = CGRect(x: 0, y: height, width: widthx, height: height2)
appended.addTarget(self, action: #selector(append), for: .touchDown)
tableView.frame = CGRect(x: 10, y: 0, width: widthx - 20, height: height)
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
tableView.register(customtv.self, forCellReuseIdentifier: "cell")
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 118 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! customtv
cell.lbl.text = "\(arr[indexPath.row])"
return cell
}
}
class customtv: UITableViewCell {
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width , height: 110))
view.backgroundColor = .green
print(self.frame.width)
return view
}()
override func layoutSubviews() {
backView.clipsToBounds = true
backView.frame = CGRect(x: 0, y: 6, width: bounds.maxX , height: 110)
}
lazy var lbl : UILabel = {
let press = UILabel(frame: CGRect(x: 0, y: 3, width: 120 , height: 50))
press.backgroundColor = .yellow
press.text = String("1")
return press
}()
lazy var txtField : UITextField = {
let press = UITextField(frame: CGRect(x: 100, y: 3, width: 120 , height: 50))
press.backgroundColor = .white
press.textAlignment = .center
return press
}()
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(animated, animated: true)
addSubview(backView)
backView.addSubview(lbl)
backView.addSubview(txtField)
}
}

Try this, please. This works with Swift 5.
func append() {
let arrayTextFields = (0..<arr.count).compactMap { (tableView.cellForRow(at: IndexPath(row: $0, section: 0)) as? customtv)?.txtField }
}
if you want to get Int values from text fields, you can add this.
let arrayValues = arrayTextFields.compactMap { Int($0.text!) }

Related

append uiimages to a uiimage array

I want my swift code below to append all of the images that are displayed in each tableview cell to be appended to an array. In this case the array is emptyA. I tried to do this action in aDDBTn. I am getting a compile error on
let arrayValues2 = collect.compactMap { UIImage($0.self.image) }
with compactMap. I just want to appended thoses images to the array when the func is called.
import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var emptyA = [UIImage]()
var addBTN = UIButton()
var tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
setTableVIew()
aDDBTn()
}
func setTableVIew(){
addBTN.backgroundColor = .orange
view.addSubview(addBTN)
addBTN.addTarget(self, action: #selector(aDDBTn), for: .touchDown)
let VCframe = view.frame
let height = VCframe.height * 0.8
let height2 = VCframe.height * 0.2
let widthx = VCframe.width
addBTN.frame = CGRect(x: 0, y: height, width: widthx, height: height2)
tableView.frame = CGRect(x: 10, y: 0, width: widthx - 20, height: height)
tableView.delegate = self
tableView.dataSource = self
view.addSubview(tableView)
tableView.register(customtv.self, forCellReuseIdentifier: "cell")
}
var arr = [1,2,3,4]
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 118 }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arr.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! customtv
return cell
}
#objc func aDDBTn(){
let collect = (0..<arr.count).compactMap { (tableView.cellForRow(at: IndexPath(row: $0, section: 0)) as? customtv)?.lbl }
let arrayValues2 = collect.compactMap { UIImage($0.self.image) }
emptyA.append(contentsOf: arrayValues2)
print("Empty Array" , emptyA)
}
}
class customtv: UITableViewCell {
lazy var backView : UIView = {
let view = UIView(frame: CGRect(x: 10, y: 6, width: self.frame.width , height: 110))
view.backgroundColor = .green
print(self.frame.width)
return view
}()
override func layoutSubviews() {
backView.clipsToBounds = true
backView.frame = CGRect(x: 0, y: 6, width: bounds.maxX , height: 110)
}
lazy var lbl : UIImageView = {
let press = UIImageView(frame: CGRect(x: 0, y: 3, width: 120 , height: 50))
press.backgroundColor = .yellow
press.image = UIImage(named: "a2")
return press
}()
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(animated, animated: true)
addSubview(backView)
backView.addSubview(lbl)
}
}
The type of collect is [UIImageView] based on the following line since lbl is of type UIImageView
let collect = (0..<arr.count).compactMap { (tableView.cellForRow(at: IndexPath(row: $0, section: 0)) as? customtv)?.lbl }
As a result, you can access the image directly through the image property. Just change the following line
let arrayValues2 = collect.compactMap { UIImage($0.self.image) }
to
let arrayValues2 = collect.compactMap { $0.image }

Fatal error: Array index out of range when appending array

I currently have an array which I am appending options to. They are they displayed in a table with 3 sections. The first 2 sections have 1 row each, but the third section has a variable number of rows depending on what is appended to the array. I essentially take the third component of my initial array (allAlbums[0].markscheme) and break it down to create multiple new items in the array.
However, when I am trying to simulate this, I get a fatal array on 'cell.textData?.text = section[indexPath.row] as! String' and I'm not sure why?
final class CaseViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet var titleText: UILabel!
#IBOutlet var tableView: UITableView!
private var allAlbums = [Case]()
let kHeaderSectionTag: Int = 6900;
var expandedSectionHeaderNumber: Int = -1
var expandedSectionHeader: UITableViewHeaderFooterView!
var sectionItems: Array<Any> = []
var sectionNames: Array<Any> = []
var markschemeRows: Array<Any> = []
override func viewDidLoad() {
super.viewDidLoad()
allAlbums = LibraryAPI.shared.getCases()
// Filter the main array to match a single case
allAlbums = allAlbums.filter { $0.title == title}
// Get data to fill in to table
sectionNames = [ "Trainee Information", "Patient Information", "Examiner Information" ];
sectionItems = [ [allAlbums[0].doctor], [allAlbums[0].patient], [allAlbums[0].markscheme]]
let text = allAlbums[0].markscheme
markschemeRows = text.components(separatedBy: " ")
sectionItems.append(contentsOf: markschemeRows)
// Autoresize rows
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 500
// Remove excess row seperators
tableView.tableFooterView = UIView()
tableView.separatorColor = UIColor.clear
titleText.text = title
}
func numberOfSections(in tableView: UITableView) -> Int {
return 3
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if (self.expandedSectionHeaderNumber == section) {
// Header section
let header = self.sectionNames[section] as! String
// If markscheme, create the markscheme format
if (header == "Examiner Information")
{
print(self.markschemeRows.count)
return self.markschemeRows.count
}
else
{
let arrayOfItems = self.sectionItems[section] as! NSArray
print(arrayOfItems.count)
return arrayOfItems.count
}
} else {
return 0;
}
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if (self.sectionNames.count != 0) {
return self.sectionNames[section] as? String
}
return ""
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 44.0;
}
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat{
return 0;
}
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
//recast your view as a UITableViewHeaderFooterView
let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.contentView.backgroundColor = UIColor.darkGray
header.textLabel?.textColor = UIColor.white
if let viewWithTag = self.view.viewWithTag(kHeaderSectionTag + section) {
viewWithTag.removeFromSuperview()
}
let headerFrame = self.view.frame.size
let theImageView = UIImageView(frame: CGRect(x: headerFrame.width - 32, y: 13, width: 18, height: 18));
theImageView.image = UIImage(named: "Chevron-Dn-Wht")
theImageView.tag = kHeaderSectionTag + section
header.addSubview(theImageView)
// make headers touchable
header.tag = section
let headerTapGesture = UITapGestureRecognizer()
headerTapGesture.addTarget(self, action: #selector(CaseViewController.sectionHeaderWasTouched(_:)))
header.addGestureRecognizer(headerTapGesture)
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
cell.textData?.text = section[indexPath.row] as! String
return cell
}
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
// MARK: - Expand / Collapse Methods
#objc func sectionHeaderWasTouched(_ sender: UITapGestureRecognizer) {
let headerView = sender.view as! UITableViewHeaderFooterView
let section = headerView.tag
let eImageView = headerView.viewWithTag(kHeaderSectionTag + section) as? UIImageView
if (self.expandedSectionHeaderNumber == -1) {
self.expandedSectionHeaderNumber = section
tableViewExpandSection(section, imageView: eImageView!)
} else {
if (self.expandedSectionHeaderNumber == section) {
tableViewCollapeSection(section, imageView: eImageView!)
} else {
let cImageView = self.view.viewWithTag(kHeaderSectionTag + self.expandedSectionHeaderNumber) as? UIImageView
tableViewCollapeSection(self.expandedSectionHeaderNumber, imageView: cImageView!)
tableViewExpandSection(section, imageView: eImageView!)
}
}
}
func tableViewCollapeSection(_ section: Int, imageView: UIImageView) {
let sectionData = self.sectionItems[section] as! NSArray
self.expandedSectionHeaderNumber = -1;
if (sectionData.count == 0) {
return;
} else {
UIView.animate(withDuration: 0.4, animations: {
imageView.transform = CGAffineTransform(rotationAngle: (0.0 * CGFloat(Double.pi)) / 180.0)
})
var indexesPath = [IndexPath]()
for i in 0 ..< sectionData.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
self.tableView!.beginUpdates()
self.tableView!.deleteRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
}
}
func tableViewExpandSection(_ section: Int, imageView: UIImageView) {
let sectionData = self.sectionItems[section] as! NSArray
if (sectionData.count == 0) {
self.expandedSectionHeaderNumber = -1;
return;
} else {
UIView.animate(withDuration: 0.4, animations: {
imageView.transform = CGAffineTransform(rotationAngle: (180.0 * CGFloat(Double.pi)) / 180.0)
})
var indexesPath = [IndexPath]()
// Header section
let header = self.sectionNames[section] as! String
// If markscheme, create the markscheme format
if (header == "Examiner Information")
{
for i in 0 ..< markschemeRows.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
else
{
for i in 0 ..< sectionData.count {
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
}
}
self.expandedSectionHeaderNumber = section
self.tableView!.beginUpdates()
self.tableView!.insertRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
}
}
}
The error is pretty clear.
In numberOfRows you return markschemeRows.count for section 2 which is the number of separated items in this line
markschemeRows = text.components(separatedBy: " ")
Then you must also get the item from markschemeRows rather than from section[indexPath.row] in cellForRow
var markschemeRows = [String]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
if indexPath.section == 2 {
cell.textData?.text = markschemeRows[indexPath.row]
} else {
cell.textData?.text = section[indexPath.row] as! String
}
return cell
}
Your code is quite cumbersome. For example sectionNames and markschemeRows are clearly [String].Why do you declare the arrays as [Any]? This is Swift. Take care of the types. And don't use Foundation collection types like NSArray in Swift at all. Again take care of the types.

Trying to filter the values in one drop down menu depending on the value selected in another drop down menu in swift

I have two drop down menus, one containing car makes and one containing car models. When I select a car make is it possible to filter the values in the models drop down to show only those that correspond with that particular make?
Currently, when I select a car make from the menu, the title value will change to whatever is selected. I have tried to use this value as a parameter for filtering the model options but have had no luck. Hope I have made this clear enough :)
import UIKit
class ViewController: UIViewController {
////Set up buttons
var makeButton = makeDropDownBtn()
var modelButton = modelDropDownBtn()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically
from a nib.
makeButton = makeDropDownBtn.init(frame: CGRect(x: 0, y: 0,
width: 0, height: 0))
makeButton.setTitle("Select Make", for: .normal)
makeButton.titleLabel?.font = UIFont.boldSystemFont(ofSize:
17)
makeButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(makeButton)
makeButton.centerXAnchor.constraint(equalTo:
self.view.centerXAnchor).isActive = true
makeButton.centerYAnchor.constraint(equalTo:
self.view.centerYAnchor, constant: -300).isActive = true
makeButton.widthAnchor.constraint(equalToConstant:
450).isActive = true
makeButton.heightAnchor.constraint(equalToConstant:
50).isActive = true
makeButton.makeDropView.dropDownOptions = carMake
modelButton = modelDropDownBtn.init(frame: CGRect(x: 0, y: 0,
width: 0, height: 0))
modelButton.setTitle("Select Model", for: .normal)
modelButton.titleLabel?.font = UIFont.boldSystemFont(ofSize:
17)
modelButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(modelButton)
modelButton.centerXAnchor.constraint(equalTo:
self.view.centerXAnchor).isActive = true
modelButton.centerYAnchor.constraint(equalTo:
self.view.centerYAnchor, constant: -240).isActive = true
modelButton.widthAnchor.constraint(equalToConstant:
450).isActive = true
modelButton.heightAnchor.constraint(equalToConstant:
50).isActive = true
modelButton.modelDropView.modelDropDownOptions = carModel
}
}
protocol makeDropDownProtocol {
func makeDropDownPressed(string: String)
}
protocol modelDropDownProtocol {
func modelDropDownPressed(string: String)
}
class modelDropDownBtn: UIButton, modelDropDownProtocol {
func modelDropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissModelDropDown()
}
var modelDropView = modelDropDownView()
var modelheight = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame:frame)
self.backgroundColor = UIColor(red: 52/255, green: 49/255,
blue: 78/255, alpha: 1)
modelDropView = modelDropDownView.init(frame: CGRect(x: 0, y:
0, width: 0, height: 0 ))
modelDropView.modelDelegate = self
modelDropView.translatesAutoresizingMaskIntoConstraints =
false
}
override func didMoveToSuperview() {
self.superview?.addSubview(modelDropView)
self.superview?.bringSubviewToFront(modelDropView)
modelDropView.topAnchor.constraint(equalTo:
self.bottomAnchor).isActive = true
modelDropView.centerXAnchor.constraint(equalTo:
self.centerXAnchor).isActive = true
modelDropView.widthAnchor.constraint(equalTo:
self.widthAnchor).isActive = true
modelheight =
modelDropView.heightAnchor.constraint(equalToConstant: 0)
}
var isOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event:
UIEvent?) {
if isOpen == false {
isOpen = true
NSLayoutConstraint.deactivate([self.modelheight])
if self.modelDropView.modelTableView.contentSize.height >
150 {
self.modelheight.constant = 150
} else {
self.modelheight.constant =
self.modelDropView.modelTableView.contentSize.height
}
NSLayoutConstraint.activate([self.modelheight])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.modelDropView.layoutIfNeeded()
self.modelDropView.center.y +=
self.modelDropView.frame.height / 2
}, completion: nil)
} else {
isOpen = false
NSLayoutConstraint.deactivate([self.modelheight])
self.modelheight.constant = 0
NSLayoutConstraint.activate([self.modelheight])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5,
options: .curveEaseInOut, animations: {
self.modelDropView.center.y -=
self.modelDropView.frame.height / 2
self.modelDropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissModelDropDown() {
isOpen = false
NSLayoutConstraint.deactivate([self.modelheight])
self.modelheight.constant = 0
NSLayoutConstraint.activate([self.modelheight])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.modelDropView.center.y -=
self.modelDropView.frame.height / 2
self.modelDropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class makeDropDownBtn: UIButton, makeDropDownProtocol {
func makeDropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissMakeDropDown()
}
var makeDropView = makeDropDownView()
var height = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame:frame)
self.backgroundColor = UIColor(red: 52/255, green: 49/255,
blue: 78/255, alpha: 1)
makeDropView = makeDropDownView.init(frame: CGRect.init(x: 0,
y: 0, width: 0, height: 0))
makeDropView.delegate = self
makeDropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(makeDropView)
self.superview?.bringSubviewToFront(makeDropView)
makeDropView.topAnchor.constraint(equalTo:
self.bottomAnchor).isActive = true
makeDropView.centerXAnchor.constraint(equalTo:
self.centerXAnchor).isActive = true
makeDropView.widthAnchor.constraint(equalTo:
self.widthAnchor).isActive = true
height = makeDropView.heightAnchor.constraint(equalToConstant:
0)
}
var makeisOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event:
UIEvent?) {
if makeisOpen == false {
makeisOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.makeDropView.tableView.contentSize.height > 150 {
self.height.constant = 150
self.superview?.bringSubviewToFront(makeDropView)
} else {
self.height.constant =
self.makeDropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {self.makeDropView.layoutIfNeeded()
self.makeDropView.center.y +=
self.makeDropView.frame.height / 2
}, completion: nil)
} else {
makeisOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5,initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.makeDropView.center.y -=
self.makeDropView.frame.height / 2
self.makeDropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissMakeDropDown() {
makeisOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5,initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.makeDropView.center.y -=
self.makeDropView.frame.height / 2
self.makeDropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
/////Drop Down View Setup
struct Section {
var make: String
var model: [String]
}
var Cars = [
Section(make: "BMW", model: ["A","B","C"]),
Section(make: "Ford", model: ["D","E","F"]),
Section(make: "Audi", model: ["G","H","I"]),
Section(make: "Bentley", model: ["J","K","L"])
]
var carMake = Cars.map({$0.make})
var carModel = Cars.flatMap({$0.model})
class makeDropDownView: UIView,
UITableViewDelegate,UITableViewDataSource {
var dropDownOptions = [String]()
var tableView = UITableView()
var delegate : makeDropDownProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.white
self.backgroundColor = UIColor.white
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo:
self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo:
self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo:
self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo:
self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
return Cars.map({$0.make}).count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
var cell = UITableViewCell()
cell.textLabel!.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.init(red: 255/255, green:
160/255, blue: 122/255, alpha: 0.8)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath:
IndexPath) {
self.delegate.makeDropDownPressed(string:
dropDownOptions[indexPath.row])
}
}
///model drop down view setup
class modelDropDownView: UIView, UITableViewDelegate,
UITableViewDataSource {
var modelDropDownOptions = [String] ()
var modelTableView = UITableView()
var modelDelegate : modelDropDownProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
modelTableView.backgroundColor = UIColor.green
self.backgroundColor = UIColor.green
modelTableView.delegate = self
modelTableView.dataSource = self
modelTableView.translatesAutoresizingMaskIntoConstraints =
false
self.addSubview(modelTableView)
modelTableView.leftAnchor.constraint(equalTo:
self.leftAnchor).isActive = true
modelTableView.rightAnchor.constraint(equalTo:
self.rightAnchor).isActive = true
modelTableView.topAnchor.constraint(equalTo:
self.topAnchor).isActive = true
modelTableView.bottomAnchor.constraint(equalTo:
self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection
section: Int) -> Int {
return Cars.flatMap({$0.model}).count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
var modelCell = UITableViewCell()
modelCell.textLabel!.text =
modelDropDownOptions[indexPath.row]
modelCell.backgroundColor = UIColor.green
return modelCell
}
func makeselection(_ tableView: UITableView, didSelectRowAt
indexPath: IndexPath) {
self.modelDelegate.modelDropDownPressed(string:
modelDropDownOptions[indexPath.row])
}
}
Hopefully it is possible to filter the model results based on what make I select in the make drop down. Thanks in advance.
You don't need to create two UIButton subclasses and two UIView subclasses. You can create one class and create multiple instances.
Don't set dropDownOptions for model button, till a make is selected.
When make is selected get model from the selected make and set in model dropDownOptions.
Just copy this code and run. It works
/////Drop Down View Setup
struct Section {
var make: String
var model: [String]
}
var Cars = [
Section(make: "BMW", model: ["A","B","C"]),
Section(make: "Ford", model: ["D","E","F"]),
Section(make: "Audi", model: ["G","H","I"]),
Section(make: "Bentley", model: ["J","K","L"])
]
var carMake = Cars.map({$0.make})
class ViewController: UIViewController, DropDownBtnProtocol {
func optionChanged(_ button: DropDownBtn, string: String) {
if button == makeButton {
if let selectedMake = Cars.first(where: { $0.make == string }) {
modelButton.dropView.dropDownOptions = selectedMake.model
}
} else if button == modelButton {
}
}
////Set up buttons
var makeButton = DropDownBtn()
var modelButton = DropDownBtn()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
makeButton = DropDownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
makeButton.delegate = self
makeButton.setTitle("Select Make", for: .normal)
makeButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
makeButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(makeButton)
makeButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
makeButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -300).isActive = true
makeButton.widthAnchor.constraint(equalToConstant: 450).isActive = true
makeButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
makeButton.dropView.dropDownOptions = carMake
modelButton = DropDownBtn.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
modelButton.delegate = self
modelButton.setTitle("Select Model", for: .normal)
modelButton.titleLabel?.font = UIFont.boldSystemFont(ofSize: 17)
modelButton.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(modelButton)
modelButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
modelButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -240).isActive = true
modelButton.widthAnchor.constraint(equalToConstant: 450).isActive = true
modelButton.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
}
protocol DropDownBtnProtocol {
func optionChanged(_ button: DropDownBtn, string: String)
}
class DropDownBtn: UIButton, DropDownViewProtocol {
func dropDownPressed(string: String) {
self.setTitle(string, for: .normal)
self.dismissMakeDropDown()
delegate.optionChanged(self, string: string)
}
var delegate: DropDownBtnProtocol!
var dropView = DropDownView()
var height = NSLayoutConstraint()
override init(frame: CGRect) {
super.init(frame:frame)
self.backgroundColor = UIColor(red: 52/255, green: 49/255, blue: 78/255, alpha: 1)
dropView = DropDownView.init(frame: CGRect.init(x: 0, y: 0, width: 0, height: 0))
dropView.delegate = self
dropView.translatesAutoresizingMaskIntoConstraints = false
}
override func didMoveToSuperview() {
self.superview?.addSubview(dropView)
self.superview?.bringSubviewToFront(dropView)
dropView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
dropView.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
dropView.widthAnchor.constraint(equalTo: self.widthAnchor).isActive = true
height = dropView.heightAnchor.constraint(equalToConstant: 0)
}
var makeisOpen = false
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
if makeisOpen == false {
makeisOpen = true
NSLayoutConstraint.deactivate([self.height])
if self.dropView.tableView.contentSize.height > 150 {
self.height.constant = 150
self.superview?.bringSubviewToFront(dropView)
} else {
self.height.constant = self.dropView.tableView.contentSize.height
}
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {self.dropView.layoutIfNeeded()
self.dropView.center.y += self.dropView.frame.height / 2
}, completion: nil)
} else {
makeisOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5,initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
}
func dismissMakeDropDown() {
makeisOpen = false
NSLayoutConstraint.deactivate([self.height])
self.height.constant = 0
NSLayoutConstraint.activate([self.height])
UIView.animate(withDuration: 0.5, delay: 0,
usingSpringWithDamping: 0.5,initialSpringVelocity: 0.5, options:
.curveEaseInOut, animations: {
self.dropView.center.y -= self.dropView.frame.height / 2
self.dropView.layoutIfNeeded()
}, completion: nil)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
protocol DropDownViewProtocol {
func dropDownPressed(string: String)
}
class DropDownView: UIView, UITableViewDelegate,UITableViewDataSource {
var dropDownOptions = [String]() {
didSet {
tableView.reloadData()
}
}
var tableView = UITableView()
var delegate : DropDownViewProtocol!
override init(frame: CGRect) {
super.init(frame: frame)
tableView.backgroundColor = UIColor.white
self.backgroundColor = UIColor.white
tableView.delegate = self
tableView.dataSource = self
tableView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(tableView)
tableView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
tableView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return dropDownOptions.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath:
IndexPath) -> UITableViewCell {
let cell = UITableViewCell()
cell.textLabel!.text = dropDownOptions[indexPath.row]
cell.backgroundColor = UIColor.init(red: 255/255, green: 160/255, blue: 122/255, alpha: 0.8)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
self.delegate.dropDownPressed(string: dropDownOptions[indexPath.row])
}
}

Create multiple UIImageViews in UICollectionViewCell

I'm trying to make multiple UIImageViews in a UICollectionViewCell so I wrote this code but nothing appends to lines apparently.
class chartsCell: UICollectionViewCell {
var lines = [UIImageView]()
var chartValueCount = Int()
override func prepareForReuse() {
super.prepareForReuse()
lines.removeAll()
chartValueCount = 0
}
override init(frame: CGRect) {
super.init(frame: frame)
for i in 0 ..< chartValueCount {
let line = UIImageView(frame: CGRect(x: frame.width * CGFloat(i + 1) / CGFloat(chartValueCount + 1) - (10 * CGFloat(i + 1)), y: 0, width: 20, height: frame.height))
line.backgroundColor = UIColor.blue
line.layer.masksToBounds = true
line.layer.cornerRadius = 10
lines.append(line)
contentView.addSubview(lines[i])
}
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
I change chartValueCount here:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "chartsCell", for: indexPath) as! chartsCell
cell.chartValueCount = chartValueCount[indexPath.row]
return cell
}
There are three values in chartValueCount array and as I print cell.lines it prints three [].
Nothing shows up in the CollectionView because lines is empty. How do I fill it properly?
class chartsCell: UICollectionViewCell {
var lines = [UIImageView]()
var chartValueCount:Int{
didSet{
for i in 0 ..< chartValueCount {
let line = UIImageView(frame: CGRect(x: frame.width * CGFloat(i + 1) / CGFloat(chartValueCount + 1) - (10 * CGFloat(i + 1)), y: 0, width: 20, height: frame.height))
line.backgroundColor = UIColor.blue
line.layer.masksToBounds = true
line.layer.cornerRadius = 10
lines.append(line)
contentView.addSubview(lines[i])
}
}
}
override func prepareForReuse() {
super.prepareForReuse()
lines.removeAll()
chartValueCount = 0
}
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

CollectionView reloaddata() after value change

I have a problem updating my CollectionView after values in an array changed. I made a short gif of my problem.
As you can see I can add goals for both teams in my soccer app. When I press the game statistic button for the first time, the result (e.g. 2:1) in the statistic view sliding in from the bottom, is correct. But as the game goes on and the home team scores again, the statistics won’t change.
I have tried several ways to call reloaddata() to update my collectionView, with no success so far. So hopefully someone can get me on the right track.
Thank you very much in advance.
GameStatistics View Controller - GameStatistics.swift
import UIKit
class StatisticTitle: NSObject {
let name: String
init(name: String) {
self.name = name
}
}
class HomeTeamValue: NSObject {
var value: Int
init(value: Int) {
self.value = value
}
}
class AwayTeamValue: NSObject {
var value: Int
init(value: Int) {
self.value = value
}
}
class GameStatistics: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
let blackView = UIView()
let collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
cv.backgroundColor = UIColor.white
return cv
}()
let cellId = "cellId"
let sectionHeader = "sectionHeader"
let sectionFooter = "sectionFooter"
let cellHeight: CGFloat = 40
let headerHeight: CGFloat = 80
let footerHeight: CGFloat = 50
let cellSpacing: CGFloat = 0
let statisticTitles: [StatisticTitle] = {
return[
StatisticTitle(name: "Goals"), //Tore
StatisticTitle(name: "Shots on Target"), //Schüsse aufs Tor
StatisticTitle(name: "Shots off Target"), //Schüsse neben das Tor
StatisticTitle(name: "Free Kicks"), //Freistöße
StatisticTitle(name: "Corner Kicks"), //Eckbälle
StatisticTitle(name: "Fouls"), //Fouls
StatisticTitle(name: "Offside / Centerline"), //Abseits / Mittellinie
StatisticTitle(name: "Cautions")] //Cautions Strafen
}()
lazy var homeTeamValues: [HomeTeamValue] = {
[ HomeTeamValue(value: homeGoals),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0),
HomeTeamValue(value: 0)
]
}()
lazy var awayTeamValues: [AwayTeamValue] = {
[ AwayTeamValue(value: awayGoals),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0),
AwayTeamValue(value: 0)
]
}()
func showStatistics() {
if let window = UIApplication.shared.keyWindow {
blackView.backgroundColor = UIColor(white: 0, alpha: 0.5)
blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
window.addSubview(blackView)
window.addSubview(collectionView)
// Dynamic Height of Collection View
let value: CGFloat = CGFloat(statisticTitles.count)
let height: CGFloat = value * cellHeight + (value - 1) * cellSpacing + headerHeight + footerHeight
let y = window.frame.height - height
blackView.frame = window.frame
collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: height)
blackView.alpha = 0
UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
self.blackView.alpha = 1
self.collectionView.frame = CGRect(x: 0, y: y, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
}, completion: nil)
}
}
#objc func handleDismiss() {
UIView.animate(withDuration: 0.5) {
self.blackView.alpha = 0
if let window = UIApplication.shared.keyWindow {
self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: self.collectionView.frame.width, height: self.collectionView.frame.height)
}
}
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return statisticTitles.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! GameStatisticCell
let title = statisticTitles[indexPath.item]
cell.statisticTitle = title
let homeValue = homeTeamValues[indexPath.item]
cell.homeTeamValue = homeValue
let awayValue = awayTeamValues[indexPath.item]
cell.awayTeamValue = awayValue
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: collectionView.frame.width, height: cellHeight)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return cellSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return cellSpacing
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
switch kind {
case UICollectionElementKindSectionHeader:
let supplementaryView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: sectionHeader, for: indexPath)
return supplementaryView
case UICollectionElementKindSectionFooter:
let supplementaryView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: sectionFooter, for: indexPath)
return supplementaryView
default:
fatalError("Unexpected element kind")
}
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: headerHeight)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
return CGSize(width: collectionView.frame.width, height: footerHeight)
}
override init() {
super.init()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(GameStatisticCell.self, forCellWithReuseIdentifier: cellId)
collectionView.register(GameStatisticHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: sectionHeader)
collectionView.register(GameStatisticFooter.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: sectionFooter)
}
}
GameStatistic Cell - GameStatisticCell.swift
import UIKit
class GameStatisticCell: BaseCell {
let statisticTitleLabel: UILabel = {
let label = UILabel()
label.text = "Shots on Goal"
label.textColor = ColorCodes.darkGray
label.textAlignment = .center
label.font = UIFont(name: "HelveticaNeue-Medium", size: 12)
return label
}()
var statisticTitle: StatisticTitle? {
didSet { statisticTitleLabel.text = statisticTitle?.name }
}
let homeTeamStatistic: UILabel = {
let label = UILabel()
label.text = String(12)
label.textColor = ColorCodes.darkGray
label.textAlignment = .right
label.font = UIFont(name: "HelveticaNeue-CondensedBold", size: 20)
return label
}()
var valueHomeTeam: Int = 1
var homeTeamValue: HomeTeamValue? {
didSet {
homeTeamStatistic.text = homeTeamValue?.value.description
valueHomeTeam = (homeTeamValue?.value)!
print(valueHomeTeam)
}
}
let awayTeamStatistic: UILabel = {
let label = UILabel()
label.text = String(2)
label.textColor = ColorCodes.darkGray
label.textAlignment = .left
label.font = UIFont(name: "HelveticaNeue-CondensedBold", size: 20)
return label
}()
var valueAwayTeam: Int = 1
var awayTeamValue: AwayTeamValue? {
didSet {
awayTeamStatistic.text = awayTeamValue?.value.description
valueAwayTeam = (awayTeamValue?.value)!
print(valueAwayTeam)
}
}
var homeTeamStatisticBar: UIView = {
let view = UIView()
view.backgroundColor = UIColor.lightGray
return view
}()
var awayTeamStatisticBar: UIView = {
let view = UIView()
view.backgroundColor = UIColor.darkGray
return view
}()
override func setupCell() {
super.setupCell()
backgroundColor = .white
addSubview(statisticTitleLabel)
addSubview(homeTeamStatistic)
addSubview(awayTeamStatistic)
addSubview(homeTeamStatisticBar)
addSubview(awayTeamStatisticBar)
let statisticValueSum = valueHomeTeam + valueAwayTeam
print(statisticValueSum)
let barWidthHome = CGFloat((Int(pitchWidth! / 2) - 40) * valueHomeTeam / statisticValueSum)
let barWidthAway = CGFloat((Int(pitchWidth! / 2) - 40) * valueAwayTeam / statisticValueSum)
let barCenter = pitchWidth! / 2
statisticTitleLabel.anchor(top: nil, left: leftAnchor, bottom: bottomAnchor, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 4, paddingRight: 0, width: 0, height: 0)
addConstraint(NSLayoutConstraint(item: statisticTitleLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0))
homeTeamStatisticBar.anchor(top: topAnchor, left: nil, bottom: nil, right: rightAnchor, paddingTop: 4, paddingLeft: 0, paddingBottom: 0, paddingRight: barCenter, width: barWidthHome, height: 16)
awayTeamStatisticBar.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 4, paddingLeft: barCenter, paddingBottom: 0, paddingRight: 0, width: barWidthAway, height: 16)
homeTeamStatistic.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 20, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
awayTeamStatistic.anchor(top: topAnchor, left: nil, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 20, width: 0, height: 0)
}
}
Statistic Button - TimerBar.swift
var homeGoals: Int = 0 {
didSet {
GameStatistics().collectionView.reloadData()
}
}
var awayGoals: Int = 0 {
didSet {
GameStatistics().collectionView.reloadData()
}
}
class TimerBar: UIView {
[...] //more Code
let homeGoalsLabel: UILabel = {
let label = UILabel()
label.text = String(homeGoals)
label.textColor = UIColor.white
label.textAlignment = .right
label.font = UIFont(name: "HelveticaNeue-CondensedBold", size: 34)
return label
}()
let awayGoalsLabel: UILabel = {
let label = UILabel()
label.text = String(awayGoals)
label.textColor = UIColor.white
label.textAlignment = .left
label.font = UIFont(name: "HelveticaNeue-CondensedBold", size: 34)
return label
}()
[...] //more Code
//Handle Menu Buttons
let changeLineUp = ChangeLineUp()
var delegate: LineUpDelegate?
var pitchLayout: String = "Test"
#objc func lineUpButtonTapped() {
changeLineUp.showLineUps()
changeLineUp.delegate = self
}
let gameStatistics = GameStatistics()
#objc func statButtonTapped() {
gameStatistics.showStatistics()
}
#objc func homeTeamButtonTapped(_ sender:UIButton!) {
homeGoals = homeGoals + 1
homeGoalsLabel.text = String(homeGoals)
}
#objc func awayTeamButtonTapped(_ sender:UIButton!) {
awayGoals = awayGoals + 1
awayGoalsLabel.text = String(awayGoals)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
...
Main Pitch View - PitchViewController.swift
import UIKit
let lineup7_321: UICollectionViewLayout = LineUp7_3_2_1()
public var pitchCollectionView: UICollectionView? = {
var layout: UICollectionViewLayout = lineup7_321
let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
//cv.dataSource = self
//cv.delegate = self
return cv
}()
class PitchViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
let cellId1 = "PlayersCell"
let cellId2 = "SubstituteCell"
let timerBar: TimerBar = {
let tb = TimerBar()
return tb
}()
//Just for testing
let sections: [String] = ["Players", "Substitutes"]
let players: [String] = ["player1", "player2", "player3", "player4", "player5", "player6", "player7"]
let substitutes: [String] = ["player8", "player9", "player10", "player12", "player13"]
var sectionData: [Int: [String]] = [:]
//Swap Players
var alwaysSwapWithOrigin: Bool!
var placementTimer: DispatchSourceTimer!
var longPress: UILongPressGestureRecognizer!
var movingPlayer: (origin:IndexPath?,lifted:IndexPath?,placement:IndexPath?,previous:IndexPath?)
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.titleView = UIImageView(image: #imageLiteral(resourceName: "overtime"))
navigationController?.navigationBar.isTranslucent = false
navigationController?.navigationBar.tintColor = UIColor.white
setupTimerBar()
setupPitchCollectionView()
setupSwapPlayers()
}
func setupTimerBar() {
view.addSubview(timerBar)
timerBar.anchor(top: view.safeAreaLayoutGuide.topAnchor, left: view.leftAnchor, bottom: nil, right: view.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 135)
}
func setupPitchCollectionView() {
pitchCollectionView?.register(PlayersCell.self, forCellWithReuseIdentifier: cellId1)
pitchCollectionView?.register(SubstituteCell.self, forCellWithReuseIdentifier: cellId2)
pitchCollectionView?.delegate = self
pitchCollectionView?.dataSource = self
pitchCollectionView?.isScrollEnabled = false
view.addSubview(pitchCollectionView!)
pitchCollectionView?.backgroundColor = ColorCodes.lightGreen
pitchCollectionView?.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor, paddingTop: 135, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
sectionData = [0: players, 1: substitutes]
}
func setupSwapPlayers() {
alwaysSwapWithOrigin = true
longPress = UILongPressGestureRecognizer(target: self, action:#selector(swapPlayersCells))
longPress.minimumPressDuration = 0.20
pitchCollectionView?.addGestureRecognizer(longPress)
let queue = DispatchQueue(label: "com.overtime")
placementTimer = DispatchSource.makeTimerSource(flags: [],queue:queue)
placementTimer.schedule(deadline: .now(), repeating:.milliseconds(250))
placementTimer.setEventHandler(handler: playersPositionUpdate)
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return sections.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return (sectionData[section]?.count)!
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch indexPath.section {
case 0:
let playerCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId1, for: indexPath) as! PlayersCell
playerCell.playerImage.image = UIImage(named: self.players[indexPath.row])
playerCell.playerName.text = self.players[indexPath.row].capitalized
return playerCell
case 1:
let substituteCell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId2, for: indexPath) as! SubstituteCell
substituteCell.substituteImage.image = UIImage(named: self.substitutes[indexPath.row])
substituteCell.substituteName.text = self.substitutes[indexPath.row].capitalized
return substituteCell
default:
fatalError("Error")
}
}
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
// required for interactive movement
}
func collectionView(_ collectionView: UICollectionView, targetIndexPathForMoveFromItemAt originalIndexPath: IndexPath, toProposedIndexPath proposedIndexPath: IndexPath) -> IndexPath {
// return the index path of selected to prevent other cells reshuffling whilst moving cell around
return movingPlayer.lifted!
}
}
I didn't see any declaration for Home/Away values, this is a sample I hope you can get the idea from it
private var homeGoals : Int = 0 {
didSet {
collectionView.reloadData()
}
}
private var awayGoals : Int = 0 {
didSet {
collectionView.reloadData()
}
}
#objc func homeTeamButtonTapped(_ sender: UIButton) {
homeGoals = homeGoals + 1
}
As you can see here any new value for homeGoals variable collectionView will be reloaded immediately and you have to use in your cell

Resources