অনুভূমিকভাবে ইউআইসিকলিকেশনভিউ সেলগুলি কীভাবে কেন্দ্র করবেন?


123

আমি কিছু গবেষণা করেছি, তবে কোনও ইউআইকোলিকেশনভিউতে অনুভূমিকভাবে কীভাবে সেলগুলি কেন্দ্র করতে হবে তার কোনও কোড উদাহরণ খুঁজে পেলাম না।

প্রথম সেলটি এই এক্স 100 এর মতো হওয়ার পরিবর্তে , আমি এটি 0x0 এর মতো হওয়া চাই । এই কাজ করা সম্ভব কোনো উপায় আছে কি?

সম্পাদনা করুন:

আমি যা চাই তা কল্পনা করতে:

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

কালেকশনভিউতে যখন কেবল একটি উপাদান রয়েছে তখন আমার কাছে এটি সংস্করণ বি এর মতো দেখতে প্রয়োজন। যখন আমি একাধিক উপাদান পেয়েছি তখন এটি সংস্করণ এ এর ​​মতো হওয়া উচিত তবে আরও উপাদান সহ।

এই মুহুর্তে এটি সংস্করণ A এর মতো দেখায় যখন আমার কাছে কেবলমাত্র 1 টি উপাদান রয়েছে এবং আমি ভাবছি যে আমি কীভাবে এটি বি এর মতো দেখতে পারি wonder

সাহায্যের জন্য ধন্যবাদ!


ঘরটি সংগ্রহের প্রস্থের প্রস্থের সাথে মাপসই করা এবং তারপরে সংগ্রহটি নিজের পিতামাতার মধ্যেই দেখার পক্ষে কী সহজ নয়?
আর্থার গেভোরকায়ান

হ্যাঁ, এটি করার কমপক্ষে দুটি উপায় রয়েছে, প্রথম (দ্রুত) হ'ল পুরো স্ক্রিনের ঘর প্রস্থ তৈরি করা এবং তার চাইল্ড ভিউটি কেন্দ্র করা। দ্বিতীয় (ডান) কাস্টম সংগ্রহ ভিউ বিন্যাসটি বাস্তবায়ন করুন
সেজে 444

ব্যাকএন্ড থেকে অবশেষে আরও কক্ষগুলি আসবে, পুরো প্রস্থটি পূরণ করা ভাল ধারণা হবে না
রাপটক্স

প্রস্থ বৃদ্ধি কেন্দ্রে সেট করতে যথেষ্ট
কিশোর কুমার

উত্তর:


227

লাইব্রেরিটি ব্যবহার করা ভাল ধারণা নয়, যদি আপনার উদ্দেশ্যটি কেবল এইভাবে হয় তবে কেন্দ্র বিন্যস্ত করা।

আপনার সংগ্রহেভিউ লেআউট ফাংশনে আপনি এই সাধারণ গণনাটি আরও ভাল করতে পারেন।

func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {

    let totalCellWidth = CellWidth * CellCount
    let totalSpacingWidth = CellSpacing * (CellCount - 1)

    let leftInset = (collectionViewWidth - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
    let rightInset = leftInset

    return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}

2
@ দর্শনাপেটেল.আপনার প্রচুর উত্তরের জন্য আমি এটি প্রয়োগ করেছি এবং সারিগুলি যেমনটি হওয়া উচিত ঠিক তেমনই এসেছিল তবে এখন সমস্যাটি হ'ল আমি প্রথম আইটেমটিতে স্ক্রোল করতে পারছি না। আমি যখন প্রথম আইটেমটিতে স্ক্রোল করার চেষ্টা করি তখন তা আমাকে পরিবর্তিত ইউআইইডিজিনসেটে ফিরিয়ে আনবে। আপনি আমার ডেমো অ্যাপটি দেখতে পারবেন github.com/anirudha- সঙ্গীত
অনিরুদ্ধ

5
সুইফ্ট 3-এ, নতুন পদ্ধতির স্বাক্ষর collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int)
কামচাতকা

