0

Collection View コードを処理するこの TatodexController があります。API 呼び出しからデータを取得し、ポケモン変数に保存します。この var は、すべてのポケモンのすべての属性 (名前、身長、能力など) を保持する Pokemon 構造体でデコードされます。

私の CollectionView では、画像、名前、その他の poke 関連の情報を表示できますが、次のように機能する機能を追加しました。

  • ポケモン セルを長押しすると、情報ビューが表示され、ポケモン情報のチャンクが表示されるはずですが、TatodexController から更新されたデータを取得していません。

これは、私の TatodexController の関連コードがどのように見えるかです:

class TatodexController: UICollectionViewController, InfoViewDelegate {

var pokemon: Pokemon?
var pokemons = [Pokemon]()
let service = Service()
    . . .

let infoView: InfoView = {
    let view = InfoView()
    view.layer.cornerRadius = 5
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()
    fetchPokemons()
}

. . .

@objc func handleDismissal() {
    dismissInfoView(pokemon: nil)
}
}

解析と一部の InfoView 構成を処理する拡張機能は次のとおりです。

extension TatodexController {

. . .

func dismissInfoView(pokemon: Pokemon?) {
    UIView.animate(withDuration: 0.5, animations: {
        self.visualEffectView.alpha = 0
        self.infoView.alpha = 0
        self.infoView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
    }) { (_) in
        self.infoView.removeFromSuperview()
        self.navigationItem.rightBarButtonItem?.isEnabled = true
        guard let pokemon = pokemon else { return }
        self.showInfoController(withPoke: pokemon)
    }
}

func fetchPokemons() {
    service.fetchPokes { (result) in
        DispatchQueue.main.async {
            
            switch result {
            case .success(let poke):
                self.pokemon = poke
                self.pokemons.append(poke)
                self.collectionView.reloadData()
                
                self.pokemons.sort { (poke1, poke2) -> Bool in
                    return poke1.name! < poke2.name!
                    
                }
            case .failure(let error):
                
                let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: .alert)
                 alert.addAction(UIAlertAction(title: "Dismiss", style: .default, handler: nil))
                 self.show(alert, sender: nil)
            }
            
        }
    }
}
}

そして、私の InfoViewDelegate を構成する拡張機能は次のとおりです。

    extension TatodexController: TatodexCellDelegate {
    
    func presentInfoView(withPokemon pokemon: Pokemon) {

        configureSearchBar(showSearch: false)
        navigationItem.rightBarButtonItem?.isEnabled = false

        view.addSubview(infoView)
        infoView.configureViewComponents()
        infoView.delegate = self
        infoView.pokemon = self.pokemon
        configureInfoView()
    }
    
    func configureInfoView() {
        
        infoView.anchor(top: nil, left: nil, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: view.frame.width - 64, height: 480)
        infoView.layer.cornerRadius = view.frame.width / 6
        infoView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        infoView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -40).isActive = true
        
        infoView.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        infoView.alpha = 0
        
        UIView.animate(withDuration: 0.3) {
            self.visualEffectView.alpha = 1
            self.infoView.alpha = 1
            self.infoView.transform = .identity
        }
        
    }
}

私の InfoView クラスの関連コードは次のとおりです。

    protocol InfoViewDelegate {
    func dismissInfoView(pokemon: Pokemon?)
}

class InfoView: UIView {
    
    var delegate: InfoViewDelegate?
    var pokemon: Pokemon? {
        didSet {
                guard let pokemon   = self.pokemon,
                      let type      = pokemon.types,
                      let typeName  = type[0].type?.name,
                      let defense   = pokemon.defense,
                      let attack    = pokemon.attack,
                      let id        = pokemon.id,
                      let height    = pokemon.height,
                      let weight    = pokemon.weight,
                      let imageUrl  = pokemon.sprites?.front else { return }
                    
                if id == pokemon.id {
                    imageView.kf.setImage(with: URL(string: imageUrl))
                }

                nameLabel.text = pokemon.name?.capitalized
                
                configureLabel(label: typeLabel,      title: "Type",        details: "\(typeName)")
                configureLabel(label: defenseLabel,   title: "Defense",     details: "\(defense)")
                configureLabel(label: attackLabel,    title: "Base Attack", details: "\(attack)")
                configureLabel(label: heightLabel,    title: "Height",      details: "\(height)")
                configureLabel(label: weightLabel,    title: "Weight",      details: "\(weight)")
                configureLabel(label: pokedexIdLabel, title: "Pokedex Id",  details: "\(id)")
        }
    }
    
    let skillLabel: UILabel = {
        let label = UILabel()
        return label
    }()
    
    let imageView: UIImageView = {
        let iv = UIImageView()
        iv.contentMode = .scaleAspectFill
        return iv
    }()
    
    lazy var nameContainerView: UIView = {
        let view = UIView()
        view.backgroundColor = Colors.softRed
        view.addSubview(nameLabel)
        view.layer.cornerRadius = 5
        nameLabel.center(inView: view)
        return view
    }()
    
    let nameLabel: UILabel = {
        let label = UILabel()
        label.textColor = .white
        label.font = UIFont.systemFont(ofSize: 24, weight: .thin)
        label.text = "Lucario"
        return label
    }()
    
    . . .

    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    @objc func handleViewMoreInfo() {
        guard let pokemon = self.pokemon else { return }
        delegate?.dismissInfoView(pokemon: pokemon)
    }

    . . .
}

そしてもちろん、このコードの最後のチャンクでは、データを取得していません。TatodexController のポケモン情報を InfoView に接続していないためだと思いますが、その方法はわかりません。たとえば、ポケモンのセルを長押しすると、InfoView が表示され、実際のポケモンの名前ではなく、「ルカリオ」(私のデフォルト値) と表示されます。

助けやアドバイスをいただければ幸いです。別のコードを確認する必要がある場合は、喜んでこの投稿を更新します。

編集 1: TatodexCell での handleLongPress 関数

    @objc func handleLongPress(sender: UILongPressGestureRecognizer) {
    if sender.state == .began {
        guard let poke = self.pokemon else { return }
        delegate?.presentInfoView(withPokemon: poke)
    }
}
4

0 に答える 0