วิธีสร้างมุมมองคอลเลกชันอย่างง่ายด้วย Swift


182

UICollectionViewฉันพยายามที่จะเรียนรู้วิธีการใช้งาน เอกสารเป็นเพียงเล็กน้อยยากที่จะเข้าใจและแบบฝึกหัดที่ผมพบว่ามีทั้งในวัตถุประสงค์ C หรือโครงการที่มีความซับซ้อนยาว

เมื่อฉันได้เรียนรู้วิธีการใช้งานUITableView, เรา❤สวิฟท์ วิธีที่จะทำให้ tableview ง่ายๆกับ iOS 8 และสวิฟท์มีการตั้งค่าขั้นพื้นฐานมากและคำอธิบายที่จะได้รับฉันไป มีอะไรแบบนี้UICollectionViewมั้ย

คำตอบด้านล่างคือความพยายามของฉันในการเรียนรู้ที่จะทำ

คำตอบ:


501

โครงการนี้ได้รับการทดสอบด้วย Xcode 10 และ Swift 4.2

สร้างโครงการใหม่

มันสามารถเป็นเพียงแอปดูครั้งเดียว

เพิ่มรหัส

สร้างไฟล์ Cocoa Touch Class ใหม่ (ไฟล์> ใหม่> ไฟล์ ... > iOS> Cocoa Touch Class) MyCollectionViewCellชื่อมัน คลาสนี้จะเก็บช่องสำหรับมุมมองที่คุณเพิ่มลงในเซลล์ของคุณในกระดานเรื่องราว

import UIKit
class MyCollectionViewCell: UICollectionViewCell {
    
    @IBOutlet weak var myLabel: UILabel!
}

เราจะเชื่อมต่อร้านนี้ในภายหลัง

เปิด ViewController.swift และตรวจสอบให้แน่ใจว่าคุณมีเนื้อหาดังต่อไปนี้:

import UIKit
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
    
    let reuseIdentifier = "cell" // also enter this string as the cell identifier in the storyboard
    var items = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"]
    
    
    // MARK: - UICollectionViewDataSource protocol
    
    // tell the collection view how many cells to make
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return self.items.count
    }
    
    // make a cell for each cell index path
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        // get a reference to our storyboard cell
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath as IndexPath) as! MyCollectionViewCell
        
        // Use the outlet in our custom class to get a reference to the UILabel in the cell
        cell.myLabel.text = self.items[indexPath.item]
        cell.backgroundColor = UIColor.cyan // make cell more visible in our example project
        
        return cell
    }
    
    // MARK: - UICollectionViewDelegate protocol
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        // handle tap events
        print("You selected cell #\(indexPath.item)!")
    }
}

หมายเหตุ

  • UICollectionViewDataSourceและUICollectionViewDelegateเป็นโปรโตคอลที่มุมมองการเก็บรวบรวมเป็นไปตาม คุณสามารถเพิ่มUICollectionViewFlowLayoutโปรโตคอลเพื่อเปลี่ยนขนาดของมุมมองโดยทางโปรแกรม แต่ไม่จำเป็น
  • เราเพิ่งใส่สายธรรมดาในกริดของเรา แต่คุณสามารถทำรูปภาพได้ในภายหลัง

ตั้งค่ากระดานเรื่องราว

ลากมุมมองคอลเล็กชันไปที่ View Controller ในสตอรี่บอร์ดของคุณ คุณสามารถเพิ่มข้อ จำกัด เพื่อให้มันเติมมุมมองพาเรนต์ได้ถ้าต้องการ

ป้อนคำอธิบายรูปภาพที่นี่

ตรวจสอบให้แน่ใจว่าค่าเริ่มต้นของคุณในตัวตรวจสอบแอตทริบิวต์นั้น

  • รายการ: 1
  • เค้าโครง: การไหล

กล่องเล็ก ๆ ที่มุมบนซ้ายของมุมมองคอลเลกชันคือเซลล์มุมมองการสะสม เราจะใช้มันเป็นเซลล์ต้นแบบของเรา ลากฉลากไปที่เซลล์และจัดกึ่งกลาง คุณสามารถปรับขนาดเส้นขอบเซลล์และเพิ่มข้อ จำกัด เพื่อจัดกึ่งกลางของป้ายกำกับหากต้องการ

