UICollectionView, पूर्ण चौड़ाई की कोशिकाएं, ऑटोलयूट को गतिशील ऊंचाई की अनुमति देती हैं?


120

एक ऊर्ध्वाधर में UICollectionView,

क्या पूर्ण-चौड़ाई वाली कोशिकाएँ होना संभव है , लेकिन, गतिशील ऊँचाई को ऑटोलयूट द्वारा नियंत्रित किया जा सकता है ?

यह शायद मुझे "आईओएस में सबसे महत्वपूर्ण सवाल है जिसका कोई अच्छा जवाब नहीं है।"


जरूरी:

ध्यान दें कि 99% मामलों में, पूर्ण चौड़ाई की कोशिकाओं को प्राप्त करने के लिए + ऑटोलेयूट गतिशील ऊंचाई, बस एक तालिका दृश्य का उपयोग करें। इट्स दैट ईजी।


तो एक उदाहरण क्या है जहां आपको संग्रह दृश्य की आवश्यकता है?

संग्रह विचार तालिका के विचारों की तुलना में अविश्वसनीय रूप से अधिक शक्तिशाली हैं।

एक सीधा उदाहरण जहां आपको वास्तव में एक संग्रह दृश्य का उपयोग करना है, पूर्ण चौड़ाई की कोशिकाओं को प्राप्त करने के लिए + ऑटोलेयूट गतिशील ऊंचाई:

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

यह आईओएस में एक सामान्य और सामान्य मुहावरा है। दुर्भाग्य से यह केवल इस क्यूए में उत्पन्न समस्या को हल करके प्राप्त किया जा सकता है। : - /


हाँ UICollectionViewDelegateFlowLayout वर्ग के साथ संभव है
सुनील प्रजापति

इसका मतलब यह नहीं है कि आप वास्तव में एक tableView का उपयोग कर सकते हैं? आपके लिए अतिरिक्त कार्यक्षमता क्या होगी, इसको पूरा करने के लिए?
कैटालिना टी।

1
हाय @CatalinaT। , संग्रह विचारों में कई, कई, टेबल व्यू पर कई अतिरिक्त विशेषताएं हैं। एक सरल उदाहरण भौतिकी को जोड़ रहा है। (यदि आप नहीं जानते कि मेरा क्या मतलब है, तो यह है कि आप iOS में "बाउंसी" सूची कैसे बनाते हैं।)
फेटी

आप टेबल सेल में किसी भी तरह से भौतिकी (जैसे SpringDampingऔर initialSpringVelocity) लागू कर सकते हैं ..... टेबल व्यू का उपयोग करके इस बाउंसी सूची पर एक नज़र डालें ,,,, pastebin.com/pFRQhkrX आप TableViewCellमेज को चेतन में willDisplayCell:(UITableViewCell *)cellडाल सकते हैं जवाब जो आपकी समस्या को हल करने में मदद करता है जो उसी समस्या की तलाश में है
धीरू

ओह, क्या आपने सूची दृश्य का उपयोग करके बाउंसी सूची की कोशिश की? @ फटी
धीरू

जवाबों:


123

1. iOS 13+ के लिए समाधान

स्विफ्ट 5.1 और आईओएस 13 के साथ, आप अपनी समस्या को हल करने के लिए कंपोजल लेआउट ऑब्जेक्ट का उपयोग कर सकते हैं ।

निम्न पूर्ण नमूना कोड दिखाता है कि UILabelपूर्ण-चौड़ाई के अंदर मल्टीलाइन कैसे प्रदर्शित करें UICollectionViewCell:

CollectionViewController.swift

import UIKit

class CollectionViewController: UICollectionViewController {

    let items = [
        [
            "Lorem ipsum dolor sit amet.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        ],
        [
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        ],
        [
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            "Lorem ipsum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
        ]
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        let size = NSCollectionLayoutSize(
            widthDimension: NSCollectionLayoutDimension.fractionalWidth(1),
            heightDimension: NSCollectionLayoutDimension.estimated(44)
        )
        let item = NSCollectionLayoutItem(layoutSize: size)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)

        let section = NSCollectionLayoutSection(group: group)
        section.contentInsets = NSDirectionalEdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10)
        section.interGroupSpacing = 10

        let headerFooterSize = NSCollectionLayoutSize(
            widthDimension: .fractionalWidth(1.0),
            heightDimension: .absolute(40)
        )
        let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem(
            layoutSize: headerFooterSize,
            elementKind: "SectionHeaderElementKind",
            alignment: .top
        )
        section.boundarySupplementaryItems = [sectionHeader]

