CollectionView reloaddata() after value change - arrays
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
Related
append all textfields in tableview cells to array
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!) }
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 }
how to change the size of a uiimageview appended to a empty array
My swift code uses a button to place imageviews on a uiviewcontroller that parent from a empty array. The problem is I dont know how to effect the size of the invidicual imageview after it is placed on the uiview controller. When a imageview is click and then when the slider is moved the imageview should change size. However what is happening is the value when the slider is changed effects the next iamgeview that is placed on the uiviewcontroller. Pitcure below is included I circled what the slider should effect. This is a video of what I am trying to do https://www.youtube.com/watch?v=ho6ID6XVEYw&feature=youtu.be. import UIKit class ViewController: UIViewController { var sx = UISlider() var count: Int = 0 var ht = -90 var ww = 80 var arrTextFields = [UIImageView]() var b7 = UIButton() override func viewDidLoad() { super.viewDidLoad() [b7,sx].forEach { $0.translatesAutoresizingMaskIntoConstraints = false view.addSubview($0) $0.backgroundColor = .systemOrange } b7.frame = CGRect(x: view.center.x-115, y: view.center.y + 200, width: 70, height: 40) sx.frame = CGRect(x: view.center.x-115, y: view.center.y-200, width: 70, height: 40) b7.addTarget(self, action: #selector(addBOx), for: .touchUpInside) } //func that adds imageview. #objc func addBOx() { let subview = UIImageView() subview.isUserInteractionEnabled = true arrTextFields.append(subview) view.addSubview(subview) sx.addTarget(self, action: #selector(ji), for: .valueChanged) sx.minimumValue = 10 sx.maximumValue = 150 subview.frame = CGRect(x: view.bounds.midX - 0, y: view.bounds.midY + CGFloat(ht), width: CGFloat(ww), height: 35) subview.backgroundColor = .purple subview.tag = count let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:))) subview.addGestureRecognizer(pan) count += 1 ht += 50 arrTextFields.append(subview) } #objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) { let draggedView = gesture.view! view.bringSubviewToFront(draggedView) let translation = gesture.translation(in: view) draggedView.center = CGPoint(x: draggedView.center.x + translation.x, y: draggedView.center.y + translation.y) gesture.setTranslation(.zero, in: view) } #objc func ji(sender : UISlider){ ww = Int(sx.value) }}
The main idea that needs to be implemented is to add the currentView variable to find out which view we want to change. We also need to add some functionality to select the specific view that needs to be changed. 1) Add variable currentView class ViewController: UIViewController { ... var currentView: UIView? override func viewDidLoad() { super.viewDidLoad() 2) Add tapGestureRecognozer to func addBOx() #objc func addBOx() { ... let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:))) subview.addGestureRecognizer(tapGesture) } 3) Add handleTapGestured(_:) #objc func handleTapGestured(_ gesture: UIPanGestureRecognizer) { currentView = gesture.view } 4) Update func ji(sender: UISlider) #objc func ji(sender: UISlider) { ... currentView?.bounds.size.width = CGFloat(sx.value) } All code: import UIKit class ViewController: UIViewController { var sx = UISlider() var count: Int = 0 var ht = -90 var ww = 80 var arrTextFields = [UIImageView]() var b7 = UIButton() var currentView: UIView? override func viewDidLoad() { super.viewDidLoad() [b7,sx].forEach { $0.translatesAutoresizingMaskIntoConstraints = false view.addSubview($0) $0.backgroundColor = .systemOrange } b7.frame = CGRect(x: view.center.x-115, y: view.center.y + 200, width: 70, height: 40) sx.frame = CGRect(x: view.center.x-115, y: view.center.y-200, width: 70, height: 40) b7.addTarget(self, action: #selector(addBOx), for: .touchUpInside) } //func that adds imageview. #objc func addBOx() { let subview = UIImageView() subview.isUserInteractionEnabled = true arrTextFields.append(subview) view.addSubview(subview) sx.addTarget(self, action: #selector(ji), for: .valueChanged) sx.minimumValue = 10 sx.maximumValue = 150 subview.frame = CGRect(x: view.bounds.midX - 0, y: view.bounds.midY + CGFloat(ht), width: CGFloat(ww), height: 35) subview.backgroundColor = .purple subview.tag = count let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGestured(_:))) subview.addGestureRecognizer(pan) count += 1 ht += 50 arrTextFields.append(subview) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTapGestured(_:))) subview.addGestureRecognizer(tapGesture) } #objc func handleTapGestured(_ gesture: UIPanGestureRecognizer) { currentView = gesture.view } #objc func handlePanGestured(_ gesture: UIPanGestureRecognizer) { let draggedView = gesture.view! view.bringSubviewToFront(draggedView) let translation = gesture.translation(in: view) draggedView.center = CGPoint(x: draggedView.center.x + translation.x, y: draggedView.center.y + translation.y) gesture.setTranslation(.zero, in: view) } #objc func ji(sender : UISlider){ ww = Int(sx.value) currentView?.bounds.size.width = CGFloat(sx.value) } } Alternatively, you can add a textField and write the number that the element from your array needs to change. And please, don't use variables like sx, ht, ww, b7 in your code. You can read API Design Guidelines here
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") } }