Swift เพิ่มการกระทำต่าง ๆ ให้กับเซลล์บน UICollectionView

ฉันไม่รู้ว่าจะเริ่มจากตรงไหน ฉันมี UICollectionView ที่มีหลายเซลล์ที่เต็มไปด้วย UIImage ฉันต้องการให้แต่ละเซลล์/UIImage ดำเนินการ แตกต่าง เพียงปลายนิ้วสัมผัส ใครสามารถระบุฉันในทิศทางที่ถูกต้องที่นี่?

การกระทำที่ฉันมีคือ @IBAction จาก UIButton ฉันรู้ว่าต้องการให้มีการกระทำนั้นในเซลล์ใน UICollectionView ..

( ฉันคิดว่าฉันต้องทำอะไรบางอย่างกับ '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 แหล่งที่มา
comment
เฮ้ เดเด มันได้ผลสำหรับคุณไหม?   -  person eemrah    schedule 12.07.2020
comment
สวัสดีเอเลีย ขอบคุณสำหรับคำตอบของคุณ! ฉันกำลังดิ้นรนเล็กน้อย ฉันได้อัปเดตเมธอด 'cellForItemAt' และเพิ่มสิ่งนี้ลงใน soundCell.swift ของฉัน (คลาส 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 } } แต่ฉันจะกำหนดค่าแต่ละเซลล์ให้แตกต่างกันเพื่อทำอะไรบางอย่างด้วยการแตะนิ้วได้อย่างไร ตัวอย่างเช่น image1: พิมพ์ (ฉันเป็นปุ่ม 1) และ image2: พิมพ์ (ฉันเป็นปุ่ม 2) อีกครั้ง ขอขอบคุณที่สละเวลา! ชื่นชมมาก   -  person DeDe Schurk    schedule 13.07.2020
comment
สวัสดีอีกครั้ง ใช้ UITapGestureRecognizer สำหรับ UIImageView ใน UICollectionViewCell ในการแตะฟังก์ชัน #action ให้ตรวจสอบฟังก์ชัน self.tag เพื่อให้คุณสามารถจัดการได้ว่าหาก tag == 0 นี่คือภาพของเซลล์แรก และถ้า tag == 3 นี่คือ 4. เซลล์ คุณสนใจไหม?   -  person eemrah    schedule 13.07.2020
comment
ฉันพยายามที่จะเข้าใจสิ่งที่คุณหมายถึงในช่วง 48 ชั่วโมงที่ผ่านมา ฉันพยายามทำให้มันได้ผลจริงๆ และค้นคว้าข้อมูลของตัวเองก่อนที่จะถามคำถามโง่ๆ ที่นี่ :P ฉันเพิ่ม let tap = UITapGestureRecognizer(target: self, action: #selector(doubleTapped)) tap.numberOfTapsRequired = 2 view.addGestureRecognizer(tap) นี้ใน ViewController ของฉัน (viewDidLoad) และ @objc func doubleTapped() { // do something here } แต่ฉันไม่เข้าใจสิ่งที่คุณหมายถึงด้วย self.tag.. ฉันมาถูกทางแล้วกับโค้ดข้างต้นหรือไม่ ขอบคุณอีกครั้งเอเลีย!   -  person DeDe Schurk    schedule 15.07.2020
comment
เฮ้ @Dede คุณสามารถกำหนด UICollectionViewCell ให้กับแท็กได้ และแท็กนี้จะช่วยคุณว่าเซลล์ใดคือองค์ประกอบใดที่อยู่ด้านในของ UICollectionViewCell ฉันแก้ไขคำตอบของฉันเป็นตัวอย่างสำหรับคุณ   -  person eemrah    schedule 15.07.2020
comment
@elia ตอนนี้ฉันใกล้จะถึงแล้ว! :) แต่เมื่อฉันเรียกใช้แอปนี้ หน้าจอจะเป็นสีขาวทั้งหมด แต่เมื่อฉันสุ่มคลิกบนหน้าจอ ฉันเห็นแท็ก Tapped > 1 หรือ 2 ฯลฯ บนเอาต์พุตคอนโซล มันใช้งานได้ แต่ฉันไม่เห็นภาพ ฉันคิดว่าฉันได้ลบโค้ดต้นฉบับของฉันไปบางส่วนแล้ว ฉันอัปเดตโค้ดของฉันในโพสต์แรกเพื่อให้คุณเห็นว่าฉันมีอะไรบ้างตอนนี้ คุณเห็นสิ่งที่หายไปไหม? ขอบคุณอีกครั้ง!! (และขออภัยที่ตอบช้าค่ะ)   -  person DeDe Schurk    schedule 20.07.2020
comment
หากคุณใช้ img.image = UIImage(named: "1") บรรทัดสำหรับโค้ด บรรทัดนี้จะบอกว่าคุณต้องมีรูปภาพชื่อ 1 ดังนั้นคุณต้องใช้ imageNames ของคุณเองใช่ไหม?   -  person eemrah    schedule 20.07.2020
comment
@elia แน่นอน .. มันได้ผล.. ! แต่.. ฉันจะกำหนดค่าภาพหลายภาพได้อย่างไร? สมมติว่าฉันมี 10 ภาพที่แตกต่างกัน.. :/   -  person DeDe Schurk    schedule 20.07.2020
comment
สมมติว่าคุณมีอาร์เรย์ let imageArray = [UIImage(named:"first"),UIImage(named:"second"),UIImage(named:"third"),UIImage(named:"fourth")] และในเมธอด cellForRow คุณต้องเรียก myCell.imageView.image = imageArray[indexPath.row] หรือวิธีจัดการเซลล์ของคุณ สำหรับตัวอย่างของฉันในคำตอบนี้ควรเป็น cell.centerImageView.image = imageArray[indexPath.row] คุณต้องหาว่า ``numberOfCount` จะต้องเท่ากับ imageArray count   -  person eemrah    schedule 20.07.2020
comment
@elia ฉันเข้าใจแล้ว แต่ cellForRow ? ฉันไม่มี..? คุณหมายถึง cellForItemAt ใช่ไหม?   -  person DeDe Schurk    schedule 20.07.2020
comment
ใช่ ฉันหมายถึงวิธี cellForItemAt :)   -  person eemrah    schedule 20.07.2020
comment
อืม กำลังรับค่า ไม่สามารถกำหนดค่าประเภท 'String' ให้พิมพ์ '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
ให้เราสนทนาต่อในการแชท   -  person eemrah    schedule 20.07.2020


คำตอบ (2)


ฉันแก้ไขเป็นตัวอย่างใหม่สำหรับการแก้ปัญหาของคุณโดยทางโปรแกรม

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
เฮ้ @DeDeSchurk คุณสร้างมันขึ้นมาเหรอ? - person eemrah; 13.07.2020

ในสถานการณ์นี้ ฉันจะหลีกเลี่ยงการใช้ปุ่มบนเซลล์ของคุณ คุณควรใช้ didSelectItemAt delegate method แทน และเพียงเพิ่มที่จำเป็น ข้อมูลเข้าสู่แบบจำลองข้อมูล:

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

ดังนั้นอาเรย์ประเทศของคุณจะมีโครงสร้างใหม่นี้แทนที่จะเป็นเพียงสตริงดิบ:

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

จากนั้นคุณจะได้เสียงที่แน่นอนที่คุณต้องการเล่นจาก indexPath ที่ส่งผ่านไปยัง DidSelectItemAt:

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

คุณจะต้องปรับวิธีการตั้งค่ารูปภาพของเซลล์ใน cellForItemAt:

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