दिलचस्प पोस्ट
उद्देश्य सी विधि का कॉलर खोजने सी # के साथ MySQL के लिए पैरामीटेड क्वेरी जेक्जरी की जांच करें कि व्यूपोर्ट में तत्व दृश्यमान है Google chrome एक्सटेंशन बनाने में सामग्री-सुरक्षा-नीति त्रुटि कैसे PHP का उपयोग कर क्रॉन नौकरी बनाने के लिए? एंड्रॉइड – JSOUP के साथ पार्स जेएस उत्पन्न यूआरएल लूप के लिए सूची प्रविष्टियों को कैसे संशोधित करें? क्या मुझे सीएसएस में फोंट परिवार के नाम के चारों ओर कोट्स लपेटने की आवश्यकता है? Jquery का उपयोग करके यादृच्छिक divs दिखाना पायथन आयात स्टेटमेंट हमेशा एक मॉड्यूल के शीर्ष पर होना चाहिए? पूरे स्ट्रिंग को एक रीजेक्स के साथ जांचना Eclipse javascript संपादक: जेएस फाइलों के लिए सामग्री सहायता, स्वत: पूर्णता Laravel के ब्लेड: मैं एक टेम्पलेट में कैसे चर सेट कर सकते हैं? सूत्रों को प्रोग्राम बनाने के लिए स्ट्रिंग हेरफेर के अलावा क्या कोई बेहतर विकल्प है? सी में स्वचालित फ्लशिंग स्टडआउट बफर के नियम क्या हैं?

UICollectionView कॉलम की संख्या निर्धारित करें

मैं अभी UICollectionViews के बारे में सीखना शुरू कर दिया। मैं सोच रहा हूं कि किसी को पता है कि एक संग्रह दृश्य में कॉलम की संख्या कैसे निर्दिष्ट करें। डिफ़ॉल्ट 3 (आईफोन / पोर्ट्रेट) पर सेट है मैंने दस्तावेज को देखा है और एक संक्षिप्त जवाब नहीं मिल सकता है।

वेब के समाधान से एकत्रित समाधान "UICollectionView कॉलम की संख्या निर्धारित करें"

संग्रहदृश्य बहुत शक्तिशाली हैं, और वे कीमत पर आते हैं। बहुत सारे, और बहुत सारे विकल्प ओमज़ ने कहा:

आप कई कॉलम की संख्या को बदल सकते हैं

मैं <UICollectionViewDelegateFlowLayout> प्रोटोकॉल को लागू करने का सुझाव देता हूं, जिससे आपको निम्न तरीकों तक पहुंच मिलती है जिसमें आप अपने UICollectionView के लेआउट पर अधिक नियंत्रण कर सकते हैं, बिना इसे उप-क्लास करने की आवश्यकता:

  • collectionView:layout:insetForSectionAtIndex:
  • collectionView:layout:minimumInteritemSpacingForSectionAtIndex:
  • collectionView:layout:minimumLineSpacingForSectionAtIndex:
  • collectionView:layout:referenceSizeForFooterInSection:
  • collectionView:layout:referenceSizeForHeaderInSection:
  • collectionView:layout:sizeForItemAtIndexPath:

साथ ही, निम्न पद्धति को लागू करने से आपके UICollectionView को एक ओरिएंटेशन परिवर्तन पर लेआउट को अपडेट करने के लिए बाध्य किया जाएगा: (आप परिदृश्य के लिए कोशिकाओं को फिर से आकार देना चाहते हैं और उन्हें फैलाना चाहते हैं)

 -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ [self.myCollectionView.collectionViewLayout invalidateLayout]; } 

इसके अतिरिक्त, यहां UICollectionViews पर 2 बहुत अच्छा ट्यूटोरियल हैं:

http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12

http://skeuo.com/uicollectionview-custom-layout-tutorial