ป้อนคำอธิบายรูปภาพที่นี่

เขียน "เซลล์" (โดยไม่ใส่เครื่องหมายอัญประกาศ) ในกล่องตัวระบุของตัวตรวจสอบแอตทริบิวต์สำหรับเซลล์มุมมองการรวบรวม โปรดทราบว่านี่เป็นค่าเดียวกับlet reuseIdentifier = "cell"ใน ViewController.swift

ป้อนคำอธิบายรูปภาพที่นี่

และในตัวตรวจสอบตัวตนสำหรับเซลล์ตั้งชื่อคลาสเป็นคลาสที่MyCollectionViewCellกำหนดเองของเราที่เราทำ

ป้อนคำอธิบายรูปภาพที่นี่

ขอขึ้นร้าน

  • ตะขอฉลากในเซลล์การเก็บรวบรวมmyLabelในMyCollectionViewCellชั้นเรียน (คุณสามารถควบคุมลากได้)
  • เกี่ยวกับมุมมองคอลเลกชันdelegateและdataSourceตัวควบคุมมุมมอง (คลิกขวาที่มุมมองคอลเลกชันใน Document Outline จากนั้นคลิกและลากลูกศรบวกขึ้นไปที่ View Controller

ป้อนคำอธิบายรูปภาพที่นี่

เสร็จ

นี่คือสิ่งที่ดูเหมือนว่าหลังจากเพิ่มข้อ จำกัด ในการจัดกึ่งกลางของฉลากในเซลล์และตรึงมุมมองคอลเลกชันไว้ที่ผนังของผู้ปกครอง

ป้อนคำอธิบายรูปภาพที่นี่

การปรับปรุง

ตัวอย่างด้านบนใช้งานได้ แต่มันค่อนข้างน่าเกลียด นี่คือบางสิ่งที่คุณสามารถเล่นกับ:

สีพื้นหลัง

ใน Interface Builder ไปที่การเก็บมุมมอง> คุณสมบัติสารวัตร> ดู> ประวัติความเป็นมา

ระยะห่างระหว่างเซลล์

การเปลี่ยนระยะห่างต่ำสุดระหว่างเซลล์ให้มีค่าน้อยลงทำให้ดูดีขึ้น ในเครื่องมือสร้างส่วนติดต่อไปที่มุมมองคอลเล็กชันของคุณ> ตัวตรวจสอบขนาด> ระยะห่างขั้นต่ำและทำให้ค่ามีขนาดเล็กลง "สำหรับเซลล์" คือระยะทางแนวนอนและ "สำหรับเส้น" คือระยะทางแนวตั้ง

รูปร่างของเซลล์

หากคุณต้องการมุมโค้งมนเส้นขอบและสิ่งที่คล้ายกันคุณสามารถเล่นกับเซลล์layerได้ นี่คือตัวอย่างรหัส คุณจะใส่มันโดยตรงหลังจากcell.backgroundColor = UIColor.cyanในรหัสข้างต้น

cell.layer.borderColor = UIColor.black.cgColor
cell.layer.borderWidth = 1
cell.layer.cornerRadius = 8

ดูคำตอบนี้สำหรับสิ่งอื่น ๆ ที่คุณสามารถทำได้กับเลเยอร์ (ตัวอย่างเช่นเงา)

การเปลี่ยนสีเมื่อแตะ

มันทำให้ประสบการณ์ผู้ใช้ดีขึ้นเมื่อเซลล์ตอบสนองต่อการมองเห็นก๊อก วิธีหนึ่งในการบรรลุเป้าหมายนี้คือการเปลี่ยนสีพื้นหลังในขณะที่สัมผัสกับเซลล์ โดยเพิ่มสองวิธีต่อไปนี้ในViewControllerชั้นเรียนของคุณ:

// change background color when user touches cell
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.red
}

// change background color back when user releases touch
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.backgroundColor = UIColor.cyan
}

นี่คือรูปลักษณ์ที่อัปเดต:

ป้อนคำอธิบายรูปภาพที่นี่

การศึกษาเพิ่มเติม

รุ่น UITableView ของคำถาม & คำตอบนี้


1
ฉันได้รับ cell.myLabel เป็นศูนย์และหยุดทำงาน ความคิดใด ๆ ว่าทำไม? ฉันใช้เค้าโครงที่กำหนดเอง
เจอรัลด์