        let layout = UICollectionViewCompositionalLayout(section: section)
        collectionView.collectionViewLayout = layout
        collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "CustomCell")
        collectionView.register(HeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView")
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return items.count
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items[section].count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.label.text = items[indexPath.section][indexPath.row]
        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView", for: indexPath) as! HeaderView
        headerView.label.text = "Header"
        return headerView
    }

    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)
        coordinator.animate(alongsideTransition: { context in
            self.collectionView.collectionViewLayout.invalidateLayout()
        }, completion: nil)
    }

}

HeaderView.swift

import UIKit

class HeaderView: UICollectionReusableView {

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .magenta

        addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

CustomCell.swift

import UIKit

class CustomCell: UICollectionViewCell {

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        label.numberOfLines = 0
        backgroundColor = .orange
        contentView.addSubview(label)

        label.translatesAutoresizingMaskIntoConstraints = false
        label.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

अपेक्षित प्रदर्शन:

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


2. iOS 11+ के लिए समाधान

स्विफ्ट 5.1 और आईओएस 11 के साथ, आप UICollectionViewFlowLayoutइसकी estimatedItemSizeसंपत्ति को उप-वर्ग और सेट कर सकते हैं UICollectionViewFlowLayout.automaticSize(यह उस सिस्टम को बताता है जिसे आप ऑटोरेस्पोन्डिंग UICollectionViewCellएस से निपटना चाहते हैं )। इसके बाद आप ओवरराइड करने के लिए होगा layoutAttributesForElements(in:)और layoutAttributesForItem(at:)क्रम में करने के लिए सेट कोशिकाओं चौड़ाई। अंत में, आपको अपनी सेल की preferredLayoutAttributesFitting(_:)विधि को ओवरराइड करना होगा और इसकी ऊंचाई की गणना करनी होगी ।

निम्न पूर्ण कोड दिखाता है कि UILabelपूर्ण-चौड़ाई के अंदर बहुस्तरीय को कैसे प्रदर्शित किया जाए UIcollectionViewCell( UICollectionViewसुरक्षित क्षेत्र और UICollectionViewFlowLayoutइनसेट द्वारा विवश ):

CollectionViewController.swift

import UIKit

class CollectionViewController: UICollectionViewController {

    let items = [
        [
            "Lorem ipsum dolor sit amet.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris. Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        ],
        [
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
        ],
        [
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt.",
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
            "Lorem ipsum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.",
        ]
    ]
    let customFlowLayout = CustomFlowLayout()

    override func viewDidLoad() {
        super.viewDidLoad()

        customFlowLayout.sectionInsetReference = .fromContentInset // .fromContentInset is default
        customFlowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        customFlowLayout.minimumInteritemSpacing = 10
        customFlowLayout.minimumLineSpacing = 10
        customFlowLayout.sectionInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        customFlowLayout.headerReferenceSize = CGSize(width: 0, height: 40)

        collectionView.collectionViewLayout = customFlowLayout
        collectionView.contentInsetAdjustmentBehavior = .always
        collectionView.register(CustomCell.self, forCellWithReuseIdentifier: "CustomCell")
        collectionView.register(HeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView")
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return items.count
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return items[section].count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.label.text = items[indexPath.section][indexPath.row]
        return cell
    }

    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "HeaderView", for: indexPath) as! HeaderView
        headerView.label.text = "Header"
        return headerView
    }

}

CustomFlowLayout.swift

import UIKit

final class CustomFlowLayout: UICollectionViewFlowLayout {

    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        let layoutAttributesObjects = super.layoutAttributesForElements(in: rect)?.map{ $0.copy() } as? [UICollectionViewLayoutAttributes]
        layoutAttributesObjects?.forEach({ layoutAttributes in
            if layoutAttributes.representedElementCategory == .cell {
                if let newFrame = layoutAttributesForItem(at: layoutAttributes.indexPath)?.frame {
                    layoutAttributes.frame = newFrame
                }
            }
        })
        return layoutAttributesObjects
    }

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        guard let collectionView = collectionView else {
            fatalError()
        }
        guard let layoutAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes else {
            return nil
        }

        layoutAttributes.frame.origin.x = sectionInset.left
        layoutAttributes.frame.size.width = collectionView.safeAreaLayoutGuide.layoutFrame.width - sectionInset.left - sectionInset.right
        return layoutAttributes
    }

}

HeaderView.swift

import UIKit

class HeaderView: UICollectionReusableView {

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .magenta

        addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

CustomCell.swift

import UIKit

class CustomCell: UICollectionViewCell {

    let label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        label.numberOfLines = 0
        backgroundColor = .orange
        contentView.addSubview(label)

        label.translatesAutoresizingMaskIntoConstraints = false
        label.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
        label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor).isActive = true
        label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor).isActive = true
        label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
        let layoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
        layoutIfNeeded()
        layoutAttributes.frame.size = systemLayoutSizeFitting(UIView.layoutFittingCompressedSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
        return layoutAttributes
    }

}