1
আপনি কীভাবে সেলউইথকে দখল করতে সক্ষম হবেন, এটি কীভাবে সেলফোর্ডআইট্যাট পদ্ধতিতে সম্ভব? আমি চেষ্টা করেছিলাম এবং এটি ফিরে পেল না .. পর্দার আকারের উপর ভিত্তি করে আমার জন্য সেল প্রস্থ পরিবর্তিত হয়েছে .. @ দর্শনাপ্যাটেল।
ক্রিস

10
@DarshanPatel। আপনার উত্তরটি মাঝে মাঝে ছোট ডিভাইসে নেতিবাচক মান তৈরি করতে পারে। আপনি leftInsetযেমন মূল্য সর্বাধিক চেক ব্যবহার বিবেচনা করুন :let leftInset = max(0.0, (self.collectionView.bounds.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2)
Rhuari Glen

3
আপনি যদি ইউআইকোলিকেশনভিউ কনট্রোলার সাবক্লাসিং না করে থাকেন তবে নিশ্চিত করুন যে আপনার ক্লাসটি ইউআইসিএলকশনভিউডেলিগেটফ্লোএলআউটে মেনে চলেছে অন্যথায় এটি কাজ করবে না
সাইদ ইর

59

সুইফট 5.1

func centerItemsInCollectionView(cellWidth: Double, numberOfItems: Double, spaceBetweenCell: Double, collectionView: UICollectionView) -> UIEdgeInsets {
    let totalWidth = cellWidth * numberOfItems
    let totalSpacingWidth = spaceBetweenCell * (numberOfItems - 1)
    let leftInset = (collectionView.frame.width - CGFloat(totalWidth + totalSpacingWidth)) / 2
    let rightInset = leftInset
    return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)
}

সুইফট 4.2

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

    let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
    let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)

    let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
    let rightInset = leftInset

    return UIEdgeInsets(top: 0, left: leftInset, bottom: 0, right: rightInset)

}

সুইফট 3

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {

        let totalCellWidth = 80 * collectionView.numberOfItems(inSection: 0)
        let totalSpacingWidth = 10 * (collectionView.numberOfItems(inSection: 0) - 1)

        let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
        let rightInset = leftInset

        return UIEdgeInsetsMake(0, leftInset, 0, rightInset)

    }

প্রোটোকল যুক্ত করতে ভুলবেন না

UICollectionViewDelegateFlowLayout

বাঁধা হতে পারে @ashforIos
আহমেদ সাফাদি

আপনার উত্তরটি ঠিকঠাক কাজ করে যখন সংগ্রহগুলিতে ফিট করে এমন সেল রয়েছে যখন ঘরের সংখ্যা বাড়লে সেলগুলি কেন্দ্র হয় এবং আপনি প্রথম কক্ষে বা শেষের দিকে স্ক্রোল করতে পারবেন না iew
নিককডার

2
@ ভিটালি ৮০ মানে সেল প্রস্থ এবং দশটি কক্ষের মধ্যে স্থান, আপনি যদি পরিবর্তনশীল নামটি পড়েন তবে আপনি এর অর্থটি বুঝতে পারবেন: পি
আহমেদ সাফাদি

সুইফট 4.2 সমাধানটি সহজ, ধন্যবাদ! আপনার আসল সেল-অবজেক্টের প্রস্থ যাই হোক না কেন কেবল "80" সেট করতে ভুলবেন না।
জন পিটস

25

সুইফট 4 এর জন্য এটি ব্যবহার করে দেখুন

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        let cellWidth : CGFloat = 165.0

        let numberOfCells = floor(self.view.frame.size.width / cellWidth)
        let edgeInsets = (self.view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)

        return UIEdgeInsetsMake(15, edgeInsets, 0, edgeInsets)
    }