मैंने अपने UICollectionViewDelegateFlowLayout पर UICollectionViewDelegateFlowLayout को कार्यान्वित किया और कक्ष के आकार को निर्धारित करने के लिए जिम्मेदार विधि को ओवरराइड किया। मैंने तब स्क्रीन की चौड़ाई ली और मेरी कॉलम आवश्यकता के साथ इसे बांटा। उदाहरण के लिए, मैं प्रत्येक स्क्रीन आकार पर 3 कॉलम करना चाहता था। तो मेरा कोड ऐसा दिखता है –

 - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { CGRect screenRect = [[UIScreen mainScreen] bounds]; CGFloat screenWidth = screenRect.size.width; float cellWidth = screenWidth / 3.0; //Replace the divisor with the column count requirement. Make sure to have it in float. CGSize size = CGSizeMake(cellWidth, cellWidth); return size; } 

Noob के जवाब पर विस्तार:

 func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout let totalSpace = flowLayout.sectionInset.left + flowLayout.sectionInset.right + (flowLayout.minimumInteritemSpacing * CGFloat(numberOfItemsPerRow - 1)) let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(numberOfItemsPerRow)) return CGSize(width: size, height: size) } 

यह कोशिकाओं के बीच किसी भी रिक्ति के लिए अनुमति देता है। यह एक Int सदस्य चर मानता है, जिसे numberOfItemsPerRownumberOfItemsPerRow कहा जाता है और यह भी कि सभी कक्ष वर्ग और एक ही आकार हैं। जैसा कि jhilgert00 के जवाब में बताया गया है, हमें अभिविन्यास परिवर्तनों पर भी प्रतिक्रिया देना चाहिए, लेकिन अब willRotateToInterfaceOrientation का उपयोग करके willRotateToInterfaceOrientation depreciated है।

स्विफ्ट 3 के साथ, आप अपने UICollectionView में प्रति पंक्ति वस्तुओं की संख्या निर्धारित करने के लिए एक निम्न तीन लागूकरण का उपयोग कर सकते हैं।


# 1। UICollectionViewFlowLayout itemSize का उपयोग UICollectionViewFlowLayout संपत्ति और UICollectionViewLayout invalidationContext(forBoundsChange:) विधि

ColumnFlowLayout.swift:

 import UIKit class ColumnFlowLayout: UICollectionViewFlowLayout { let cellsPerRow: Int override var itemSize: CGSize { get { guard let collectionView = collectionView else { return super.itemSize } let marginsAndInsets = sectionInset.left + sectionInset.right + minimumInteritemSpacing * CGFloat(cellsPerRow - 1) let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down) return CGSize(width: itemWidth, height: itemWidth) } set { super.itemSize = newValue } } init(cellsPerRow: Int, minimumInteritemSpacing: CGFloat = 0, minimumLineSpacing: CGFloat = 0, sectionInset: UIEdgeInsets = .zero) { self.cellsPerRow = cellsPerRow super.init() self.minimumInteritemSpacing = minimumInteritemSpacing self.minimumLineSpacing = minimumLineSpacing self.sectionInset = sectionInset } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func invalidationContext(forBoundsChange newBounds: CGRect) -> UICollectionViewLayoutInvalidationContext { let context = super.invalidationContext(forBoundsChange: newBounds) as! UICollectionViewFlowLayoutInvalidationContext context.invalidateFlowLayoutDelegateMetrics = newBounds != collectionView?.bounds return context } } 

CollectionViewController.swift:

 import UIKit class CollectionViewController: UICollectionViewController { let columnLayout = ColumnFlowLayout( cellsPerRow: 5, minimumInteritemSpacing: 10, minimumLineSpacing: 10, sectionInset: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10) ) override func viewDidLoad() { super.viewDidLoad() collectionView?.collectionViewLayout = columnLayout } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 29 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) } } 