यहाँ कुछ वैकल्पिक कार्यान्वयन हैं preferredLayoutAttributesFitting(_:):

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
    layoutAttributes.frame.size = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .fittingSizeLevel)
    return layoutAttributes
}
override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    label.preferredMaxLayoutWidth = layoutAttributes.frame.width
    layoutAttributes.frame.size.height = contentView.systemLayoutSizeFitting(UIView.layoutFittingCompressedSize).height
    return layoutAttributes
}

अपेक्षित प्रदर्शन:

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


मेरे लिए यह तब तक अच्छा रहा जब तक मैंने अनुभाग हेडर नहीं जोड़े। IOS 11 में सेक्शन हेडर गलत हैं और अन्य सेल को कवर करते हैं। लेकिन iOS 12 में ठीक काम करता है। क्या आपने सेक्शन हेडर जोड़ने के साथ किसी समस्या का सामना किया है?
नकुल

बहुत बहुत धन्यवाद। आपने मेरा हफ्ता बचा लिया। 🙇♂️
गातन

1
जब भी आकार बदलता है तो कलेक्शन व्यू शीर्ष पर पहुंच जाता है
सजीथ

1
शानदार खबर, @ImanouPetit! काश इनाम बड़ा होता! समग्र लेआउट वस्तुओं पर शानदार जानकारी, धन्यवाद।
फेटी

1
हाय, मैं यह कोशिश कर रहा हूँ। हालाँकि, मैं लेआउट को viewdidload में सेट कर रहा हूँ जैसा कि आपने ऊपर किया था, मुझे यह बताते हुए क्रैश हो जाता है कि कलेक्शनव्यू को नॉन-नील लेआउट पैरामीटर के साथ आरंभीकृत किया जाना चाहिए। क्या मुझे कुछ याद आ रहा है? यह IOS 13. के लिए Xcode 11 है
जिओमेटमेट

29

संकट

आप स्वचालित ऊंचाई की तलाश कर रहे हैं और चौड़ाई में भी पूर्ण होना चाहते हैं, दोनों का उपयोग करना संभव नहीं है UICollectionViewFlowLayoutAutomaticSize

आप UICollectionViewनीचे का उपयोग करना चाहते हैं आप के लिए समाधान है।

उपाय

चरण- I : सेल की अपेक्षित ऊंचाई की गणना करें

1. केवल आप है UILabel में CollectionViewCellसे सेट numberOfLines=0और उस की उम्मीद ऊंचाई की गणना UIlable, सभी तीन पैरामीटर पारित

func heightForLable(text:String, font:UIFont, width:CGFloat) -> CGFloat {
    // pass string, font, LableWidth  
    let label:UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude))
     label.numberOfLines = 0
     label.lineBreakMode = NSLineBreakMode.byWordWrapping
     label.font = font
     label.text = text
     label.sizeToFit()

     return label.frame.height
}

2. यदि आपका CollectionViewCellकेवल शामिल है UIImageViewऔर यदि इसे ऊंचाई में गतिशील माना जाता है, तो आपको इसकी ऊंचाई प्राप्त करने की आवश्यकता है UIImage (आपके UIImageViewपास AspectRatioबाधाएं होनी चाहिए )

// this will give you the height of your Image
let heightInPoints = image.size.height
let heightInPixels = heightInPoints * image.scale

3. यदि इसमें उनकी ऊँचाई की गणना की जाती है और उन्हें एक साथ जोड़ा जाता है।

चरण- II : का आकार वापस करेंCollectionViewCell

1.UICollectionViewDelegateFlowLayout अपने viewController में प्रतिनिधि जोड़ें

2. प्रतिनिधि पद्धति को लागू करना

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

    // This is just for example, for the scenario Step-I -> 1 
    let yourWidthOfLable=self.view.size.width
    let font = UIFont(name: "Helvetica", size: 20.0)

    var expectedHeight = heightForLable(array[indePath.row], font: font, width:yourWidthOfLable)


    return CGSize(width: view.frame.width, height: expectedHeight)
}

उम्मीद है की यह आपकी मदद करेगा।


1
क्या ऑटो लेआउट के साथ लंबवत रूप से बढ़ती कोशिकाओं की ऊँचाई के साथ क्षैतिज स्क्रॉलिंग UICollectionView होना संभव है?
एनआर

मैं एक ही लेकिन आधी चौड़ाई और गतिशील ऊंचाई हासिल करना चाहता हूं
मिहिर मेहता

return CGSize(width: view.frame.width/2, height: expectedHeight)चौड़ाई को वापस करने के बजाय पैडिंग को भी ध्यान में रखें अन्यथा दो सेल एकल पंक्ति में फिट नहीं होंगे।
धीरू

@ nr5 क्या आपको समाधान मिला? मेरी आवश्यकता आपके जैसी ही है। धन्यवाद।
मौलिक भूपानी

