Swift Tambahkan tindakan berbeda ke sel di UICollectionView

Saya tidak tahu harus mulai dari mana, saya memiliki UICollectionView dengan banyak sel yang diisi dengan UIImage. Saya ingin setiap sel/UIImage melakukan tindakan berbeda dengan satu ketukan jari. Dapatkah seseorang mengarahkan saya ke arah yang benar di sini?

Tindakan yang saya miliki adalah @IBAction dari UIButton, saya tahu ingin melakukan tindakan itu pada sel di UICollectionView..

(Saya kira saya harus melakukan sesuatu dengan 'let cell = countryCollectionView.dequeueReusableCell'?

import UIKit

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {

    @IBOutlet weak var soundsCollectionView: UICollectionView!
    
    lazy var cv: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    layout.scrollDirection = .vertical
        
    var cc = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cc.translatesAutoresizingMaskIntoConstraints = false
    cc.register(CustomCell.self, forCellWithReuseIdentifier: "CustomCell")
    cc.delegate = self
    cc.dataSource = self
    cc.backgroundColor = .white
    return cc
    }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
            
            view.addSubview(cv)
            cv.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
            cv.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
            cv.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            cv.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            
        }
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.tag = indexPath.row
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: 100)
    }
    
}

class CustomCell: UICollectionViewCell {
    
