ইউআইকোলিকেশনভিউ, পূর্ণ প্রস্থের কক্ষগুলি অটোলেআউট গতিশীল উচ্চতার অনুমতি দেয়?


120

উল্লম্বভাবে UICollectionView ,

পূর্ণ-প্রস্থের কক্ষগুলি রাখা কি সম্ভব , কিন্তু, গতিশীল উচ্চতাটি অটোলেআউট দ্বারা নিয়ন্ত্রিত হওয়ার অনুমতি দেয় ?

এটি আমাকে সম্ভবত "হ'ল আইওএসের সবচেয়ে গুরুত্বপূর্ণ প্রশ্ন যার সত্যিকারের ভাল উত্তর নেই" "


গুরুত্বপূর্ণ:

মনে রাখবেন যে 99% ক্ষেত্রে, সম্পূর্ণ প্রস্থের ঘরগুলি + অটোলেআউট গতিশীল উচ্চতা অর্জন করতে, কেবল একটি টেবিল ভিউ ব্যবহার করুন। এটা এত সহজ।


সুতরাং যেখানে আপনার সংগ্রহ ভিউ প্রয়োজন তার উদাহরণ কী?

সংগ্রহের দর্শনগুলি সারণী দর্শনগুলির চেয়ে অবিশ্বাস্যভাবে আরও শক্তিশালী।

সম্পূর্ণ প্রস্থের ঘরগুলি + অটোলেআউট গতিশীল উচ্চতা অর্জনের জন্য আপনাকে যেখানে সরাসরি ভিউ সংগ্রহ করতে হবে সেখানে একটি সহজ উদাহরণ :

আপনি যদি প্রাণবন্ত হয় সংগ্রহের দৃশ্যে দুটি বিন্যাসের মধ্যে । উদাহরণস্বরূপ, 1 এবং 2 কলামের বিন্যাসের মধ্যে, যখন ডিভাইসটি ঘোরানো হয়।

এটি আইওএসের একটি সাধারণ এবং সাধারণ প্রতিমা। দুর্ভাগ্যক্রমে এটি কেবল এই QA এর মধ্যে উপস্থিত সমস্যা সমাধানের মাধ্যমেই অর্জন করা যেতে পারে। : - /


হ্যাঁ ইউআইকোলিকেশনভিউ ডেলিগেটফ্লোএলয়েট ক্লাসের মাধ্যমে সম্ভব
সুনীল প্রজাপতি

এর অর্থ কি আপনি আসলে একটি টেবিলভিউ ব্যবহার করতে পারবেন? এটিকে অতিরিক্ত জটিল করার জন্য আপনার আরও কী কী কার্যকারিতা প্রয়োজন?
ক্যাটালিনা টি।

1
হাই @ ক্যাটালিনা , সংগ্রহের ভিউগুলিতে অনেকগুলি, অনেকগুলি, অনেকগুলি অতিরিক্ত বৈশিষ্ট্য রয়েছে টেবিল দর্শনের। একটি সহজ উদাহরণ পদার্থবিদ্যা যুক্ত করা হয়। (আপনি যদি আমার অর্থ কী তা জানেন না, তবে আপনি কীভাবে আইওএস-এ "বাউন্সি" তালিকা তৈরি করেন))
ফ্যাটি

আপনি টেবিল সেলে কোনওভাবে পদার্থবিজ্ঞান (যেমন SpringDampingএবং initialSpringVelocity) প্রয়োগ করতে পারেন ..... টেবিল ভিউ ব্যবহার করে এই বাউন্সি তালিকার দিকে নজর দিন ,,,, পেস্টবিনTableViewCell . willDisplayCell:(UITableViewCell *)cellcom/pFRQhkrX আপনি ডেলগেট পদ্ধতিতে টেবিলটি অ্যানিমেট করতে পারেন @ ফ্যাটি আপনি গ্রহণ করতে পারেন একই সমস্যার
সন্ধানকারী

ওহ, তালিকার ভিউ ব্যবহার করে আপনি বাউন্সি তালিকাটি ব্যবহার করে দেখেছেন? @ ফ্যাটি
ধিরু