@MaulikBhuptani मैं इसे ऑटो लेआउट के साथ पूरी तरह से नहीं कर सका। एक कस्टम लेआउट क्लास बनाना था और कुछ क्लास तरीकों को ओवरराइड करना था।
nr5

18

इस समस्या से निपटने के कुछ तरीके हैं।

एक तरीका यह है कि आप संग्रह दृश्य प्रवाह लेआउट को अनुमानित आकार दे सकते हैं और सेल आकार की गणना कर सकते हैं।

नोट: जैसा कि नीचे टिप्पणी में कहा गया है, आईओएस 10 के रूप में आपको कोशिकाओं को कॉल को ट्रिगर करने के लिए अब और अनुमानित आकार प्रदान करने की आवश्यकता नहीं है func preferredLayoutAttributesFitting(_ layoutAttributes:)। इससे पहले (iOS 9) आपको एक अनुमानित आकार प्रदान करने की आवश्यकता होगी यदि आप एक कोशिकाओं prefferedLayoutAttributes को क्वेरी करना चाहते थे।

(यह मानते हुए कि आप स्टोरीबोर्ड का उपयोग कर रहे हैं और संग्रह दृश्य आईबी के माध्यम से जुड़ा हुआ है)

override func viewDidLoad() {
    super.viewDidLoad()
    let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout
    layout?.estimatedItemSize = CGSize(width: 375, height: 200) // your average cell size
}

साधारण कोशिकाओं के लिए जो आमतौर पर पर्याप्त होगी। यदि आकार अभी भी गलत है, तो संग्रह व्यू सेल में आप ओवरराइड कर सकते हैं func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes, जो आपको सेल आकार पर अधिक बढ़िया अनाज नियंत्रण देगा। नोट: आपको अभी भी प्रवाह लेआउट को एक अनुमानित आकार देने की आवश्यकता होगी

फिर func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributesसही आकार वापस करने के लिए ओवरराइड करें।

override func preferredLayoutAttributesFitting(_ layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes {
    let autoLayoutAttributes = super.preferredLayoutAttributesFitting(layoutAttributes)
    let targetSize = CGSize(width: layoutAttributes.frame.width, height: 0)
    let autoLayoutSize = contentView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityDefaultLow)
    let autoLayoutFrame = CGRect(origin: autoLayoutAttributes.frame.origin, size: autoLayoutSize)
    autoLayoutAttributes.frame = autoLayoutFrame
    return autoLayoutAttributes
}

वैकल्पिक रूप से, इसके बजाय आप सेल के आकार की गणना करने के लिए एक आकार देने वाले सेल का उपयोग कर सकते हैं UICollectionViewDelegateFlowLayout

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    let width = collectionView.frame.width
    let size = CGSize(width: width, height: 0)
    // assuming your collection view cell is a nib
    // you may also instantiate a instance of our cell from a storyboard
    let sizingCell = UINib(nibName: "yourNibName", bundle: nil).instantiate(withOwner: nil, options: nil).first as! YourCollectionViewCell
    sizingCell.autoresizingMask = [.flexibleWidth, .flexibleHeight]
    sizingCell.frame.size = size
    sizingCell.configure(with: object[indexPath.row]) // what ever method configures your cell
    return sizingCell.contentView.systemLayoutSizeFitting(size, withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityDefaultLow)
}

हालांकि ये सही उत्पादन के लिए तैयार उदाहरण नहीं हैं, लेकिन आपको सही दिशा में शुरुआत करनी चाहिए। मैं यह नहीं कह सकता कि यह सबसे अच्छा अभ्यास है, लेकिन यह मेरे लिए काम करता है, यहां तक ​​कि कई लेबल वाले काफी जटिल कोशिकाओं के साथ भी, जो कई लाइनों में लपेट सकते हैं या नहीं भी।


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

इसके अतिरिक्त यदि यह उत्तर सहायक होने के लिए कुछ विशिष्ट याद कर रहा है और / या जिसे आप विहित मानते हैं, तो मुझे बताएं। मैं इनाम पर बहस नहीं करूंगा, मैं इस प्रश्न को देखने वाले किसी अन्य व्यक्ति के लिए सहायक बनना चाहूंगा।
एरिक मर्फी

1
(अनुमान सहित या नहीं सहित। Itememize वर्तमान iOS में कोई अंतर नहीं डालता है, और "पूर्ण चौड़ाई + गतिशील ऊंचाई" समस्या में किसी भी तरह से कोई मदद नहीं करता है।) अंत में कोड, nibs शायद ही कभी इन दिनों उपयोग किया जाता है और यह। एक गतिशील ऊंचाई से थोड़ी प्रासंगिकता (उदाहरण के लिए, कुछ गतिशील ऊंचाई पाठ दृश्य)। हालांकि धन्यवाद
फटी