# 2। UICollectionViewDelegateFlowLayout collectionView(_:layout:sizeForItemAt:) UICollectionViewDelegateFlowLayout collectionView(_:layout:sizeForItemAt:) और UIContentContainer प्रोटोकॉल UICollectionViewDelegateFlowLayout का उपयोग करके UICollectionViewDelegateFlowLayout collectionView(_:layout:sizeForItemAt:) viewWillTransition(to:with:) विधि

 import UIKit class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { let margin: CGFloat = 10 let cellsPerRow = 5 override func viewDidLoad() { super.viewDidLoad() guard let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else { return } flowLayout.minimumInteritemSpacing = margin flowLayout.minimumLineSpacing = margin flowLayout.sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin) } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 29 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout let marginsAndInsets = flowLayout.sectionInset.left + flowLayout.sectionInset.right + flowLayout.minimumInteritemSpacing * CGFloat(cellsPerRow - 1) let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down) return CGSize(width: itemWidth, height: itemWidth) } override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { collectionView?.collectionViewLayout.invalidateLayout() super.viewWillTransition(to: size, with: coordinator) } } 

# 3। UICollectionViewDelegateFlowLayout collectionView(_:layout:sizeForItemAt:) का उपयोग करना collectionView(_:layout:sizeForItemAt:) और UICollectionViewFlowLayout estimatedItemSize संपत्ति