উত্তর:


123

1. আইওএস 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. আইওএস 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
}

প্রত্যাশিত প্রদর্শন:

এখানে চিত্র বর্ণনা লিখুন


আমি বিভাগের শিরোনাম যোগ না করা পর্যন্ত এটি আমার পক্ষে ভাল কাজ করেছে। বিভাগে শিরোনামগুলি ভুল জায়গায় প্রতিস্থাপন করা হয়েছে এবং আইওএস-এ অন্য কক্ষগুলি coverেকে রাখে ১১. তবে আইওএসে ভাল কাজ করে ১২. বিভাগীয় শিরোনাম যুক্ত করার সাথে আপনি কি কোনও সমস্যার মুখোমুখি হয়েছিলেন?
নকুল

তোমাকে অনেক ধন্যবাদ. আপনি আমার সপ্তাহ বাঁচিয়েছেন। 🙇♂️
Gaetan

1
যখনই আকার পরিবর্তন হয়
কালেকশনভিউ

1
দুর্দান্ত খবর, @ ইমানুপিট! আমি যদি অনুগ্রহটি আরও বড় হত! সংশ্লেষপূর্ণ লেআউট অবজেক্টগুলির সম্পর্কে দুর্দান্ত তথ্য, ধন্যবাদ।
ফ্যাটি

1
হাই, আমি এটি চেষ্টা করছি যদিও আপনি উপরের মতো ভিডডিডলোডে লেআউটটি সেট করছি, তবুও আমি ক্র্যাশটি জানিয়েছিলাম যে কালেকশন ভিউটি অবশ্যই একটি নন-নীল লেআউট প্যারামিটার দিয়ে শুরু করা উচিত। আমি কি অনুপস্থিত কিছু আছে? এটি আইওএস ১৩ এর জন্য
এক্সকোড

29

সমস্যা

আপনি স্বয়ংক্রিয় উচ্চতা খুঁজছেন এবং প্রস্থ পূর্ণ করতে চান, এটি উভয় ব্যবহার পেতে করা সম্ভব নয় UICollectionViewFlowLayoutAutomaticSize

আপনি UICollectionViewনীচে তাই ব্যবহার করতে চান আপনার জন্য সমাধান।

সমাধান

স্টেপ-আমি : ঘরের প্রত্যাশিত উচ্চতা গণনা করুন

1. কেবলমাত্র আপনি যদি UILabelCollectionViewCellতুলনায় সেট numberOfLines=0এবং যে প্রত্যাশিত উচ্চতা গণনা করা UIlable, সব তিনটি paramters পাস

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
}

২. যদি আপনার CollectionViewCellকেবলমাত্র থাকে UIImageViewএবং যদি উচ্চতা অর্জনের চেয়ে আপনার উচ্চতার চেয়ে গতিশীল হওয়ার কথা হয় UIImage (আপনার UIImageViewঅবশ্যই AspectRatioবাধা থাকতে হবে )

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

৩. যদি এটি উভয়ই তাদের উচ্চতা গণনা করে এবং সেগুলি একসাথে যুক্ত করে।

দ্বিতীয় ধাপ : এর আকারটি ফিরিয়ে দিনCollectionViewCell

1.UICollectionViewDelegateFlowLayout আপনার ভিউকন্ট্রোলারে প্রতিনিধি যুক্ত করুন

২. প্রতিনিধি পদ্ধতি কার্যকর করুন

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
স্বয়ংক্রিয় বিন্যাসের সাথে কোষের উচ্চতা উল্লম্বভাবে বৃদ্ধি সহ একটি অনুভূমিক স্ক্রোলিং ইউআইসিওলিকেশনভিউ পাওয়া কি সম্ভব?
এনআর

আমি একই তবে অর্ধ প্রস্থ এবং গতিশীল উচ্চতা অর্জন করতে চাই
মিহির মেহতা

return CGSize(width: view.frame.width/2, height: expectedHeight)প্রস্থটি ফেরত দেওয়ার চেয়ে প্যাডিংকে অ্যাকাউন্টে রাখুন অন্যথায় দুটি ঘর একক সারিতে মানায় না।
ধিরু