165.0 পরিবর্তে আপনার সেলউইথ যুক্ত করুন


1
এটি সেরা উত্তর। এটিতে সবচেয়ে সহজ গণিত। যে কোনও সংখ্যক সারি এবং কলামের সাথে কাজ করে
27:59

20

আমি এর জন্য কেটিসিটিন্টারফ্লোএলআউট ব্যবহার করি এবং এটি দুর্দান্ত কাজ করে। এটি আপনার পছন্দমতো UICollectionViewFlowLayoutকেন্দ্রের ঘরগুলির একটি কাস্টম সাবক্লাস । (দ্রষ্টব্য: কিছু কোড পোস্ট করার মাধ্যমে এটি সমাধান করা তুচ্ছ বিষয় নয়, এ কারণেই আমি একটি গিটহাব প্রকল্পের সাথে সংযুক্ত করছি!)


আইবি থেকে এটি কাজ করতে পারেনি। এই গ্রন্থাগারটি আমার জন্য কবজির মতো কাজ করেছিল। সবেমাত্র পোড ইনস্টল করেছেন এবং আইবিতে লেআউটের শ্রেণি বদল করেছেন!
ট্যাগিরকাজেড

15

দর্শন প্যাটেলের উত্তরের একটি উদ্দেশ্য-সি সংস্করণ :

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    CGFloat totalCellWidth = kItemWidth * self.dataArray.count;
    CGFloat totalSpacingWidth = kSpacing * (((float)self.dataArray.count - 1) < 0 ? 0 :self.dataArray.count - 1);
    CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
    CGFloat rightInset = leftInset;
    UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
    return sectionInset;
}

ধন্যবাদ। একক সারিতে এটি কাজ করছে fine তবে একাধিক সারিতে সমস্যা তৈরি হচ্ছে। আমি স্ক্রিন শটটি দেখতে এখানে url যুক্ত করতে সক্ষম নই। । তবে আপনি ক্ষুদ্র ইউআরএলে "yynoalzg" যুক্ত করতে পারেন। আপনি ধারণা পাবেন। সোনার বিভাগে 4 টি রেকর্ড রয়েছে। চতুর্থটি নতুন লাইনে হওয়া উচিত। .কিন্তু এই পদ্ধতির পরে এটি এরকম প্রদর্শিত হয় ... কোনও ধারণা থাকলে আমাকে জানান।
হিতার্থ

6

@ সাফাদ ফানির উত্তরটি সামান্যভাবে সংশোধন করা, এটি আমার জন্য সুইফট এবং আইওএসের সর্বশেষতম সংস্করণে কাজ করেছে। এই ক্ষেত্রে আমি কক্ষগুলির প্রস্থ সংগ্রহের আকারের তৃতীয় হতে চাই wanted

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

  let totalCellWidth = Int(collectionView.layer.frame.size.width) / 3 * collectionView.numberOfItems(inSection: 0)
  let totalSpacingWidth = (collectionView.numberOfItems(inSection: 0) - 1)

  let leftInset = (collectionView.layer.frame.size.width - CGFloat(totalCellWidth + totalSpacingWidth)) / 2
  let rightInset = leftInset

  return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}

2
এটি আমার জন্য বিশেষত কাজ করেছিল, যখন কেবলমাত্র একটি ঘর রয়েছে।
দাশোগা

6

আপনি এই এক্সটেনশনটি ব্যবহার করতে পারেন (সুইফট 4)।

এটি আপনার সাথে থাকলে সেলগুলি কেন্দ্র করে রাখতে collectionViewপারেlayout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize

এটি কোনও কক্ষের আকারের সাথে কাজ করে এবং যখন পুরোপুরি কাজ করে scrollDirection = .horizontal

