值更改后的CollectionView reloaddata()

时间:2018-09-05 16:00:47

标签: arrays swift uicollectionview nsobject reloaddata

在更改数组中的值后,我无法更新CollectionView。我对问题做了简短的gif

如您所见,我可以在我的足球应用中为两个球队添加目标。当我第一次按下游戏统计按钮时,从底部滑入的统计视图中的结果(例如2:1)是正确的。但是随着比赛的进行和主队再得分,统计数据不会改变。

我尝试了几种方法来调用reloaddata()来更新我的collectionView,但到目前为止没有成功。因此,希望有人可以让我走上正确的轨道。

非常感谢您。

GameStatistics视图控制器-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)            
    }
}

统计按钮-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")
}

...

主音高视图-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!
    }
}

1 个答案:

答案 0 :(得分:1)

我没有看到任何关于Home / Away值的声明,这是一个示例,希望您能从中得到启发

private var homeGoals : Int = 0 {
    didSet {
        collectionView.reloadData()
    }
}

private var awayGoals : Int = 0 {
    didSet {
        collectionView.reloadData()
    }
}

@objc func homeTeamButtonTapped(_ sender: UIButton) {    
    homeGoals = homeGoals + 1
}

如您所见,homeGoals变量collectionView的任何新值将立即重新加载,您必须在单元格中使用