सेल रिक्ति और UICollectionView - UICollectionViewFlowLayout आकार अनुपात कैसे सेट करें?


137

मैं जोड़ने के लिए कोशिश कर रहा हूँ UICollectionViewकरने के लिए ViewController, और मैं कोशिकाओं के बीच रिक्त स्थान के बिना 3 कोशिकाओं 'पंक्ति प्रति' की आवश्यकता है (यह एक ग्रिड की तरह दिखना चाहिए)। सेल की चौड़ाई स्क्रीन के आकार का एक तिहाई होनी चाहिए, इसलिए मैंने सोचा कि layout.itemचौड़ाई समान होनी चाहिए। लेकिन फिर मुझे यह मिलता है:

layout.itemSize चौड़ाई = screenSize. उपलब्धता / 3

यदि मैं उस आकार ( 7 या 8 पिक्सेल जैसे) को कम कर देता हूं , तो यह बेहतर है, लेकिन पंक्ति में तीसरा सेल पूरी तरह से दिखाई नहीं देता है, और मेरे पास अभी भी वह रिक्त स्थान (ऊपर और नीचे, और बाएं और दाएं) है।

यहां छवि विवरण दर्ज करें

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
    var collectionView: UICollectionView?
    var screenSize: CGRect!
    var screenWidth: CGFloat!
    var screenHeight: CGFloat!

    override func viewDidLoad() {
        super.viewDidLoad()

        screenSize = UIScreen.mainScreen().bounds
        screenWidth = screenSize.width
        screenHeight = screenSize.height

        // Do any additional setup after loading the view, typically from a nib
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth / 3, height: screenWidth / 3)
        collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        collectionView!.dataSource = self
        collectionView!.delegate = self
        collectionView!.registerClass(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell")
        collectionView!.backgroundColor = UIColor.greenColor()
        self.view.addSubview(collectionView!)
    }

    func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
        return 1
    }

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CollectionViewCell", forIndexPath: indexPath) as CollectionViewCell
        cell.backgroundColor = UIColor.whiteColor()
        cell.layer.borderColor = UIColor.blackColor().CGColor
        cell.layer.borderWidth = 0.5
        cell.frame.size.width = screenWidth / 3
        cell.frame.size.height = screenWidth / 3

        cell.textLabel?.text = "\(indexPath.section):\(indexPath.row)"
        return cell
    }
}

यहाँ आपका समाधान है। धन्यवाद।
जानू कांसगरा

यहाँ स्विफ्ट 4 के लिए वर्किंग कोड है stackoverflow.com/a/54703798/10150796
निकुंज कुंभानी

जवाबों:


299

इन 2 लाइनों को जोड़ें

layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0

मतलब आपके पास है:

   // Do any additional setup after loading the view, typically from a nib.
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
        layout.itemSize = CGSize(width: screenWidth/3, height: screenWidth/3)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout

यह सभी रिक्त स्थान को हटा देगा और आपको एक ग्रिड लेआउट देगा:

यहां छवि विवरण दर्ज करें

यदि आप चाहते हैं कि पहला कॉलम स्क्रीन की चौड़ाई के बराबर चौड़ाई वाला हो तो निम्न फ़ंक्शन जोड़ें:

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
    if indexPath.row == 0
    {
        return CGSize(width: screenWidth, height: screenWidth/3)
    }
    return CGSize(width: screenWidth/3, height: screenWidth/3);

}

ग्रिड लेआउट अब दिखेगा (मैंने पहली सेल में एक नीली पृष्ठभूमि भी जोड़ी है): यहां छवि विवरण दर्ज करें


बहुत बहुत धन्यवाद, मैं कुछ और अधिक जटिल की उम्मीद कर रहा था, और मैंने उस पर बहुत समय बिताया। एक बार और धन्यवाद।
मार्को

और सिर्फ एक बात और है, क्या लेआउट बदलने की कोई संभावना है। केवल पहले सेल के लिए ही साइटाइज़ करें ? (मुझे पता है कि मैं परिवर्तन cell.frame.size करने की जरूरत है जब indexPath.row 0 है, लेकिन पता नहीं है केवल एक आइटम के लिए लेआउट आकार बदलने के लिए कैसे) पहले तत्व चौड़ाई बराबर होना चाहिए screenWidth
मार्को

1
नमस्ते, मैं एक ही समस्या है, लेकिन मैं उद्देश्य सी में समान समारोह शीर्षक जानना चाहता हूँ।
नाडा गामल

1
ठीक है, यह अब ठीक काम करता है, बहुत बहुत धन्यवाद :) उद्देश्य सी फ़ंक्शन: - (CGSize) संग्रह दृश्य : (UICollectionView ) संग्रह दृश्य लेआउट: (UICollectionViewLayout ) संग्रहदृश्य आकार का आकारमध्यअति। ); }
नाडा गमाल

4
महान उत्तर @greentor के लिए धन्यवाद। एक इनाम भेजा है। मत भूलना ! CollectionView .collectionViewLayout = लेआउट , पाठकों
fattie

47

स्विफ्ट 3 और एक्सकोड 8 के लिए , इसने काम किया। इसे प्राप्त करने के लिए नीचे दिए गए चरणों का पालन करें: -