@ এনআর 5 আপনি কি সমাধান পেয়েছেন? আমার চাহিদাও আপনার মতো। ধন্যবাদ।
মৌলিক ভূপতানি

@ মৌলিকভূতানি অটো লেআউট দিয়ে আমি এটি পুরোপুরি করতে পারিনি। একটি কাস্টম লেআউট ক্লাস তৈরি করতে হয়েছিল এবং কিছু শ্রেণির পদ্ধতি ওভাররাইড করতে হয়েছিল।
nr5

18

এই সমস্যাটি মোকাবেলার জন্য কয়েকটি উপায় রয়েছে।

একটি উপায় হ'ল আপনি সংগ্রহ দর্শনের প্রবাহের বিন্যাসটিকে আনুমানিক আকার এবং কক্ষের আকার গণনা করতে পারেন।

দ্রষ্টব্য: নীচের মন্তব্যে যেমন উল্লিখিত হয়েছে, আইওএস 10 এর হিসাবে আপনাকে কোনও সেলতে কলটি ট্রিগার করতে আপনার আর সরবরাহের অনুমানের প্রয়োজন হবে না func preferredLayoutAttributesFitting(_ layoutAttributes:)। পূর্বে (আইওএস 9) এর জন্য আপনাকে একটি প্রাক্কলিত আকার সরবরাহ করতে হবে যদি আপনি কোনও সেল প্রাক-লেয়ারআউটঅ্যাট্রিবিউটগুলি কোয়েরি করতে চান।

(ধরে নিই যে আপনি স্টোরিবোর্ড ব্যবহার করছেন এবং সংগ্রহের ভিউ আইবির মাধ্যমে সংযুক্ত রয়েছে)

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
(আনুমানিক আইটেমসাইজ সহ অন্তর্ভুক্ত বা না করে বর্তমান আইওএসে কোনও পার্থক্য নেই এবং কোনওভাবেই "সম্পূর্ণ প্রস্থ + গতিশীল উচ্চতা" ইস্যুতে কোনও সহায়তা নেই)) কোডটির শেষে, নিবগুলি আজকাল খুব কমই ব্যবহৃত হয় এবং এটিতে রয়েছে গতিশীল উচ্চতার সাথে সামান্য প্রাসঙ্গিকতা (উদাহরণস্বরূপ, কয়েকটি গতিশীল উচ্চতার পাঠ্য দর্শনগুলি)। ধন্যবাদ যদিও
ফ্যাটি

আমি এই সমাধানটিতেও পৌঁছেছি, তবে আমার ক্ষেত্রে, আইওএস 11, এক্সকোড 9.2, সেল সামগ্রীগুলি সেল থেকে নিজেই সংযোগ বিচ্ছিন্ন বলে মনে হয়েছিল - আমি নির্দিষ্ট মাত্রার পূর্ণ উচ্চতা বা প্রস্থে প্রসারিত করার জন্য কোনও চিত্র পেতে পারি না। আমি আরও লক্ষ্য করেছি যে সিভি সেটিংসের সীমাবদ্ধতা ছিল preferredLayoutAttributesFitting। আমি তখন ফাংশনটিতে আমার নিজের বাধা যুক্ত করে আনুমানিক আইটেম সাইজ, এফডাব্লুআইডাব্লু থেকে স্থির মাত্রায় বাধ্য হয়ে নীচে আমার উত্তরটি দেখুন।
ক্রিস কনভারের

16

আমি এই সমস্যার জন্য একটি খুব সহজ সমাধান পেয়েছি: আমার সংগ্রহেভিউসিলের অভ্যন্তরে আমি একটি ইউআইভিউ () পেয়েছি যা আসলে একটি পটভূমি। পূর্ণ প্রস্থ পেতে আমি নিম্নলিখিত অ্যাঙ্করগুলি সেট করেছি set

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