    lazy var centerImageView: UIImageView = {
        var img = UIImageView()
        img.translatesAutoresizingMaskIntoConstraints = false
        img.image = UIImage(named: "1")
        img.clipsToBounds = true
        img.isUserInteractionEnabled = true
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handler(_:)))
        tapGesture.numberOfTapsRequired = 1
        
        img.addGestureRecognizer(tapGesture)
        
        return img
    }()
    
    @objc private func handler(_ sender: UITapGestureRecognizer) {
        print("tapped tag > ", self.tag)
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        addSubview(centerImageView)
        centerImageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        centerImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        centerImageView.heightAnchor.constraint(equalToConstant: 80).isActive = true
        centerImageView.widthAnchor.constraint(equalToConstant: 80).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

person DeDe Schurk    schedule 11.07.2020    source sumber
comment
hei Dede apakah itu berhasil untukmu?   -  person eemrah    schedule 12.07.2020
comment
Hai elia, terima kasih atas balasan Anda! Saya sedikit kesulitan. Saya telah memperbarui metode 'cellForItemAt' dan menambahkan ini ke soundCell.swift saya (kelas UICollectionViewCell?) @IBAction func sound1(_ sender: UIButton) { if (self.tag == 0) { // I am first cell, so act like this. } else if (self.tag == 1) { // Second cell blah blah } } Namun bagaimana cara mengonfigurasi setiap sel secara berbeda untuk melakukan sesuatu dengan satu ketukan jari? Misalnya gambar1: cetak (saya tombol 1) Dan gambar2: cetak (saya tombol 2) Sekali lagi, terima kasih atas waktunya! Sangat menghargai   -  person DeDe Schurk    schedule 13.07.2020
comment
hei lagi, gunakan UITapGestureRecognizer untuk UIImageView di UICollectionViewCell. Dalam gerakan ketuk #action fungsi centang self.tag sehingga Anda dapat mengatasinya jika tag == 0 jadi ini adalah gambar sel pertama. dan jika tag == 3 ini adalah 4. sel. Apakah kamu keberatan?   -  person eemrah    schedule 13.07.2020
comment
Yah, setelah mencoba memahami apa yang Anda maksud selama 48 jam terakhir, saya benar-benar mencoba membuatnya berfungsi dan melakukan penelitian sendiri sebelum mengajukan pertanyaan bodoh di sini :P. Saya menambahkan let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped)) tap.numberOfTapsRequired = 2 view.addGestureRecognizer(tap) ini di ViewController saya (viewDidLoad). Dan @objc func doubleTapped() { // do something here } Tapi saya tidak mengerti apa yang Anda maksud dengan self.tag.. Apakah saya berada di jalur yang benar dengan kode di atas? Sekali lagi terima kasih Elia!   -  person DeDe Schurk    schedule 15.07.2020
comment
hai @Dede, Anda dapat menetapkan UICollectionViewCell ke tag dan tag ini membantu Anda sel mana yang merupakan elemen mana di dalam UICollectionViewCell. Saya mengedit jawaban saya sebagai contoh untuk Anda   -  person eemrah    schedule 15.07.2020
comment
@elia , aku semakin dekat sekarang! :) Tapi, saat saya MENJALANKAN aplikasinya, layarnya putih semua. Namun ketika saya mengklik layar secara acak, saya melihat tag Tapped ›1 atau 2 dll. pada output konsol. Jadi ini berfungsi, tetapi saya tidak melihat gambarnya. Saya rasa saya menghapus sesuatu dari kode asli saya. Saya memperbarui kode saya pada posting pertama saya sehingga Anda dapat melihat apa yang saya dapatkan sekarang. Dapatkah Anda melihat apa yang hilang? Terima kasih lagi!! (Dan maaf atas balasan saya yang terlambat).   -  person DeDe Schurk    schedule 20.07.2020
comment
jika Anda menggunakan baris img.image = UIImage(named: "1") untuk kodenya, baris ini mengatakan Anda harus memiliki gambar dengan nama 1 . jadi mungkin Anda harus menggunakan imageNames Anda sendiri?   -  person eemrah    schedule 20.07.2020
comment
@elia Tentu saja .. berhasil ..! Tapi.. Bagaimana cara mengkonfigurasi beberapa gambar? Katakanlah saya memiliki 10 gambar berbeda.. :/   -  person DeDe Schurk    schedule 20.07.2020
comment
Asumsikan Anda memiliki array let imageArray = [UIImage(named:"first"),UIImage(named:"second"),UIImage(named:"third"),UIImage(named:"fourth")] dan dalam metode cellForRow Anda harus memanggil myCell.imageView.image = imageArray[indexPath.row] atau cara Anda menangani sel Anda. Sebagai contoh saya dalam jawaban ini seharusnya cell.centerImageView.image = imageArray[indexPath.row]. Anda harus mengetahui bahwa ``numberOfCount` harus sama dengan imageArray hitungan   -  person eemrah    schedule 20.07.2020
comment
@elia Saya mengerti, tapi cellForRow? aku tak punya..? Maksudnya cellForItemAt ?   -  person DeDe Schurk    schedule 20.07.2020
comment
ya, maksud saya cellForItemAt metode :)   -  person eemrah    schedule 20.07.2020
comment
Hmmm, mendapatkan nilai Tidak dapat menetapkan tipe 'String' untuk mengetik 'UIImage' func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell cell.centerImageView.image = countries[indexPath.row] cell.tag = indexPath.row return cell }   -  person DeDe Schurk    schedule 20.07.2020
comment
Mari kita melanjutkan diskusi ini dalam chat.   -  person eemrah    schedule 20.07.2020


Jawaban (2)


Saya mengedit sebagai contoh terprogram baru untuk solusi masalah Anda.

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    
    lazy var cv: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .vertical
        
        var cc = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cc.translatesAutoresizingMaskIntoConstraints = false
        cc.register(CustomCell.self, forCellWithReuseIdentifier: "CustomCell")
        cc.delegate = self
        cc.dataSource = self
        cc.backgroundColor = .white
        return cc
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.addSubview(cv)
        cv.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        cv.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        cv.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        cv.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }
    
    
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 10
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.tag = indexPath.row
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: 100)
    }
    
    
}


class CustomCell: UICollectionViewCell {
    
    lazy var centerImageView: UIImageView = {
        var img = UIImageView()
        img.translatesAutoresizingMaskIntoConstraints = false
        img.image = UIImage(named: "1")
        img.clipsToBounds = true
        img.isUserInteractionEnabled = true
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handler(_:)))
        tapGesture.numberOfTapsRequired = 1
        
        img.addGestureRecognizer(tapGesture)
        
        return img
    }()
    
    @objc private func handler(_ sender: UITapGestureRecognizer) {
        print("tapped tag > ", self.tag)
    }
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        
        
        addSubview(centerImageView)
        centerImageView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        centerImageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
        centerImageView.heightAnchor.constraint(equalToConstant: 80).isActive = true
        centerImageView.widthAnchor.constraint(equalToConstant: 80).isActive = true
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
person eemrah    schedule 11.07.2020
comment
hai @DeDeSchurk apakah kamu membuatnya? - person eemrah; 13.07.2020

Dalam skenario ini, saya akan menghindari penggunaan tombol pada sel Anda. Sebagai gantinya, Anda harus menghubungkan ke metode delegasididSelectItemAt dan cukup tambahkan yang diperlukan informasi ke dalam model data:

struct Country {
    let imageName: String
    let sound: Sound // You didn't specify what type the sound1 object is but you get the gist
}

Jadi array negara Anda sekarang akan berisi struct baru ini, bukan hanya String mentah:

let countries = [
    Country("country1", sound1),
    Country("country2", sound2),
    ...
]

Kemudian Anda bisa mendapatkan suara persis yang ingin Anda putar dari indexPath yang diteruskan ke didSelectItemAt:

let sound = self.countries[indexPath.row].sound
sound.play()

Anda juga harus menyesuaikan cara Anda mengatur gambar sel di cellForItemAt:

let imageName = self.countries[indexPath.row].imageName
cell.countryImageView.image = UIImage(named: imageName)
person WongWray    schedule 15.07.2020