4
หากคุณไม่ได้ขอขึ้นเต้าเสียบโดยการควบคุมการลากจากฉลากในกระดานเพื่อที่@IBOutletสำหรับmyLabelในรหัสคุณจะได้รับความผิดพลาดเช่นนี้
Suragch

3
หากคุณใช้ตัวสร้างส่วนต่อประสานและอ้างอิงเซลล์โดยใช้เต้าเสียบอย่าลงทะเบียนคลาสเซลล์ที่กำหนดเองในคอนโทรลเลอร์ของคุณ ดูนี่
เจอรัลด์

1
ถ้า UICollectionViewCell self.collectionView.registerClass(MyCollectionViewCell.self, forCellWithReuseIdentifier: "Cell")เต้าเสียบเป็นศูนย์แล้วคุณจะต้องลบ หากคุณยังคงมีปัญหาการตรวจสอบสภาพอากาศreuseIdentifierเหมือนกันทั้งในdequeueReusableCellWithReuseIdentifierและในสตอรี่บอร์ด
Ashok R

40
ฉันหวังว่าเอกสารของ Apple นั้นอ่านง่ายเหมือนคำอธิบายนี้
elmarko

3

ผู้รับมอบสิทธิ์และแหล่งข้อมูลของ UICollectionView

//MARK: UICollectionViewDataSource

override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1     //return number of sections in collection view
}

override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10    //return number of rows in section
}

override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier("collectionCell", forIndexPath: indexPath)
    configureCell(cell, forItemAtIndexPath: indexPath)
    return cell      //return your cell
}

func configureCell(cell: UICollectionViewCell, forItemAtIndexPath: NSIndexPath) {
    cell.backgroundColor = UIColor.blackColor()


    //Customise your cell

}

override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    let view =  collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "collectionCell", forIndexPath: indexPath) as UICollectionReusableView
    return view
}

//MARK: UICollectionViewDelegate
override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
      // When user selects the cell
}

override func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
     // When user deselects the cell
}

3

สำหรับswift 4.2-

//MARK: UICollectionViewDataSource

func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
    return 1     //return number of sections in collection view
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10    //return number of rows in section
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionCell", for: indexPath as IndexPath)
    configureCell(cell: cell, forItemAtIndexPath: indexPath)
    return cell      //return your cell
}

func configureCell(cell: UICollectionViewCell, forItemAtIndexPath: NSIndexPath) {
    cell.backgroundColor = UIColor.black


    //Customise your cell

}

func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    let view =  collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "collectionCell", for: indexPath as IndexPath) as UICollectionReusableView
    return view
}

//MARK: UICollectionViewDelegate
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    // When user selects the cell
}

func collectionView(collectionView: UICollectionView, didDeselectItemAtIndexPath indexPath: NSIndexPath) {
    // When user deselects the cell
}

1

การใช้ UICollectionView ค่อนข้างน่าสนใจ คุณสามารถใช้ซอร์สโค้ดแบบง่ายและดูวิดีโอการสอนโดยใช้ลิงก์เหล่านี้:

https://github.com/Ady901/Demo02CollectionView.git

https://www.youtube.com/watch?v=5SrgvZF67Yw

extension ViewController : UICollectionViewDataSource {

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 2
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DummyCollectionCell", for: indexPath) as! DummyCollectionCell
        cell.titleLabel.text = nameArr[indexPath.row]
        cell.userImageView.backgroundColor = .blue
        return cell
    }

}

extension ViewController : UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        let alert = UIAlertController(title: "Hi", message: "\(nameArr[indexPath.row])", preferredStyle: .alert)
        let action = UIAlertAction(title: "OK", style: .default, handler: nil)
        alert.addAction(action)
        self.present(alert, animated: true, completion: nil)
    }

}

0

UICollectionView เหมือนกับ UITableView แต่ให้ฟังก์ชันการทำงานเพิ่มเติมเพียงแค่สร้างมุมมองกริดซึ่งเป็นปัญหาเล็กน้อยใน UITableView มันจะเป็นโพสต์ที่ยาวมากฉันพูดถึงลิงค์จากที่คุณจะได้รับทุกอย่างในขั้นตอนง่าย ๆ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.