ध्यान दें कि यह कोड केवल Springs और Struts के साथ ठीक काम करता है

 import UIKit class CollectionViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { let margin: CGFloat = 10 let cellsPerRow = 5 override func viewDidLoad() { super.viewDidLoad() guard let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else { return } flowLayout.minimumInteritemSpacing = margin flowLayout.minimumLineSpacing = margin flowLayout.sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin) flowLayout.estimatedItemSize = flowLayout.itemSize // CGSize(width: 50, height: 50) } override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 29 } override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let flowLayout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout let marginsAndInsets = flowLayout.sectionInset.left + flowLayout.sectionInset.right + flowLayout.minimumInteritemSpacing * CGFloat(cellsPerRow - 1) let itemWidth = ((collectionView.bounds.size.width - marginsAndInsets) / CGFloat(cellsPerRow)).rounded(.down) return CGSize(width: itemWidth, height: itemWidth) } } 

आप उन उदाहरणों को ढूंढ सकते हैं और इस गिथूब रेपो पर एक Xcode प्रोजेक्ट में एक और बंडल किया जा सकता है: संग्रह दृश्य -स्तंभ-उदाहरण

स्विफ्ट 3 में अपडेट किया गया:

प्रवाह लेआउट के बजाय, मैं विशिष्ट स्तंभ संख्या और पंक्ति संख्या के लिए कस्टम लेआउट का उपयोग करना पसंद करता हूं। इसलिये:

  1. यह क्षैतिज रूप से खींच लिया जा सकता है अगर स्तंभ संख्या बहुत बड़ी है
  2. स्तंभ और पंक्ति का उपयोग करने के कारण यह तार्किक रूप से अधिक स्वीकार्य है

सामान्य सेल और हैडर सेल: (अपने xib के लिए एक IBOutlet के रूप में UILabel जोड़ें):

 class CollectionViewCell: UICollectionViewCell { @IBOutlet weak var label: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code self.backgroundColor = UIColor.black label.textColor = UIColor.white } } class CollectionViewHeadCell: UICollectionViewCell { @IBOutlet weak var label: UILabel! override func awakeFromNib() { super.awakeFromNib() // Initialization code self.backgroundColor = UIColor.darkGray label.textColor = UIColor.white } } 

कस्टम लेआउट:

 let cellHeight: CGFloat = 100 let cellWidth: CGFloat = 100 class CustomCollectionViewLayout: UICollectionViewLayout { private var numberOfColumns: Int! private var numberOfRows: Int! // It is two dimension array of itemAttributes private var itemAttributes = [[UICollectionViewLayoutAttributes]]() // It is one dimension of itemAttributes private var cache = [UICollectionViewLayoutAttributes]() override func prepare() { if self.cache.isEmpty { self.numberOfColumns = self.collectionView?.numberOfItems(inSection: 0) self.numberOfRows = self.collectionView?.numberOfSections // Dynamically change cellWidth if total cell width is smaller than whole bounds /* if (self.collectionView?.bounds.size.width)!/CGFloat(self.numberOfColumns) > cellWidth { self.cellWidth = (self.collectionView?.bounds.size.width)!/CGFloat(self.numberOfColumns) } */ for row in 0..<self.numberOfRows { var row_temp = [UICollectionViewLayoutAttributes]() for column in 0..<self.numberOfColumns { let indexPath = NSIndexPath(item: column, section: row) let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath as IndexPath) attributes.frame = CGRect(x: cellWidth*CGFloat(column), y: cellHeight*CGFloat(row), width: cellWidth, height: cellHeight) row_temp.append(attributes) self.cache.append(attributes) } self.itemAttributes.append(row_temp) } } } override var collectionViewContentSize: CGSize { return CGSize(width: CGFloat(self.numberOfColumns)*cellWidth, height: CGFloat(self.numberOfRows)*cellHeight) } override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { var layoutAttributes = [UICollectionViewLayoutAttributes]() for attributes in cache { if attributes.frame.intersects(rect) { layoutAttributes.append(attributes) } } return layoutAttributes } } 

CollectionView:

 let CellIdentifier = "CellIdentifier" let HeadCellIdentifier = "HeadCellIdentifier" class CollectionView: UICollectionView, UICollectionViewDelegate, UICollectionViewDataSource { init() { let layout = CustomCollectionViewLayout() super.init(frame: CGRect.zero, collectionViewLayout: layout) self.register(UINib(nibName: "CollectionViewCell", bundle: nil), forCellWithReuseIdentifier: CellIdentifier) self.register(UINib(nibName: "CollectionViewHeadCell", bundle: nil), forCellWithReuseIdentifier: HeadCellIdentifier) self.isDirectionalLockEnabled = true self.dataSource = self self.delegate = self } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } func updateCollectionView() { DispatchQueue.main.async { self.reloadData() } } // MARK: CollectionView datasource func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 20 } func numberOfSections(in collectionView: UICollectionView) -> Int { return 20 } override func numberOfItems(inSection section: Int) -> Int { return 20 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let column = (indexPath as NSIndexPath).row let row = (indexPath as NSIndexPath).section if column == 0 { let cell : CollectionViewHeadCell = collectionView.dequeueReusableCell(withReuseIdentifier: HeadCellIdentifier, for: indexPath) as! CollectionViewHeadCell cell.label.text = "\(row)" return cell } else if row == 0 { let cell : CollectionViewHeadCell = collectionView.dequeueReusableCell(withReuseIdentifier: HeadCellIdentifier, for: indexPath) as! CollectionViewHeadCell cell.label.text = "\(column)" return cell } else { let cell : CollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: CellIdentifier, for: indexPath) as! CollectionViewCell cell.label.text = String(format: "%d", arguments: [indexPath.section*indexPath.row]) return cell } } // MARK: CollectionView delegate func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { let column = (indexPath as NSIndexPath).row let row = (indexPath as NSIndexPath).section print("\(column) \(row)") } } 

ViewViewController से संग्रह दृश्य का उपयोग करें:

 class ViewController: UIViewController { let collectionView = CollectionView() override func viewDidLoad() { collectionView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(collectionView) self.view.backgroundColor = UIColor.red self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[collectionView]|", options: [], metrics: nil, views: ["collectionView": collectionView])) self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[collectionView]|", options: [], metrics: nil, views: ["collectionView": collectionView])) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) collectionView.updateCollectionView() } } 

अंत में आप फैंसी CollectionView सकते हैं!

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

चूंकि UICollectionView बहुत लचीला है, इसलिए आप जिस प्रकार के लेआउट का उपयोग करते हैं, उसके आधार पर आप कॉलम की संख्या को बदल सकते हैं।