{
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    let width = UIScreen.main.bounds.width
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
    layout.minimumInteritemSpacing = 0
    layout.minimumLineSpacing = 0
    collectionView!.collectionViewLayout = layout
}

इस कोड को viewDidLoad () फ़ंक्शन में रखें।


32

कुछ स्थितियों में, की स्थापना UICollectionViewFlowLayoutमें viewDidLoadया ViewWillAppearcollectionView पर प्रभाव नहीं हो सकता।

स्थापना UICollectionViewFlowLayoutमें viewDidAppearक्रम में कोशिकाओं आकार के परिवर्तन देखने हो सकती है।

एक अन्य समाधान, स्विफ्ट 3 में:

extension YourViewController : UICollectionViewDelegateFlowLayout{

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return UIEdgeInsets(top: 20, left: 0, bottom: 10, right: 0)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let collectionViewWidth = collectionView.bounds.width
        return CGSize(width: collectionViewWidth/3, height: collectionViewWidth/3)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 20
    }
}

बहुत बढ़िया जवाब! यह निश्चित रूप से ऐसा करने का Apple तरीका है। अब, आपको यह जानने की ज़रूरत नहीं है कि जब डिवाइस ओरिएंटेशन बदलता है, तो आपको कैसे रिफ्रेश करना है?
jlstr

17

यदि आप स्विफ्ट 3 की तलाश कर रहे हैं, तो इसे प्राप्त करने के लिए चरणों का पालन करें:

func viewDidLoad() {

    //Define Layout here
    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()

    //Get device width
    let width = UIScreen.main.bounds.width

    //set section inset as per your requirement.
    layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)

    //set cell item size here 
    layout.itemSize = CGSize(width: width / 2, height: width / 2)

    //set Minimum spacing between 2 items
    layout.minimumInteritemSpacing = 0

    //set minimum vertical line spacing here between two lines in collectionview
    layout.minimumLineSpacing = 0

    //apply defined layout to collectionview
    collectionView!.collectionViewLayout = layout

}

यह स्विफ्ट 3 के साथ Xcode 8.0 पर सत्यापित है।



4

स्विफ्ट 4

let collectionViewLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
collectionViewLayout?.sectionInset = UIEdgeInsetsMake(0, 20, 0, 40) 
collectionViewLayout?.invalidateLayout()

1

स्विफ्ट 3 और एक्सकोड 8 के लिए, इसने काम किया। इसे प्राप्त करने के लिए नीचे दिए गए चरणों का पालन करें: -

viewDidLoad()
    {
        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        var width = UIScreen.main.bounds.width
        layout.sectionInset = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
    width = width - 10
    layout.itemSize = CGSize(width: width / 2, height: width / 2)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        collectionView!.collectionViewLayout = layout
    }

3
इस तथ्य को ध्यान में रखें कि यदि आपके पास कई खंड हैं
निखिल पांडे

यह केवल 1 कॉलम (अनुभाग) के लिए है
user924

0

स्विफ्ट 3+ और Xcode 9+ के लिए इसका उपयोग करने का प्रयास करें

extension ViewController: UICollectionViewDelegateFlowLayout {

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let collectionWidth = collectionView.bounds.width
    return CGSize(width: collectionWidth/3, height: collectionWidth/3)

}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 0

}

0

स्विफ्ट 5: कंटेनर स्पेस का सबसे अच्छा उपयोग करने के लिए डायनेमिक सेल चौड़ाई के साथ कोशिकाओं के बीच समान रूप से वितरित रिक्त स्थान के लिए आप न्यूनतम न्यूनतम मूल्य प्रदान करके नीचे दिए गए कोड स्निपेट का उपयोग कर सकते हैं ।

private func collectionViewLayout() -> UICollectionViewLayout {
    
    let layout = UICollectionViewFlowLayout()
    layout.sectionHeadersPinToVisibleBounds = true
    // Important: if direction is horizontal use minimumItemSpacing instead. 
    layout.scrollDirection = .vertical
    
    let itemHeight: CGFloat = 240
    let minCellWidth :CGFloat = 130.0
    let minItemSpacing: CGFloat = 10
    let containerWidth: CGFloat = self.view.bounds.width
    let maxCellCountPerRow: CGFloat =  floor((containerWidth - minItemSpacing) / (minCellWidth+minItemSpacing ))
    
    let itemWidth: CGFloat = floor( ((containerWidth - (2 * minItemSpacing) - (maxCellCountPerRow-1) * minItemSpacing) / maxCellCountPerRow  ) )
    // Calculate the remaining space after substracting calculating cellWidth (Divide by 2 because of left and right insets)
    let inset = max(minItemSpacing, floor( (containerWidth - (maxCellCountPerRow*itemWidth) - (maxCellCountPerRow-1)*minItemSpacing) / 2 ) )

    
    layout.itemSize = CGSize(width: itemWidth, height: itemHeight)
    layout.minimumInteritemSpacing = min(minItemSpacing,inset)
    layout.minimumLineSpacing = minItemSpacing
    layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

    
    return layout
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.