मैं इस समाधान पर भी पहुंचा था, लेकिन मेरे मामले में, iOS 11, Xcode 9.2, सेल सामग्री को सेल से ही डिस्कनेक्ट किया गया था - मुझे निश्चित आयाम की पूरी ऊंचाई या चौड़ाई तक विस्तार करने के लिए एक छवि नहीं मिल सकती है। मैंने आगे देखा कि CV सेटिंग्स में अड़चन थी preferredLayoutAttributesFitting। मैंने तब उक्त समारोह में अपने खुद के एक बाधा को जोड़ा, अनुमान से तय आयाम के लिए बाध्य करते हुए, FWIW, नीचे मेरा जवाब देखें।
क्रिस कॉनओवर

16

मुझे उस मुद्दे के लिए एक बहुत ही आसान समाधान मिला: मेरे कलेक्शन व्यू के अंदर मुझे एक UIView () मिला, जो वास्तव में सिर्फ एक पृष्ठभूमि है। पूरी चौड़ाई पाने के लिए मैंने बस निम्नलिखित एंकर स्थापित किए हैं

bgView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.size.width - 30).isActive = true // 30 is my added up left and right Inset
bgView.topAnchor.constraint(equalTo: topAnchor).isActive = true
bgView.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
bgView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
bgView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true

"जादू" पहली पंक्ति में होता है। मैं चौड़ाई को स्क्रीन पर चौड़ाई में गतिशील रूप से सेट करता हूं। इसके अलावा अपने संग्रह दृश्य के इनसेट को घटाना महत्वपूर्ण है। अन्यथा सेल दिखाई नहीं देगी। यदि आप ऐसी पृष्ठभूमि को देखना नहीं चाहते हैं, तो बस इसे अदृश्य बना दें।

FlowLayout निम्नलिखित सेटिंग्स का उपयोग करता है

layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize

परिणाम गतिशील ऊंचाई के साथ एक पूर्ण चौड़ाई के आकार का सेल है।

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


1
पवित्र गाय - यह अद्भुत है! इतना स्पष्ट ! प्रतिभाशाली !
फेटी

1
सिर्फ TBC @ inf1783, आप UICollectionView में ऐसा कर रहे हैं? (टेबल व्यू नहीं) - सही है?
फेटी

1
@ फैटी हाँ, यह एक UICollectionView है;)
inf1783

शानदार @ inf1783, यह बाहर की कोशिश करने के लिए इंतजार नहीं कर सकता। वैसे, ऐसा करने का एक और अच्छा तरीका यह है कि UIView को उपवर्गित करें और बस एक आंतरिक चौड़ाई जोड़ें (मेरा अनुमान है कि इसका प्रभाव समान होगा, और यह शायद स्टोरीबोर्ड समय पर भी काम करेगा)
Fattie

1
हर बार जब मैं यह कोशिश करता हूं तो मैं अंतहीन लूप में समाप्त हो जाता हूं। UICollectionViewFlowLayout के व्यवहार में कोई त्रुटि नहीं है: /
Skodik.o

7

काम कर रहे!!! IOS पर परीक्षण किया गया: 12.1 स्विफ्ट 4.1

मेरे पास एक बहुत ही सरल उपाय है जो सिर्फ बिना किसी बाधा के काम करता है।

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

मेरा दृश्य नियंत्रक

class ViewController: UIViewController {

    @IBOutlet weak var collectionView: UICollectionView!

    let cellId = "CustomCell"

    var source = ["nomu", "when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. ", "t is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by", "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia,","nomu", "when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. ", "t is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by", "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia,","nomu", "when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. ", "t is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by", "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia,"]

    override func viewDidLoad() {
        super.viewDidLoad()

        self.collectionView.delegate = self
        self.collectionView.dataSource = self
        self.collectionView.register(UINib.init(nibName: cellId, bundle: nil), forCellWithReuseIdentifier: cellId)

        if let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
            flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize
        }

    }

}


extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as? CustomCell else { return UICollectionViewCell() }
        cell.setData(data: source[indexPath.item])
        return cell
    }


}

CustomCell वर्ग:

class CustomCell: UICollectionViewCell {

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var widthConstraint: NSLayoutConstraint!

    override func awakeFromNib() {
        super.awakeFromNib()
        self.widthConstraint.constant = UIScreen.main.bounds.width
    }

    func setData(data: String) {
        self.label.text = data
    }

    override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
        return contentView.systemLayoutSizeFitting(CGSize(width: self.bounds.size.width, height: 1))
    }

}

मुख्य घटक CustomL में SystemLayoutSizeFitting फ़ंक्शन है। और इसके अलावा, हमें सेल के अंदर के दृश्य को बाधाओं के साथ निर्धारित करना होगा।


6

आपको संग्रह दृश्य में चौड़ाई की बाधा को जोड़ना होगा

class SelfSizingCell: UICollectionViewCell {