UICollectionViewFlowLayout (जो हो सकता है कि आप किसके साथ काम कर रहे हैं) कई कॉलम सीधे निर्दिष्ट नहीं करता है (क्योंकि यह दृश्य आकार / अभिविन्यास पर निर्भर करता है) इसे बदलने का सबसे आसान तरीका यह होगा कि itemSize का itemSize संपत्ति और / या minimumInteritemSpacing / minimumLineSpacing

स्विफ्ट 3 के लिए यहां दो कोड वाले लेआउट का काम कोड है:

 func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { let nbCol = 2 let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout let totalSpace = flowLayout.sectionInset.left + flowLayout.sectionInset.right + (flowLayout.minimumInteritemSpacing * CGFloat(nbCol - 1)) let size = Int((collectionView.bounds.width - totalSpace) / CGFloat(nbCol)) return CGSize(width: size, height: size) } 

अपने इच्छित कॉलम की "nbCol" को बदलने के लिए स्वतंत्र महसूस करें।

अगर आप आलसी प्रतिनिधि का उपयोग कर रहे हैं

 extension UICollectionView { func setItemsInRow(items: Int) { if let layout = self.collectionViewLayout as? UICollectionViewFlowLayout { let contentInset = self.contentInset let itemsInRow: CGFloat = CGFloat(items); let innerSpace = layout.minimumInteritemSpacing * (itemsInRow - 1.0) let insetSpace = contentInset.left + contentInset.right + layout.sectionInset.left + layout.sectionInset.right let width = floor((CGRectGetWidth(frame) - insetSpace - innerSpace) / itemsInRow); layout.itemSize = CGSizeMake(width, width) } } } 

पुनश्च: रोटेशन के बाद भी बुलाया जाना चाहिए

इसके सभी लेआउट जिन्हें आप आकर्षित करना चाहते हैं आप UICollectionViewFlowLayout से कस्टम क्लास उत्तराधिकार बना सकते हैं। फिलहाल कॉलम सेट करने के लिए कोई सीधा तरीका नहीं है। यदि आप इस तरह की कार्यक्षमता हासिल करना चाहते हैं तो आपको इसे मैन्युअल रूप से करने की आवश्यकता है। आपको इसे अपने कस्टम प्रवाह लेआउट कक्षा में प्रबंधित करना होगा।

अब सवाल उठता है कि आप यह कैसे करेंगे? यदि आप सेल फ्रेम को परेशान नहीं करना चाहते हैं तो आप समायोजित कर सकते हैं

  collectionView:layout:minimumInteritemSpacingForSectionAtIndex: collectionView:layout:minimumLineSpacingForSectionAtIndex: 

एक अन्य तरीका आपको कक्षों की अपनी स्थिति प्रदान करता है। दो विधियों के नीचे ओवरराइड करके, जो आपके लेआउट के निर्माण के दौरान कहा जाएगा।

  - (NSArray*)layoutAttributesForElementsInRect:(CGRect)rect - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)path 

UICollectionViewLayoutAttributes वर्ग है जो सेल की स्थिति, फ़्रेम, ज़िन्डेक्स इत्यादि के साथ व्यवहार करेगा

स्विफ्ट 3.0 दोनों क्षैतिज और ऊर्ध्वाधर स्क्रॉल दिशाओं और चर अंतरालन के लिए काम करता है

कॉलम की संख्या निर्दिष्ट करें

 let numberOfColumns: CGFloat = 3 

निर्धारित flowLayout को प्रस्तुत करने के लिए flowLayout को कॉन्फ़िगर flowLayout

 if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout { let horizontalSpacing = flowLayout.scrollDirection == .vertical ? flowLayout.minimumInteritemSpacing : flowLayout.minimumLineSpacing let cellWidth = (view.frame.width - max(0, numberOfColumns - 1)*horizontalSpacing)/numberOfColumns flowLayout.itemSize = CGSize(width: cellWidth, height: cellWidth) } 

