首页 > 解决方案 > creating a new image in a collection view based off of user input

问题描述

right now I have a collection view that displays a certain number of trophies.

import UIKit

class TrophyViewController: UIViewController, UICollectionViewDelegate,  UICollectionViewDataSource {

    let trophies = ["1", "2", "3"]

    fileprivate let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        layout.scrollDirection = .vertical
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.register(CutomCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    } ()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(collectionView)
        collectionView.backgroundColor = .white
        collectionView.topAnchor.constraint(equalTo: view.topAnchor, constant:  40).isActive = true
        collectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 40).isActive = true
        collectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant:  -40).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant:  -40).isActive = true

        collectionView.delegate = self
        collectionView.dataSource = self

    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: collectionView.frame.width/2.5, height: collectionView.frame.width/2)
     }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return trophies.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CutomCell
        cell.backgroundColor = .white
        return cell
     }
}

class CutomCell: UICollectionViewCell {

    fileprivate let trophy: UIImageView = {
        let trophy = UIImageView()
        trophy.image = #imageLiteral(resourceName: "trophy")
        trophy.translatesAutoresizingMaskIntoConstraints = false
        trophy.contentMode = .scaleAspectFill
        trophy.clipsToBounds = true
        return trophy
    } ()

    override init(frame: CGRect) {
        super.init(frame: frame)

        contentView.addSubview(trophy)
        trophy.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        trophy.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        trophy.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        trophy.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

however, I want to make this collection view so that it displays trophies based off of when a goal is complete, the user will earn a new trophy. here is my progress bar.

    let shapeLayer = CAShapeLayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        //creates the path for the progress bar animation
        let trackLayer = CAShapeLayer()

        let circularPath = UIBezierPath(arcCenter: CGPoint(x: 200, y: 225), radius: 100, startAngle: -CGFloat.pi/2, endAngle: 2 * CGFloat.pi, clockwise: true)

            trackLayer.path = circularPath.cgPath
            trackLayer.lineWidth = 10
            trackLayer.strokeColor = UIColor.lightGray.cgColor
            trackLayer.fillColor = UIColor.clear.cgColor
            view.layer.addSublayer(trackLayer)

            shapeLayer.path = circularPath.cgPath
            shapeLayer.lineWidth = 10
            shapeLayer.strokeColor = UIColor.green.cgColor
            shapeLayer.fillColor = UIColor.clear.cgColor
            shapeLayer.strokeEnd = 0
            shapeLayer.lineCap = CAShapeLayerLineCap.round

            view.layer.addSublayer(shapeLayer)
     }

     //creates the progress bar animation and the progress bar
    func progressBarAnimation() {
        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
            self.increment += 0.16
            basicAnimation.toValue = self.increment
            basicAnimation.duration = 2
            basicAnimation.fillMode = CAMediaTimingFillMode.forwards
            basicAnimation.isRemovedOnCompletion = false
            shapeLayer.add(basicAnimation, forKey: "basic")
            self.countingIncrement += 20.0

            //increments the counting label
            countingLabel.count(from: 0, to: self.countingIncrement, withDuration: 2, andAnimation: .linear, andCounterType: .intType)

can I create a function that relies on an if statement when the user completes the goal to equal a new trophy in the collection view? if so, how would I create this function? or is there another way to solve this problem?

标签: iosswiftxcodeuicollectionview

解决方案


class Trophy {
    var isEarned = false
    var id = "a id"
}

class TrophyViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {

    let collectionView: UICollectionView
    let allTrophies = [Trophy]()//init it with all your trophies

    var earnedTrophies: [Trophy] {
        return allTrophies.filter{ $0.isEarned == true }
    }

    func userEarnTrophy(_ trophy: Trophy) {
        allTrophies.forEach{
            if $0.id == trophy.id {
                $0.isEarned = true
            }
        }
        collectionView.reloadData()
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        //or return allTrophies.count if you want to display a disable state for unearned ones
        return earnedTrophies.count
    }

}

推荐阅读