  override func awakeFromNib() {
      super.awakeFromNib()
      contentView.translatesAutoresizingMaskIntoConstraints = false
      contentView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width).isActive = true
  }
}

अंत में किसी ने इसे दो लाइनों में परिपूर्ण कर दिया
उमर एन शामली

यह सेल को एक निश्चित चौड़ाई तक सीमित कर देगा, शायद ही आत्म-आकार। यदि आप डिवाइस को घुमाने या एक iPad पर स्क्रीन के आकार को समायोजित करने के लिए थे, तो यह निश्चित रहेगा।
थॉमस वर्बीक

4
  1. estimatedItemSizeआपके प्रवाह लेआउट का सेट :

    collectionViewLayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize
  2. सेल में एक चौड़ाई की कमी को परिभाषित करें और इसे पर्यवेक्षण की चौड़ाई के बराबर सेट करें:

    class CollectionViewCell: UICollectionViewCell {
        private var widthConstraint: NSLayoutConstraint?
    
        ...
    
        override init(frame: CGRect) {
            ...
            // Create width constraint to set it later.
            widthConstraint = contentView.widthAnchor.constraint(equalToConstant: 0)
        }
    
        override func updateConstraints() {
            // Set width constraint to superview's width.
            widthConstraint?.constant = superview?.bounds.width ?? 0
            widthConstraint?.isActive = true
            super.updateConstraints()
        }
    
        ...
    }

पूर्ण उदाहरण

IOS 11 पर परीक्षण किया गया।


3

व्यक्तिगत रूप से मुझे एक UICollectionView का सबसे अच्छा तरीका मिला, जहां AutoLayout आकार को निर्धारित करता है, जबकि प्रत्येक सेल में एक अलग आकार हो सकता है UICollectionViewDelegateFlowLayout sizeForItem.tIndexPath फ़ंक्शन को लागू करने के लिए आकार को मापने के लिए फ़ंक्शन।

मैंने अपने एक ब्लॉग पोस्ट में इस बारे में बात की थी

उम्मीद है कि यह आपको वह हासिल करने में मदद करेगा जो आप चाहते हैं। मुझे 100% यकीन नहीं है, लेकिन मेरा मानना ​​है कि यूआईटेबल व्यू के विपरीत, जहां आप वास्तव में ऑटोलॉयट अंतर्ग्रहण का उपयोग करके कोशिकाओं की पूरी तरह से स्वचालित ऊंचाई पा सकते हैं

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44

UICollectionView में AutoLayout को आकार निर्धारित करने देने का ऐसा कोई तरीका नहीं है क्योंकि UICollectionViewCell आवश्यक रूप से स्क्रीन की पूरी चौड़ाई को भरता नहीं है।

लेकिन यहां आपके लिए एक सवाल है : यदि आपको पूर्ण स्क्रीन चौड़ाई वाली कोशिकाओं की आवश्यकता है, तो आप एक अच्छे पुराने यूआईटेबल व्यू पर UICollectionView का उपयोग करके भी क्यों परेशान होते हैं जो ऑटो सेलिंग कोशिकाओं के साथ आता है?


इसे पकड़ो, नीचे Aprit कह रहा है कि UICollectionViewFlowLayoutAutomaticSize अब फ्लो लेआउट में उपलब्ध है, iOS10 में ...
Fattie

मैंने भी बस यही देखा। IOS 10. में अब स्पष्ट रूप से एक बात है। मैं इस पर इसी WWDC बात देखा था: developer.apple.com/videos/play/wwdc2016/219 हालांकि, यह पूरी तरह से सेल को अपनी सामग्री फिट करने के लिए स्वतः पूर्ण करेगा। मुझे यकीन नहीं है कि आप स्क्रीन चौड़ाई को भरने के लिए सेल (ऑटोलॉयट के साथ) को कैसे बता सकते हैं क्योंकि आप UICollectionViewCell और उसके माता-पिता (कम से कम स्टोरीबॉर्ड में नहीं) के बीच एक बाधा स्थापित नहीं कर सकते हैं
xxtesetx

सही। हम इस अविश्वसनीय रूप से स्पष्ट समस्या के वास्तविक समाधान के करीब नहीं हैं। : /
फटी

बात के अनुसार, आप अभी भी आकार को हटा सकते हैं। वैसे भी, मैं तब भी उपयोग के मामले में दिलचस्पी लेता हूँ जब उसे / उसे पूरी चौड़ाई की आवश्यकता होती है UICollectionViewCell और क्यों इस विशेष मामले में UITableView का उपयोग न करने के लिए इतना बड़ा सौदा होगा (निश्चित रूप से कुछ निश्चित हो सकता है लेकिन फिर मुझे लगता है आपको बस खुद कुछ गणना करने से निपटना होगा)
xxtesaxx