public extension UICollectionView {
    func centerContentHorizontalyByInsetIfNeeded(minimumInset: UIEdgeInsets) {
        guard let layout = collectionViewLayout as? UICollectionViewFlowLayout,
            layout.scrollDirection == .horizontal else {
                assertionFailure("\(#function): layout.scrollDirection != .horizontal")
                return
        }

        if layout.collectionViewContentSize.width > frame.size.width {
            contentInset = minimumInset
        } else {
            contentInset = UIEdgeInsets(top: minimumInset.top,
                                        left: (frame.size.width - layout.collectionViewContentSize.width) / 2,
                                        bottom: minimumInset.bottom,
                                        right: 0)
        }
    }
}


final class Foo: UIViewController {
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        collectionView.centerContentHorizontalyByInsetIfNeeded(minimumInset: yourDefaultInset)
    }
}

আশা করি এটি আপনাকে সাহায্য করবে!


1
ত্রুটি পেতে: থ্রেড 1: EXC_BAD_ACCESS (কোড = 2, ঠিকানা = 0x118ffde58)
অতুলখাত্রি

4

সুইফট 4.2 (অনুভূমিকভাবে এবং উল্লম্বভাবে) এটি গোলাপী প্যান্থার কোডটির ছোট আপগ্রেড এবং তাকে ধন্যবাদ!


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    let cellWidth: CGFloat = flowLayout.itemSize.width
    let cellHieght: CGFloat = flowLayout.itemSize.height
    let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
    let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
    var collectionWidth = collectionView.frame.size.width
    var collectionHeight = collectionView.frame.size.height
    if #available(iOS 11.0, *) {
        collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
        collectionHeight -= collectionView.safeAreaInsets.top + collectionView.safeAreaInsets.bottom
    }
    let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
    let totalHieght = cellHieght * cellCount + cellSpacing * (cellCount - 1)
    if totalWidth <= collectionWidth {
        let edgeInsetWidth = (collectionWidth - totalWidth) / 2

        print(edgeInsetWidth, edgeInsetWidth)
        return UIEdgeInsets(top: 5, left: edgeInsetWidth, bottom: flowLayout.sectionInset.top, right: edgeInsetWidth)
    } else {
        let edgeInsetHieght = (collectionHeight - totalHieght) / 2
        print(edgeInsetHieght, edgeInsetHieght)
        return UIEdgeInsets(top: edgeInsetHieght, left: flowLayout.sectionInset.top, bottom: edgeInsetHieght, right: flowLayout.sectionInset.top)

    }
}

নিশ্চিত করুন যে আপনার শ্রেণি ইউআইসিএল্লেশনভিউডেলিগেটফ্লোএলআউট প্রোটোকলে মেনে চলেছে


সত্যিই আপনার কোডটি আমার পক্ষে দুর্দান্ত কাজ করে, ধন্যবাদ ডুড; )
স্টিভসারসাওয়া

4

এখানে সুইফট 5-র জন্য নতুন সংস্করণ রয়েছে যা ঘরগুলি একাধিক সারির চেয়ে বেশি হলে এটিও ঠিক কাজ করে:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    let cellWidth: CGFloat = flowLayout.itemSize.width
    let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
    var cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
    var collectionWidth = collectionView.frame.size.width
    var totalWidth: CGFloat
    if #available(iOS 11.0, *) {
        collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
    }
    repeat {
        totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
        cellCount -= 1
    } while totalWidth >= collectionWidth

    if (totalWidth > 0) {
        let edgeInset = (collectionWidth - totalWidth) / 2
        return UIEdgeInsets.init(top: flowLayout.sectionInset.top, left: edgeInset, bottom: flowLayout.sectionInset.bottom, right: edgeInset)
    } else {
        return flowLayout.sectionInset
    }
}

নিশ্চিত করুন যে আপনার বর্গ দয়া করে কনর্ফাম করার UICollectionViewDelegateFlowLayoutপ্রোটোকল।


3

সুইফট 4

extension ViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {

        let cellWidth: CGFloat = 170.0 // Your cell width