"যাদু" প্রথম লাইনে ঘটে। আমি স্ক্রিনের প্রস্থে গতিবেগভাবে প্রস্থআন্সারকে সেট করেছি। আপনার সংগ্রহভিউয়ের ইনসেটগুলি বিয়োগ করাও গুরুত্বপূর্ণ। অন্যথায় ঘরটি প্রদর্শিত হবে না। আপনি যদি এই জাতীয় পটভূমি দেখতে না চান তবে কেবল এটি অদৃশ্য করুন।

ফ্লোএলআউট নিম্নলিখিত সেটিংস ব্যবহার করে

layout.itemSize = UICollectionViewFlowLayoutAutomaticSize
layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize

ফলাফলটি গতিশীল উচ্চতা সহ একটি পূর্ণ প্রস্থের আকারের ঘর।

এখানে চিত্র বর্ণনা লিখুন


1
পবিত্র গরু - এটি আশ্চর্যজনক! একদমই সুস্পষ্ট ! উজ্জ্বল!
ফ্যাটি

1
শুধু টিবিসি @ inf1783, আপনি এটি ইউআইকিলেকশনভিউতে করছেন? (টেবিল দেখুন নয়) - সঠিক?
ফ্যাটি

1
@ ফ্যাটি হ্যাঁ, এটি একটি ইউআইকোলিকেশনভিউ;)
inf1783

চমত্কার @ inf1783, এটি চেষ্টা করে দেখার অপেক্ষা করতে পারে না। যাইহোক, এটি করার আরেকটি ভাল উপায় হ'ল ইউআইভিউ সাবক্লাস করা এবং কেবল একটি অন্তর্নির্মিত প্রস্থ যুক্ত করা (আমি ধারণা করছি এটির একই প্রভাব হবে, এবং এটি সম্ভবত স্টোরিবোর্ডের সময় এটিও কাজ করবে)
ফ্যাটি

1
প্রতিবার যখনই আমি এটি চেষ্টা করি তখন ইউআইকিলেকশন ভিউফ্লোলোআউট এর আচরণের সাথে অন্তহীন লুপটি শেষ করি না: /
Skodik.o

7

কাজ !!! আইওএস-তে পরীক্ষা করা হয়েছে: 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
    }


}

কাস্টমসেল শ্রেণী:

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))
    }

}

প্রধান উপাদান হ'ল কাস্টমসেলে সিস্টেমলাউট সাইজ ফিটিং ফাংশন। এছাড়াও আমাদের সীমাবদ্ধতার সাথে দৃশ্যের প্রস্থ নির্ধারণ করতে হবে।


6

কালেকশনভিউসেলকে আপনাকে প্রস্থের সীমাবদ্ধতা যুক্ত করতে হবে

class SelfSizingCell: UICollectionViewCell {

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

অবশেষে কেউ এটিকে দুটি লাইনে নিখুঁত করেছেন
ওমর এন শামালি

এটি সেলকে একটি নির্দিষ্ট প্রস্থে সীমাবদ্ধ করবে, খুব কমই স্ব-আকার দেবে। আপনি যদি কোনও আইপ্যাডে ডিভাইসটি ঘোরান বা স্ক্রিনের আকারটি সামঞ্জস্য করতে চান তবে এটি স্থির থাকবে।
টমাস ভারবিক

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()
        }
    
        ...
    }

পুরো উদাহরণ

আইওএস 11-তে পরীক্ষা করা হয়েছে।


3

ব্যক্তিগতভাবে আমি ইউআইকোলিকেশনভিউয়ের সর্বোত্তম উপায়গুলি খুঁজে পেয়েছি যেখানে মাপ নির্ধারণের জন্য একটি আসল সেল ব্যবহার করার সময় প্রতিটি সেল পৃথক আকারের থাকতে পারে যখন অটোলয়েট আকারটি নির্ধারণ করতে পারে তবে ইউআইসিএল্লেশনভিউ ডেলিগেটফ্লোএলআউট আকারের আইটেমএটিএন্ডেক্সপথ ফাংশনটি প্রয়োগ করা হয়।

আমি আমার ব্লগ পোস্টে এই সম্পর্কে কথা বললাম