इसके बारे में सोचते हुए, यह काफी अविश्वसनीय है कि आप संग्रह के विचारों के साथ "कॉलम == 1" (और तब शायद कॉलम == 2 जब डिवाइस बग़ल में है) सेट नहीं कर सकते।
फटी

3

एरिक के जवाब पर मेरी टिप्पणी के अनुसार, मेरा समाधान उसके लिए बहुत समान है, लेकिन मुझे निश्चित आयाम में बाधा डालने के लिए पसंदीदासाइज़फ़ोर ... में एक बाधा जोड़ना था।

    override func systemLayoutSizeFitting(
        _ targetSize: CGSize, withHorizontalFittingPriority
        horizontalFittingPriority: UILayoutPriority,
        verticalFittingPriority: UILayoutPriority) -> CGSize {

        width.constant = targetSize.width

        let size = contentView.systemLayoutSizeFitting(
            CGSize(width: targetSize.width, height: 1),
            withHorizontalFittingPriority: .required,
            verticalFittingPriority: verticalFittingPriority)

        print("\(#function) \(#line) \(targetSize) -> \(size)")
        return size
    }

इस प्रश्न में कई डुप्लिकेट हैं, मैंने इसका विस्तार से उत्तर दिया , और यहां एक कार्य नमूना एप्लिकेशन प्रदान किया


2

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

extension PhotoAlbumVC: UICollectionViewDelegateFlowLayout {
  func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    // My height is static, but it could use the screen size if you wanted
    return CGSize(width: collectionView.frame.width - sectionInsets.left - sectionInsets.right, height: 60) 
  }
}

फिर व्यू कंट्रोलर में जहां ऑटोलैयट बाधा को संशोधित किया जाता है, मैं एक NSNotification को बंद कर देता हूं।

NotificationCenter.default.post(name: NSNotification.Name("constraintMoved"), object: self, userInfo: nil)

मेरे UICollectionView उपवर्ग में, मैं उस अधिसूचना को सुनता हूं:

// viewDidLoad
NotificationCenter.default.addObserver(self, selector: #selector(handleConstraintNotification(notification:)), name: NSNotification.Name("constraintMoved"), object: nil)

और लेआउट को अमान्य करें:

func handleConstraintNotification(notification: Notification) {
    self.collectionView?.collectionViewLayout.invalidateLayout()
}

यह sizeForItemAtसंग्रह दृश्य के नए आकार का उपयोग करके फिर से कॉल करने का कारण बनता है। आपके मामले में, यह लेआउट में उपलब्ध नई बाधाओं को देखते हुए अद्यतन करने में सक्षम होना चाहिए।


सिर्फ TBC मार्क का मतलब है कि आप वास्तव में सेल का आकार बदल रहे हैं ? (यानी, सेल दिखाई देता है और यह आकार एक्स है, तो आपके ऐप में कुछ होता है और यह आकार वाई हो जाता है ..?) thx
Fattie

हाँ। जब उपयोगकर्ता स्क्रीन पर एक तत्व को ड्रग करता है, तो एक घटना आग हो जाती है जो सेल के आकार को अपडेट करती है।
मार्क सुमन

1

अपने पर viewDidLayoutSubviews, estimatedItemSizeपूरी चौड़ाई पर सेट करें (लेआउट UICollectionViewFlowLayout ऑब्जेक्ट को संदर्भित करता है):

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize(width: collectionView.bounds.size.width, height: 120)
}

अपने सेल पर, सुनिश्चित करें कि आपकी बाधाएँ सेल के ऊपर और नीचे दोनों को छूती हैं (निम्नलिखित कोड बाधाओं को स्थापित करने को आसान बनाने के लिए कार्टोग्राफी का उपयोग करता है, लेकिन आप चाहें तो NSLayoutConstraint या IB के साथ कर सकते हैं)

constrain(self, nameLabel, valueLabel) { view, name, value in
        name.top == view.top + 10
        name.left == view.left
        name.bottom == view.bottom - 10
        value.right == view.right
        value.centerY == view.centerY
    }

वोइला, आप सेल अब ऊंचाई में ऑटोग्रॉव करेंगे!


0