सही समाधान UICollectionViewDelegateFlowLayout का उपयोग करना है, लेकिन आप आसानी से सेल की चौड़ाई की गणना कर सकते हैं और इच्छित कॉलम की इच्छित संख्या पर विभाजित कर सकते हैं

मुश्किल से कोई अंश नहीं के साथ चौड़ाई बनाने के लिए है

 (UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { CGFloat screenWidth = self.view.frame.size.width; CGFloat marginWidth = (screenWidth - collectionView.frame.size.width); CGFloat cellWith = (collectionView.frame.size.width - marginWidth )/3; cellWith= floorf(cellWith); CGSize retval = CGSizeMake(cellWith,cellWith); return retval;} 

मैं सिर्फ इमानौ पेटिट का उत्तर # 2 में जोड़ना चाहता था यह सुनिश्चित करने के लिए कि मार्जिन सटीक स्क्रीन चौड़ाई की परवाह किए बिना, मैं एक वांछित हाशिया के साथ एक चलने वाला सॉल्वर का उपयोग करता हूं, और # कॉलम के रूप में इनपुट। मैंने एक दिशात्मक झंडा भी जोड़ा है जहां उनके अंतिम मार्जिन की तुलना उनके लक्ष्य से की जाएगी।

चलने वाला सॉल्वर नीचे दिखाया गया है और सेलवड्थ और मार्जिन देता है।

 private func iterativeCellSpacing(targetMargins : CGFloat, cellsPerRow : Int, isMinTarget : Bool) -> (CGFloat, CGFloat) { var w : CGFloat = 0 var m : CGFloat = targetMargins let cols : CGFloat = CGFloat(cellsPerRow) let numMargins : CGFloat = cols + 1.0 let screenWidth : CGFloat = collectionView!.bounds.size.width var delta = CGFloat.greatestFiniteMagnitude while abs(delta) > 0.001 { let totalMarginSpacing = numMargins * m let totalCellSpacing = screenWidth - totalMarginSpacing if (isMinTarget) { w = floor(totalCellSpacing / cols) m = ceil((screenWidth - cols * w) / numMargins) } else { w = ceil(totalCellSpacing / cols) m = floor((screenWidth - cols * w) / numMargins) } delta = screenWidth - w * CGFloat(cellsPerRow) - m * numMargins } return (w, m) } 

मैं उसे इस तरह कहता हूं:

 fileprivate var margin: CGFloat = 20 fileprivate var cellWidth : CGFloat = 80 fileprivate let cellsPerRow = 4 override func viewDidLoad() { super.viewDidLoad() (cellWidth, margin) = iterativeCellSpacing(targetMargins: margin, cellsPerRow: 4, isMinTarget: true) ... } 

फिर मैं सेल वाइड और मार्जिन मान को प्रवाह लेआउट पर लागू कर देता हूं:

 extension MyCollectionController : UICollectionViewDelegateFlowLayout 

{func collectionView (_ collectionView: UICollectionView, लेआउट कलेक्शनवॉललेआउट: UICollectionViewLayout, आकारएफ़ाइटआइटम सूचकांकपाथ: इंडेक्सपैथ) -> CGSize {वापसी CGSize (चौड़ाई: सेलविड्थ, ऊंचाई: सेलविड्थ)}

 override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { collectionView?.collectionViewLayout.invalidateLayout() super.viewWillTransition(to: size, with: coordinator) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { return UIEdgeInsetsMake(margin, margin, margin, margin) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return margin } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return margin } 

}

उम्मीद है की यह मदद करेगा। शायद हाशिए सटीक है यह सुनिश्चित करने के लिए एक आसान तरीका है, लेकिन यह एक तरीका है इसके अलावा, इस कोड को उन उपकरणों के लिए नहीं परीक्षण किया गया है जो संग्रहण दृश्यों को घूर्णन करने की अनुमति देते हैं।

धन्यवाद,