        let numberOfCells = floor(view.frame.size.width / cellWidth)
        let edgeInsets = (view.frame.size.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)

        return UIEdgeInsetsMake(0, edgeInsets, 0, edgeInsets)
    }

 }

2

যে সমস্ত লোকেরা কেবল একটি প্যাডিং যুক্ত করতে চান ( উপরে, বাম, নীচে, ডান ):

প্রোটোকল যুক্ত করুন UICollectionViewDelegateFlowLayout

এই উদাহরণটি 40 সহ একটি প্যাডিং বাম এবং ডান দেখায়।

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {        
    return UIEdgeInsetsMake(0, 40, 0, 40)
}

2

সুইফট 4.2

private lazy var contentView: UICollectionView = {
        let layoutView: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
            layoutView.scrollDirection = .horizontal
            layoutView.minimumInteritemSpacing = 0
            layoutView.minimumLineSpacing = 5

        let collectionView: UICollectionView = UICollectionView(frame: .zero, collectionViewLayout: layoutView)
            collectionView.dataSource = self
            collectionView.delegate = self
            collectionView.showsHorizontalScrollIndicator = false
            collectionView.isPagingEnabled = true
            collectionView.registerCell(Cell.self)
            collectionView.backgroundColor = .clear
            collectionView.translatesAutoresizingMaskIntoConstraints = false
        return collectionView
    }()

//

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

        return CGSize(width: collectionView.frame.width*4/5, height: collectionView.frame.height)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        let cellWidth : CGFloat = collectionView.frame.width*4/5

        let numberOfCells = floor(collectionView.frame.width / cellWidth)
        let edgeInsets = (collectionView.frame.width - (numberOfCells * cellWidth)) / (numberOfCells + 1)

        return UIEdgeInsets(top: 0, left: edgeInsets, bottom: 0, right: edgeInsets)
    }
}

1

আপনি আমার সমাধানটি চেষ্টা করতে পারেন এটি কার্যকর হয়,

func refreshCollectionView(_ count: Int) {
    let collectionViewHeight = collectionView.bounds.height
    let collectionViewWidth = collectionView.bounds.width
    let numberOfItemsThatCanInCollectionView = Int(collectionViewWidth / collectionViewHeight)
    if numberOfItemsThatCanInCollectionView > count {
        let totalCellWidth = collectionViewHeight * CGFloat(count)
        let totalSpacingWidth: CGFloat = CGFloat(count) * (CGFloat(count) - 1)
        // leftInset, rightInset are the global variables which I am passing to the below function
        leftInset = (collectionViewWidth - CGFloat(totalCellWidth + totalSpacingWidth)) / 2;
        rightInset = -leftInset
    } else {
        leftInset = 0.0
        rightInset = -collectionViewHeight
    }
    collectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
}

1

গৃহীত উত্তর সঠিক উত্তর কিন্তু যদি আপনার totalCellWidthচেয়ে কম হয় CollectionViewএর widthআপনি নীচের হিসাবে কাজ করতে পারেন এই বিরুদ্ধে, কিন্তু পাহারা রয়েছে।

if (leftInset > 0) {
     return UIEdgeInsetsMake(0, leftInset, 0, rightInset)
  } else {
     return UIEdgeInsetsMake(0, 10, 0, 10)
}

1

এই কোডটি কোনও পরিবর্তন ছাড়াই এমনকি সুইফট ৪.০ এ অনুভূমিকভাবে সংগ্রহের ভিউকে কেন্দ্র করা উচিত :

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    let cellWidth: CGFloat = flowLayout.itemSize.width
    let cellSpacing: CGFloat = flowLayout.minimumInteritemSpacing
    let cellCount = CGFloat(collectionView.numberOfItems(inSection: section))
    var collectionWidth = collectionView.frame.size.width
    if #available(iOS 11.0, *) {
        collectionWidth -= collectionView.safeAreaInsets.left + collectionView.safeAreaInsets.right
    }
    let totalWidth = cellWidth * cellCount + cellSpacing * (cellCount - 1)
    if totalWidth <= collectionWidth {
        let edgeInset = (collectionWidth - totalWidth) / 2
        return UIEdgeInsetsMake(flowLayout.sectionInset.top, edgeInset, flowLayout.sectionInset.bottom, edgeInset)
    } else {
        return flowLayout.sectionInset
    }
}