कोई भी समाधान मेरे लिए काम नहीं कर रहा था क्योंकि मुझे आईफ़ोन की चौड़ाई के बीच अनुकूलन करने के लिए गतिशील चौड़ाई की आवश्यकता थी।

    class CustomLayoutFlow: UICollectionViewFlowLayout {
        override init() {
            super.init()
            minimumInteritemSpacing = 1 ; minimumLineSpacing = 1 ; scrollDirection = .horizontal
        }

        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            minimumInteritemSpacing = 1 ; minimumLineSpacing = 1 ; scrollDirection = .horizontal
        }

        override var itemSize: CGSize {
            set { }
            get {
                let width = (self.collectionView?.frame.width)!
                let height = (self.collectionView?.frame.height)!
                return CGSize(width: width, height: height)
            }
        }
    }

    class TextCollectionViewCell: UICollectionViewCell {
        @IBOutlet weak var textView: UITextView!

        override func prepareForReuse() {
            super.prepareForReuse()
        }
    }




    class IntroViewController: UIViewController, UITextViewDelegate, UICollectionViewDataSource, UICollectionViewDelegate, UINavigationControllerDelegate {
        @IBOutlet weak var collectionViewTopDistanceConstraint: NSLayoutConstraint!
        @IBOutlet weak var collectionViewTopDistanceConstraint: NSLayoutConstraint!
        @IBOutlet weak var collectionView: UICollectionView!
        var collectionViewLayout: CustomLayoutFlow!

        override func viewDidLoad() {
            super.viewDidLoad()

            self.collectionViewLayout = CustomLayoutFlow()
            self.collectionView.collectionViewLayout = self.collectionViewLayout
        }

        override func viewWillLayoutSubviews() {
            self.collectionViewTopDistanceConstraint.constant = UIScreen.main.bounds.height > 736 ? 94 : 70

            self.view.layoutIfNeeded()
        }
    }

0

IOS 10 से, हमें ऐसा करने के लिए फ्लो लेआउट पर नया एपीआई मिला है।

आपको बस इतना करना है अपने सेट किया गया है flowLayout.estimatedItemSize, एक नया निरंतर करने के लिए UICollectionViewFlowLayoutAutomaticSize

स्रोत


हम्म, आपको पूरा यकीन है कि यह * पूरी चौड़ाई बनाता है ? तो, अनिवार्य रूप से एक कॉलम?
फेटी

यदि आप स्पष्ट रूप से पूर्ण चौड़ाई में UICollectionViewCell की चौड़ाई सेट करते हैं तो यह हो सकता है।
अर्पित डोंगरे

नहीं, यह पूरी ऊंचाई तक चौड़ाई को ठीक नहीं करता है, और अनुमानित आकार के मूल्य की अनदेखी नहीं करता है जब तक कि आप एरिक के उत्तर का पालन नहीं करते हैं, या नीचे / बाद में मेरा।
क्रिस कॉनोवर

ठीक है, दुर्भाग्य से तब इस समस्या का कोई संबंध नहीं है! हे! : ओ
फटी जूल

0

AutoLayout का उपयोग संग्रह व्यू में कोशिकाओं के ऑटो-साइज़िंग के लिए 2 आसान चरणों में किया जा सकता है:

  1. डायनेमिक सेल को सक्षम करना

flowLayout.estimatedItemSize = UICollectionViewFlowLayout.automaticSize

  1. एक collectionView(:cellForItemAt:)कन्टैंट दृश्य देखें और कन्टैंटव्यू की चौड़ाई को संग्रह दृश्य की चौड़ाई तक सीमित करने के लिए कन्टेनरैविसएक्टिवचोर.कॉन्स्ट्रैंट सेट करें ।
class ViewController: UIViewController, UICollectionViewDataSource {
    ...

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! MultiLineCell
        cell.textView.text = dummyTextMessages[indexPath.row]
        cell.maxWidth = collectionView.frame.width
        return cell
    }

    ...
}
class MultiLineCell: UICollectionViewCell{
    ....

    var maxWidth: CGFloat? {
        didSet {
            guard let maxWidth = maxWidth else {
                return
            }
            containerViewWidthAnchor.constant = maxWidth
            containerViewWidthAnchor.isActive = true
        }
    }

    ....
}

यह आपको वांछित परिणाम मिलेगा। पूर्ण कोड के लिए निम्नलिखित जिप देखें:

संदर्भ / क्रेडिट:

स्क्रीनशॉट: यहां छवि विवरण दर्ज करें


-6

आपको अपने संग्रह व्यू कंट्रोलर पर वर्ग UICollectionViewDelegateFlowLayout इनहेरिट करना होगा। फिर फ़ंक्शन जोड़ें:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize(width: view.frame.width, height: 100)
}

इसका उपयोग करते हुए, आपके पास स्क्रीन की चौड़ाई का आकार है।

और अब आपके पास tableViewController के रूप में पंक्तियों के साथ एक संग्रह दृश्य नियंत्रक है।

यदि आप चाहते हैं कि प्रत्येक सेल की ऊंचाई का आकार गतिशील रूप से हो, तो शायद आपको प्रत्येक सेल के लिए कस्टम सेल बनाने चाहिए जिनकी आपको आवश्यकता है।


7
यह वास्तव में सवाल का जवाब नहीं है :) कि 100 की एक निश्चित ऊंचाई देगा, अर्थात, यह है कि ऑटोलैयूट से पहले भी प्रोग्राम कैसे अस्तित्व में है।
फेटी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.