আশা করি এটি একটি যা আপনি চান তা অর্জনে সহায়তা করবে। আমি ১০০% নিশ্চিত নই তবে আমি ইউআইটিএবলভিউয়ের বিপরীতে বিশ্বাস করি যেখানে আপনি স্বয়ংক্রিয়ভাবে লেআউটআউট সংযোগ ব্যবহার করে কোষগুলির সম্পূর্ণ স্বয়ংক্রিয় উচ্চতা রাখতে পারবেন

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 44

ইউআইকোলিকেশনভিউতে অটোলআউটটিকে আকার নির্ধারণ করার মতো উপায় নেই কারণ ইউআইসিকলিকেশনভিউসেল অগত্যা স্ক্রিনের পুরো প্রস্থটি পূরণ করে না।

তবে এখানে আপনার জন্য একটি প্রশ্ন রয়েছে : আপনার যদি পূর্ণ পর্দার প্রস্থের ঘরগুলির প্রয়োজন হয় তবে আপনি কেন একটি ভাল পুরানো ইউআইটিবেল ভিউতে ইউআইসিএল্লেশনভিউ ব্যবহার করে বিরক্ত করবেন না যা অটো সাইজিং কোষগুলির সাথে আসে?


এটা ধরে রাখুন, Aprit নিচে বলছে যে UICollectionViewFlowLayoutAutomaticSize এখন প্রবাহ বিন্যাস পাওয়া যায়, iOS10 করুন ...
Fattie

আমিও ঠিক এই দেখেছি। স্পষ্টতই আইওএস ১০-এ এখন কোনও জিনিস রয়েছে I আমি কেবলমাত্র এটি সম্পর্কিত ডাব্লুডাব্লুডিসির আলাপ দেখেছি: বিকাশকারী.অ্যাপল. com/ভিডিওস / প্লে /wwdc2016/219 তবে, এটির সামগ্রীতে ফিট করার জন্য এটি সেলটি পুরোপুরি অটোসাইজ করবে। আমি নিশ্চিত না যে আপনি কীভাবে সেলটি (স্ক্রিনের প্রস্থ পূরণ করতে) স্ক্রিনের প্রস্থ পূরণ করতে পারবেন যেহেতু আপনি ইউআইকিলেকশনভিউসেল এবং তার পিতামাতার (অন্তত স্টোরিবোর্ডে নয়) সীমাবদ্ধ করতে পারবেন না
xxtesaxx

ঠিক আছে। আমরা মনে করি এই অবিশ্বাস্যভাবে সুস্পষ্ট সমস্যার আসল সমাধানের খুব কাছে নেই। : /
ফ্যাটি

আলাপ অনুসারে, আপনি এখনও আকারটি্যাটফিট () বা পছন্দসই লেআউটআট্রিবিউজস ফিটিং () ওভাররাইট করতে পারেন এবং নিজেই আকারটি গণনা করতে পারেন তবে ওপি আমার কাছে যা বলেছে তা বলে না। যাইহোক, আমি তার এখনও যখন তার পুরো প্রস্থের ইউআইসিএল্লেশনভিউসেল প্রয়োজন হয় এবং এই নির্দিষ্ট ক্ষেত্রে কোনও ইউআইটিএলভিউ ব্যবহার না করা কেন এত বড় বিষয় হবে তা নিশ্চিত হয়ে উঠতে হবে (অবশ্যই কিছু নির্দিষ্ট ক্ষেত্রে থাকতে পারে তবে আমার ধারণা) আপনাকে কেবল কিছু গণনা নিজেই
করাতে হবে

এটির বিষয়ে চিন্তা করা, এটি বেশ অবিশ্বাস্য যে আপনি কেবলমাত্র "কলামগুলি == 1" সেট করতে পারবেন না (এবং তারপরে সম্ভবত ডিভাইসটি পাশের কলামগুলি == 2) সংগ্রহের দর্শন সহ with
ফ্যাটি

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) 
  }
}

তারপরে ভিউ কন্ট্রোলারে যেখানে অটোলেআউট সীমাবদ্ধতা পরিবর্তিত হয়, আমি একটি এনএসএনটিফিকেশন বন্ধ করে দিই।

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