আপনার ক্লাসটি UICollectionViewDelegateFlowLayoutপ্রোটোকল অনুসারে তা নিশ্চিত করুন


0

আমি এখানে সম্পূর্ণ ভিন্ন পদ্ধতির অবলম্বন করে শেষ করেছি, যা আমি বিশ্বাস করি যে উল্লেখযোগ্য।

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

let newWidth = (items.count * cellWidth) + (items.count * cellSpacing)

তারপরে আমি .constantগণনার ফলাফলের জন্য সীমাবদ্ধতার আউটলেটটির মান সেট করেছিলাম এবং বাকীটি অটোলেআউট করে।

এটি `ইউআইসি কালেকশনভিউডেলিগেটফ্লোএলআউটের সাথে দ্বন্দ্ব করতে পারে তবে বাম-ন্যায়সঙ্গত সংগ্রহের দৃশ্য তৈরি করতে আমার পক্ষে এটি পুরোপুরি কাজ করেছে। কোনও প্রতিনিধি ছাড়াই, কেবলমাত্র ঘরগুলি যখন ভিউটির বেশিরভাগ অংশ পূরণ করে তখন এটি কাজ করে বলে মনে হয়।


0

ফ্লোআউটআউটের সাধারণ সমাধান যা পৃষ্ঠাগুলি প্রস্থের চেয়ে কম হলে কেন্দ্রগুলি এবং আরও বেশি থাকলে বামে সারিবদ্ধ করে

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(nonnull UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    // Centering if there are fever pages
    CGSize itemSize = [(UICollectionViewFlowLayout *)collectionViewLayout itemSize];
    CGFloat spacing = [(UICollectionViewFlowLayout *)collectionViewLayout minimumLineSpacing];

    NSInteger count = [self collectionView:self numberOfItemsInSection:section];
    CGFloat totalCellWidth = itemSize.width * count;
    CGFloat totalSpacingWidth = spacing * ((count - 1) < 0 ? 0 : count - 1);
    CGFloat leftInset = (self.bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2;
    if (leftInset < 0) {
        UIEdgeInsets inset = [(UICollectionViewFlowLayout *)collectionViewLayout sectionInset];
        return inset;
    }
    CGFloat rightInset = leftInset;
    UIEdgeInsets sectionInset = UIEdgeInsetsMake(0, leftInset, 0, rightInset);
    return sectionInset;
}

সুইফ্ট সংস্করণ (ওবিজেসি থেকে রূপান্তরিত)

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    // Centering if there are fever pages
    let itemSize: CGSize? = (collectionViewLayout as? UICollectionViewFlowLayout)?.itemSize
    let spacing: CGFloat? = (collectionViewLayout as? UICollectionViewFlowLayout)?.minimumLineSpacing

    let count: Int = self.collectionView(self, numberOfItemsInSection: section)
    let totalCellWidth = (itemSize?.width ?? 0.0) * CGFloat(count)
    let totalSpacingWidth = (spacing ?? 0.0) * CGFloat(((count - 1) < 0 ? 0 : count - 1))
    let leftInset: CGFloat = (bounds.size.width - (totalCellWidth + totalSpacingWidth)) / 2
    if leftInset < 0 {
        let inset: UIEdgeInsets? = (collectionViewLayout as? UICollectionViewFlowLayout)?.sectionInset
        return inset!
    }
    let rightInset: CGFloat = leftInset
    let sectionInset = UIEdgeInsets(top: 0, left: Float(leftInset), bottom: 0, right: Float(rightInset))
    return sectionInset
}

শিরোনামহীন-3.png


সুইফট কোডের সীমা কী? আমি অমীমাংসিত শনাক্তকারী '
গণ্ডি

হাই, আমার উদাহরণে আমি একটি ইউআইভিউ-র ভিতরে পদ্ধতিটি প্রয়োগ করেছি, যার সীমানা রয়েছে, আপনি যদি এটি অন্য কোথাও প্রয়োগ করছেন, উপযুক্ত সীমানা ব্যবহার করুন
পিটার লাপিসু

0

প্রকল্পে আমার একই অবস্থা রয়েছে এবং উল্লেখ করে আমি এটি ঠিক করেছি UPCarouselFlowLayout

আমি মনে করি এটি swift 5সংস্করণ সমর্থন করে

https://github.com/ink-spot/UPCarouselFlowLayout/blob/master/UPCarouselFlowLayout/UPCarouselFlowLayout.swift

কোড বাস্তবায়ন দেখুন

override open func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint

0

সবচেয়ে সহজ উপায় হ'ল স্টোরিবোর্ডে বা কোড সহ কোনওটিতে সংগ্রহের ভিউ অনুমানের আকার সেট করা layout.estimatedItemSize = CGSize.zero


0

যদি গ্রুপ প্রতি এক সেল, একটি কেবল রুম leading:এবং trailing:এর .flexible(0)অনুভূমিকভাবে সেল কেন্দ্র হবে:

item.edgeSpacing = NSCollectionLayoutEdgeSpacing(
    leading: .flexible(0), top: nil,                                                     
    trailing: .flexible(0), bottom: nil
)

0

আমি একটি প্রকল্পে সেই কোডটি ব্যবহার করেছি। এটি সংগ্রহের কেন্দ্রটিকে অনুভূমিকভাবে এবং উল্লম্বভাবে উভয় দিক .horizontalএবং .verticalবিভাগের ইনসেটগুলি ব্যবহার করে কেন্দ্র করে। সেট করা থাকলে স্পেসিং এবং বিভাগটির মূল ইনসেটকে সম্মান করে। প্রতিনিধিটিতে ব্যবহারের কোড যাতে আমাদের পুনরায় ব্যবহারযোগ্যতার জন্য স্টোরিবোর্ডে UICollectionViewDelegateFlowLayoutপুনরুদ্ধার করতে UIcollectionViewবা স্টোরিবোর্ডে সেট করা সমস্ত সম্পত্তিতে আমাদের অ্যাক্সেস থাকে ।

// original function of the delegate
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    // casting the layout as a UICollectionViewFlowLayout to have access to the properties of items for reusability - you could also link the real one from the storyboard with an outlet
    let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
    // getting all the properties we need
    let itemWidth = flowLayout.itemSize.width
    let itemHeight = flowLayout.itemSize.height
    let interSpacing = flowLayout.minimumInteritemSpacing
    let lineSpacing = flowLayout.minimumLineSpacing
    // getting the size of the collectionView
    let collectionWidth = collectionView.bounds.width
    let collectionHeight = collectionView.bounds.height
    // getting the direction to choose how to align the collection
    let direction = flowLayout.scrollDirection
    // you don't want to have an item greater than the collection
    guard (itemWidth < collectionWidth && direction == .vertical) || (itemHeight < collectionHeight && direction == .horizontal) else {
        print("Really?")
        return UIEdgeInsets(top: flowLayout.sectionInset.top, left: flowLayout.sectionInset.left, bottom: flowLayout.sectionInset.bottom, right: flowLayout.sectionInset.right)
    }
    // getting the number of item in the current section
    let totalItemCount = CGFloat(collectionView.numberOfItems(inSection: section))
    // setting number of item in a row to the max number of items that can fit in a row without spacing or to the number of items in the section if less than the max
    var itemCountInRow = totalItemCount < (collectionWidth / itemWidth).rounded(.towardZero) ? totalItemCount : (collectionWidth / itemWidth).rounded(.towardZero)
    // how many max row can we have
    var countOfRow = totalItemCount < (collectionHeight / itemHeight).rounded(.towardZero) ? totalItemCount : (collectionHeight / itemHeight).rounded(.towardZero)
    // calculating the total width of row by multiplying the number of items in the row by the width of item and adding the spacing multiplied by the number of item minus one
    var totalWidthOfRow:CGFloat {
        get{
            return (itemWidth * itemCountInRow) + (interSpacing * (itemCountInRow - 1))
        }
    }
    // calculating the total height of row by multiplying the number of row by the height of item and adding the spacing multiplied by the number of row minus one
    var totalHeightOfRow:CGFloat {
        get{
            return (itemHeight * countOfRow) + (lineSpacing * (countOfRow - 1))
        }
    }
    // first we set the inset to the default
    var edgeInsetLeft = flowLayout.sectionInset.left
    var edgeInsetTop = flowLayout.sectionInset.top

    if direction == .vertical {
        // while the width of row with original margin is greater than the width of the collection we drop one item until it fits
        while totalWidthOfRow > collectionWidth || ((collectionWidth - totalWidthOfRow) / 2) < flowLayout.sectionInset.left {
            // droping an item to fit in the row
            itemCountInRow -= 1
        }
        // calculating the number of rows in collectionView by dividing the number of items by the number of items in a row
        countOfRow = (totalItemCount / (itemCountInRow)).rounded(.up)
    } else {
        itemCountInRow = (totalItemCount / countOfRow).rounded(.up)
        // while the height of row with original marginis greater than the height of the collection we drop one row until it fits
        while totalHeightOfRow >= collectionHeight  || ((collectionHeight - totalHeightOfRow) / 2) < flowLayout.sectionInset.top  {
            // droping an item to fit in the row
            countOfRow -= 1
        }
    }
    edgeInsetLeft = max(flowLayout.sectionInset.left, (collectionWidth - totalWidthOfRow) / 2)
    edgeInsetTop = max(flowLayout.sectionInset.top, (collectionHeight - totalHeightOfRow) / 2)
    // we don't specially need insets where the items are overflowing
    let edgeInsetRight = direction == .vertical ? edgeInsetLeft : flowLayout.sectionInset.right
    let edgeInsetBottom = direction == .horizontal ? edgeInsetTop : flowLayout.sectionInset.bottom
    // returning the UIEdgeInsets
    return UIEdgeInsets(top: edgeInsetTop, left: edgeInsetLeft, bottom: edgeInsetBottom, right: edgeInsetRight)
}

আশা করি এটি অন্য কারো সাহায্য করবে - এটা অধ্যায় ভিতরে না আইটেম অধ্যায় সেন্টার, জন্য আরও আমরা উপশ্রেণী আছে UICollectionViewFlowLayoutবা UICollectionViewLayoutঅ্যাপল মোজাইক উদাহরণ হিসাবে।


-3

আমার মনে হয় আপনার সেলটি কেন্দ্র করা দরকার, সুতরাং কালেক্টভিউ আইল্ডের পরিবর্তে ইউআইটিএবলভিউয়ের মতো দুর্দান্ত ব্যবহার হবে। কেবলমাত্র একটি ইউআইভিউকন্ট্রোলার ব্যবহার করুন এবং দুটি এবং ইউআইভিউগুলি সামনে এবং পিছনে রাখুন এবং একটি UITableViewমাঝখানে রাখুন আশা করি এটি সাহায্য করে


আমি একটি ছবি যুক্ত করেছি, আমার ঠিক কী প্রয়োজন তা আপনাকে দেখাতে, ধন্যবাদ!
রাপটক্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.