আমার ইউআইসিকলিকেশনভিউ সাবক্লাসে, আমি এই বিজ্ঞপ্তিটি শুনছি:

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

এবং লেআউটটি অবৈধ করুন:

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

এটি sizeForItemAtকালেকশন ভিউর নতুন আকার ব্যবহার করে আবার কল করার কারণ ঘটায় । আপনার ক্ষেত্রে, এটি লেআউটে উপলব্ধ নতুন প্রতিবন্ধকতাগুলি আপডেট করে আপডেট করতে সক্ষম হওয়া উচিত।


শুধু টিবিসি মার্কের অর্থ কী আপনি আসলে কোনও ঘরের আকার পরিবর্তন করছেন ? (উদাহরণস্বরূপ, ঘরটি উপস্থিত হবে এবং এটি আকারের আকার X, তারপরে আপনার অ্যাপে কিছু ঘটে এবং এটি আকার Y হয়ে যায় ..?) থেক্স
ফ্যাটি

হ্যাঁ. যখন ব্যবহারকারী স্ক্রিনে কোনও উপাদান টেনে আনেন, একটি ইভেন্ট আগুন দেয় যা ঘরের আকার আপডেট করে।
সুমন

1

আপনার উপর viewDidLayoutSubviews, estimatedItemSizeপূর্ণ প্রস্থ সেট করুন (লেআউটটি ইউআইকোলিকেশনভিউ ফ্লোলয়আউট অবজেক্টকে বোঝায়):

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

আইওএস 10 থেকে, এটি করতে আমরা প্রবাহ বিন্যাসে নতুন এপিআই পেয়েছি।

আপনাকে যা করতে হবে তা হ'ল flowLayout.estimatedItemSizeএকটি নতুন ধ্রুবকটিতে সেট করা UICollectionViewFlowLayoutAutomaticSize

উৎস


হুম, আপনি নিশ্চিত যে এটি * পুরো প্রস্থের করে তোলে ? সুতরাং, মূলত একটি কলাম?
ফ্যাটি

আপনি যদি ইউআইকোলিকেশনভিউসেল এর প্রস্থকে সম্পূর্ণ প্রস্থে স্পষ্টভাবে সেট করেন তবে এটি হতে পারে।
অর্পিত ডংরে

না, এটি প্রস্থটি পুরো উচ্চতায় স্থির করে না, এবং যদি আপনি উপরে এরিকের উত্তর অনুসরণ না করেন বা নীচে / পরে আমার অনুসরণ না করেন তবে অনুমিত আকারের মানটিকে উপেক্ষা করে।
ক্রিস কনভারের

ঠিক আছে, দুর্ভাগ্যক্রমে তখন সমস্যার সাথে একেবারেই কোনও সংযোগ নেই! হেহ! : ও
ফ্যাটি

0

অটোলাউট 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

আপনার সংগ্রহে ভিউকন্ট্রোলারের ইউআইসিএল্লেশনভিউডেলিগেটফ্লোএলআউট ক্লাসটি উত্তরাধিকারী হতে হবে। তারপরে ফাংশনটি যুক্ত করুন:

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

এটি ব্যবহার করে, আপনার পর্দার প্রস্থের প্রস্থের আকার রয়েছে।

এবং আপনার কাছে এখন টেবিলভিউ কনট্রোলার হিসাবে সারি সহ একটি সংগ্রহ ভিউকন্ট্রোলার রয়েছে।

আপনি যদি প্রতিটি কক্ষের উচ্চতার আকার গতিশীল হতে চান তবে আপনার প্রয়োজন প্রতিটি ঘরের জন্য আপনার নিজের পছন্দসই ঘর তৈরি করা উচিত।


7
এটি ঠিক এই প্রশ্নের উত্তর নয় :) এটি 100 এর একটি নির্দিষ্ট উচ্চতা দেবে, যেমন, অটোলেআউট এমনকি অস্তিত্বের আগেই কীভাবে কোনও প্রোগ্রাম করা হয়েছিল।
ফ্যাটি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.