ইউআইকোলিকেশনভিউতে কক্ষের ব্যবধান


197

এর একটি বিভাগে আমি কীভাবে সেল স্পেসিং সেট করব UICollectionView? আমি জানি একটি সম্পত্তি আছেminimumInteritemSpacing আমি এটি 5.0 এ সেট করে রেখেছি তবে ফাঁকা স্থানটি 5.0 তে প্রদর্শিত হচ্ছে না। আমি প্রবাহের প্রতিনিধি পদ্ধতিটি কার্যকর করেছি।

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section
{

    return 5.0;
}

তবুও আমি পছন্দসই ফলাফল পাচ্ছি না। আমি মনে করি এটির ন্যূনতম ব্যবধান। এমন কোনও উপায় নেই যেখানে আমি সর্বোচ্চ ব্যবধান স্থাপন করতে পারি?

সিমুলেটর এসসি


আপনি কি এটি পরীক্ষা করে দেখেছেন যে এটি প্রতিনিধি পদ্ধতিতে প্রবেশ করছে কিনা ..? ব্রেকপয়েন্ট রেখে ..
প্রশান্ত নিকম

হ্যাঁ এটি প্রতিনিধি প্রবেশ করছে, আইবিতেও আমি ন্যূনতম কক্ষের ব্যবধান স্থাপন করেছি But তবে আমি মনে করি না যে ন্যূনতম স্থানটি সেই সম্পত্তি যা আমাকে সাহায্য করবে কারণ এটি কেবল নিশ্চিত করবে যে কোষগুলির মধ্যে ন্যূনতম স্থানটি 5 হওয়া উচিত, তবে যদি সংগ্রহের দৃশ্যের অতিরিক্ত স্থান থাকে তবে এটি অতিরিক্ত স্থানটি ব্যবহার করবে। সর্বাধিক ঘরের ব্যবধানের মতো কিছু হওয়া উচিত
বিশাল সিং

আমি একই সমস্যা আছে। 5px কাজ করে না বলে মনে হচ্ছে। আন্তরিকভাবে আমি এটি কোনও ইউআইটিএলভিউ দিয়ে করতে পারি, তবে কোনও ইউআইসিএলক্লেশন ভিউ দিয়ে নয় ...
জেরিক

আমি এটি কিছু গণনা করে স্থির করেছি..আমি এটি পোস্ট করব পোস্ট :) :)
বিশাল সিং

2016 এর জন্য দ্রষ্টব্য এটি সহজ: স্ট্যাকওভারফ্লো.com
a

উত্তর:


145

আমি জানি যে বিষয়টি পুরানো, তবে যদি কারও এখনও আপনার সঠিক উত্তর প্রয়োজন তবে এখানে:

  1. স্ট্যান্ডার্ড ফ্লো লেআউটটিকে ওভাররাইড করুন।
  2. এর মতো বাস্তবায়ন যুক্ত করুন:

    - (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
        NSArray *answer = [super layoutAttributesForElementsInRect:rect];
    
        for(int i = 1; i < [answer count]; ++i) {
            UICollectionViewLayoutAttributes *currentLayoutAttributes = answer[i];
            UICollectionViewLayoutAttributes *prevLayoutAttributes = answer[i - 1];
            NSInteger maximumSpacing = 4;
            NSInteger origin = CGRectGetMaxX(prevLayoutAttributes.frame);
    
            if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width) {
                CGRect frame = currentLayoutAttributes.frame;
                frame.origin.x = origin + maximumSpacing;
                currentLayoutAttributes.frame = frame;
            }
        }
        return answer;
    }

যেখানে সর্বাধিকস্পেসিং আপনার পছন্দ অনুযায়ী যে কোনও মান সেট করা যেতে পারে। এই কৌশলটি গ্যারান্টি দেয় যে কোষগুলির মধ্যে স্থানটি সর্বাধিক স্পেসিংয়ের সমান হবে!


তো, আমরা এটি কোথায় রাখি?
জনি

1
ওহে জনি, স্ট্যান্ডার্ড ফ্লো লেআউট থেকে উত্তরাধিকারী হন এবং এই পদ্ধতিটি অনুলিপি করে আপনার ক্লাসে আটকান।
iago849

1
মনে রাখবেন যে আপনাকে mutableCopyএগুলি তৈরি করার দরকার নেই : আপনি অ্যারের সামগ্রীগুলি পরিবর্তন করছেন না, তবে এর মধ্যে থাকা অবজেক্টগুলিকে পরিবর্তন করছেন।
ব্রুক বোল্যান্ড

5
হতে পারে আমি কিছু ভুল করেছি বা এই ধারণাটি 100% এর জন্য কাজ করছে না, কারণ যখন আমি শেষ পর্যন্ত স্ক্রোল করি তখন দেখি যে কয়েকটি কোষ একে অপরকে ওভারলে করছে :(
pash3r

2
দুর্দান্ত পোস্ট। আমি কিছু পরিস্থিতিতে লেআউটের শেষ লাইনের বিন্যাসটিকে বিরক্ত করতে এর সাথে ত্রুটির মুখোমুখি হয়েছি। সমাধানের জন্য আমি এটিকে ifএবং একটি অতিরিক্ত শর্ত পরিবর্তন করেছি : if(origin + maximumSpacing + currentLayoutAttributes.frame.size.width < self.collectionViewContentSize.width && currentLayoutAttributes.frame.origin.x > prevLayoutAttributes.frame.origin.x) {
ক্রিসোনিওটা

190

প্রাথমিক প্রশ্ন সমর্থন। আমি স্পেসিংটি 5px এ পাওয়ার চেষ্টা করেছি UICollectionViewতবে এটি কার্যকর হয় না, পাশাপাশি UIEdgeInsetsMake(0,0,0,0)...

একটি ইউআইটিএবলভিউতে আমি সরাসরি এক্স, ওয়াই স্থানাঙ্কগুলি নির্দিষ্ট করে নির্দিষ্ট করে এটি করতে পারি ...

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

আমার ইউ আই সি কালেকশনভিউ কোডটি হেরস:

#pragma mark collection view cell layout / size
- (CGSize)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
    return [self getCellSize:indexPath];  // will be w120xh100 or w190x100
    // if the width is higher, only one image will be shown in a line
}

#pragma mark collection view cell paddings
- (UIEdgeInsets)collectionView:(UICollectionView*)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    return UIEdgeInsetsMake(0, 0, 0, 0); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {

    return 5.0;
}

আপডেট: নীচের কোড সহ আমার সমস্যা সমাধান করুন।

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

ViewController.m

#import "ViewController.h"
#import "MagazineCell.h" // created just the default class. 

static NSString * const cellID = @"cellID";

@interface ViewController ()

@end

@implementation ViewController

#pragma mark - Collection view
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
    return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
    return 30;
}

-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    MagazineCell *mCell = (MagazineCell *)[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];

    mCell.backgroundColor = [UIColor lightGrayColor];

    return mCell;
}

#pragma mark Collection view layout things
// Layout: Set cell size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {

    NSLog(@"SETTING SIZE FOR ITEM AT INDEX %d", indexPath.row);
    CGSize mElementSize = CGSizeMake(104, 104);
    return mElementSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
    return 2.0;
}

// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
   // return UIEdgeInsetsMake(0,8,0,8);  // top, left, bottom, right
    return UIEdgeInsetsMake(0,0,0,0);  // top, left, bottom, right
}

@end

এটি একটি আরও ভাল উত্তর। আপনি ইউআইসিওলেকশনভিউডেলিগেটফ্লোএলআউটে সামঞ্জস্য করতে পারেন এমন কলব্যাকগুলি একবার দেখুন এবং কীভাবে এটি টুইট করা যায় তা আপনি দেখতে পারেন।
cynisterix

1
আমি কেবল তখনই কাজ করতে পারি যখন আইটেম + স্পেসিংয়ের প্রস্থটি ইউিকোলিকেশন ভিউয়ের প্রস্থের সমান হয়।
xi.lin

@ জয়প্রকাশদুবে বর্তমানে আমি দ্রুতগতিতে ফিট নই। তোমাকে এটি চেষ্টা করতে হবে. শুভকামনা
jerik

5px এর কোষগুলির মধ্যে আপনি প্রস্থটি কোথায় নির্দিষ্ট করছেন?
ইউকেডাটাগীক

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

80

অনুভূমিক প্রবাহের বিন্যাসটি ব্যবহার করে, আমি ঘরগুলির মধ্যে একটি 10 ​​পয়েন্টের ব্যবধানও পাচ্ছি। ব্যবধানটি সরাতে আমার শূন্যের minimumLineSpacingপাশাপাশি সেট minimumInterItemSpacingকরতে হবে।

UICollectionViewFlowLayout *flow = [[UICollectionViewFlowLayout alloc] init];
flow.itemSize = CGSizeMake(cellWidth, cellHeight);
flow.scrollDirection = UICollectionViewScrollDirectionHorizontal;
flow.minimumInteritemSpacing = 0;
flow.minimumLineSpacing = 0;

এছাড়াও, যদি আপনার সমস্ত কক্ষ একই আকারের হয় তবে প্রতিনিধি পদ্ধতি ব্যবহার না করে সরাসরি প্রবাহের বিন্যাসে সম্পত্তি সেট করা সহজ এবং আরও দক্ষ।


34
আশ্চর্যজনকভাবে, ন্যূনতমলাইনস্পেসিং কোষগুলির মধ্যে অনুভূমিক স্থানকে প্রভাবিত করে।
ম্যাট এইচ

4
আমারও, আমার কক্ষগুলির মধ্যে একটি অনুভূমিক স্ক্রোল এবং শূন্য ব্যবধান প্রয়োজন এবং সর্বনিম্ন লাইনেস্পেসিং = 0 হ'ল মূল।
উইংজারো

3
আমি ব্যবহার না করেই এই প্রভাবটি অর্জন করতে সক্ষম হয়েছি minimumInteritemSpacingminimumLineSpacing = 0আমার অনুভূমিক লেআউটে কেবল সেট করা আইটেমগুলির মধ্যে অনুভূমিক ব্যবধানকে সরিয়ে দিয়েছে।
জিউভেটার

1
আপনি যদি এটির বিষয়ে চিন্তা করেন তবে আইটেমগুলির মধ্যে অনুভূমিক দূরত্ব একটি অনুভূমিকভাবে প্রবাহিত বিন্যাসের জন্য লাইন ব্যবধান। লাইন ব্যবধানটি একটি আদর্শ, উল্লম্বভাবে প্রবাহমান বিন্যাসের আইটেমগুলির মধ্যে উল্লম্ব দূরত্ব।
ল্যান্সব্রাজার

62

মনে রাখবেন, এটি ন্যূনতম লাইন স্পেস , ন্যূনতম আন্তঃ আইটেম স্পেসিং বা সেল স্পেস নয়। কারণ আপনার সংগ্রহভিউয়ের স্ক্রোলের দিকটি হরিজন্টাল

যদি এটি উল্লম্ব হয় তবে আপনার ঘরের মধ্যে অনুভূমিক স্থানের জন্য সেল স্পেস বা আন্তঃ আইটেম স্পেস নির্ধারণ করতে হবে এবং কোষগুলির মধ্যে উল্লম্ব স্থানের জন্য লাইন ফাঁক করতে হবে।

উদ্দেশ্য-সি সংস্করণ

- (CGFloat)collectionView:(UICollectionView *)collectionView
                       layout:(UICollectionViewLayout*)collectionViewLayout
    minimumLineSpacingForSectionAtIndex:(NSInteger)section
    {
        return 20;
    }

সুইফ্ট সংস্করণ:

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

আমি 0 ফিরে আসার সময় এখন নীচের স্থানটি চলে গেছে; কিভাবে ডান পাশের স্থান অপসারণ?
বেঙ্গালুরু

আরে, আমি আপনার প্রশ্নটি খুব ভাল করে বুঝতে পারি নি। তবে আমি মনে করি ইনসেটফোর্সেকশনআটিআইডেক্স যা আপনি সন্ধান করছেন। - (ইউআইএডিজইনসেটস) সংগ্রহ ভিউ: (ইউআইসিএল্লেশনভিউ *) সংগ্রহ ভিউ লেআউট: (ইউআইসিএল্লেশনভিউলয়আউট *) সংগ্রহভিউলয়আউট ইনসটারফোর্সঅ্যাকশনএন্ডেক্স: (এনএসআইঞ্জার) বিভাগ {রিটার্ন ইউআইএডিজইনসেটস মেক (5, 10, 5, 10); }
ভিনসেন্ট জয়

এটি অনুভূমিক এবং উল্লম্ব উভয়ের জন্য ন্যূনতম রেখার ব্যবধান।
সোয়াতি

আপনি আমার দিন (Y) বাঁচিয়েছেন।
উমায়ের_উএএস

ইস আমার কথাটা! আমি এটা বিশ্বাস করতে পারি না। ধন্যবাদ
মাগু

36

আপনার প্রতিটি আইটেমের মধ্যে 5px ব্যবধান রয়েছে তা নিশ্চিত করার জন্য এই কোডটি ব্যবহার করে দেখুন:

- (UIEdgeInsets)collectionView:(UICollectionView *) collectionView 
                        layout:(UICollectionViewLayout *) collectionViewLayout 
        insetForSectionAtIndex:(NSInteger) section {

    return UIEdgeInsetsMake(0, 0, 0, 5); // top, left, bottom, right
}

- (CGFloat)collectionView:(UICollectionView *) collectionView
                   layout:(UICollectionViewLayout *) collectionViewLayout
  minimumInteritemSpacingForSectionAtIndex:(NSInteger) section {    
    return 5.0;
}

আপনার কোডটি একটি কোড ব্লক হিসাবে ফর্ম্যাট করুন যাতে এটি এসও তে খুব সুন্দরভাবে প্রদর্শিত হবে।
কন্ডুইট

33

সর্বাধিক জনপ্রিয় উত্তরের সুইফ্ট সংস্করণ। কক্ষগুলির মধ্যে স্থান সমান হবে cellSpacing

class CustomViewFlowLayout : UICollectionViewFlowLayout {

    let cellSpacing:CGFloat = 4

    override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        if let attributes = super.layoutAttributesForElementsInRect(rect) {
        for (index, attribute) in attributes.enumerate() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
        }
        return nil
    }
}

সুপার.এলআউটআট্রিবিউটস ফরইমেন্টস (ইন: রেক্টর) কোনও ধারণা শূন্য করে ফিরছে?
অশোক আর

এটি ব্যবহার করে এমন অন্যান্য সমস্ত পদ্ধতির মতো, এটি একাধিক সারিগুলির জন্য সঠিকভাবে কাজ করে না। মাঝে মাঝে, গোল-ত্রুটি-শৈলীর শূন্যস্থানগুলি সারিগুলির মধ্যে থাকবে, এমনকি উপযুক্ত ডেলিগেট পদ্ধতি এবং বৈশিষ্ট্যগুলি 0 ব্যবহারের জন্য সেট করা থাকলেও এটি কোনও ইউআইকোলিকেশনভিউ রেন্ডারিংয়ের সমস্যা হতে পারে।
Womble

30

আমি আইবি ব্যবহার করে ঘর বা সারিগুলির মধ্যে ব্যবধান কনফিগার করার খুব সহজ উপায় খুঁজে পেয়েছি।

স্টোরিবোর্ড / এক্সিব ফাইল থেকে কেবল ইউআইকোলিকেশনভিউ নির্বাচন করুন এবং নীচের চিত্রে বর্ণিত আকার পরিদর্শককে ক্লিক করুন ।

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

স্থান কনফিগার করার জন্য প্রোগ্রামারমেটিকভাবে নিম্নলিখিত বৈশিষ্ট্যগুলি ব্যবহার করুন।

1) সারিগুলির মধ্যে স্থান নির্ধারণের জন্য।

[self.collectionView setMinimumLineSpacing:5];

2) আইটেম / কোষের মধ্যে স্থান নির্ধারণের জন্য।

[self.collectionView setMinimumInteritemSpacing:5];

1
সর্বনিম্ন স্থান নির্ধারণ করে, যা নির্দিষ্ট মানের চেয়ে বেশি হবে এবং সর্বদা নির্দিষ্ট মানের থেকে নয়।
বিশাল সিং

21

দয়া করে সম্পত্তির নাম ন্যূনতমআইন্টার আইটেমস্প্যাকিং নোট করুন । এটি হ'ল ব্যবধান নয় আইটেমগুলির মধ্যে ন্যূনতম ব্যবধান। আপনি যদি কোনও মানকে ন্যূনতমআইন্টার আইটেমস্পেসিং সেট করেন তবে আপনি নিশ্চয়তা দিতে পারবেন যে ব্যবধানটি এর চেয়ে কম মান হবে না। তবে একটি উচ্চতর মূল্য পেতে একটি সুযোগ আছে।

আসলে আইটেমগুলির মধ্যে ব্যবধান বিভিন্ন কারণের উপর নির্ভর করে ব্যবধানটি সাইজ এবং বিভাগ- ইনসেটের । সংগ্রহের ভিউ এই মানগুলির উপর ভিত্তি করে বিষয়বস্তুগুলিকে গতিশীলভাবে রাখুন। সুতরাং আপনি সঠিক ব্যবধানের নিশ্চয়তা দিতে পারবেন না। আপনার বিভাগীয় ইনসেট এবং ন্যূনতমআইন্টার আইটেমস্প্যাকিংয়ের সাথে কিছু ট্রায়াল এবং ত্রুটি করা উচিত ।


1
@ কোন প্রান্ত পোকামাকড়? : ডি
নাইটফিউরি

10
আপনার বিভাগে কীটপতঙ্গ থাকতে পারে।
নেস্টর

24
পোকামাকড় == বাগ && কীট! = ইনসেট :)
নেস্টর

16

সুইফট 3.0, এক্সকোড 8 এর উত্তর

1. নিশ্চিত করুন যে আপনি সংগ্রহ দর্শন প্রতিনিধি সেট করেছেন

class DashboardViewController: UIViewController {
    @IBOutlet weak var dashboardCollectionView: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        dashboardCollectionView.delegate = self
    }
}

2.আইআইসি কলিকেশনভিউডেলিগেটফ্লোএলআউট প্রোটোকলটি কার্যকর করুন, ইউআইসিএল্লেশনভিউ ডেলেগেট নয়।

extension DashboardViewController: UICollectionViewDelegateFlowLayout {
    fileprivate var sectionInsets: UIEdgeInsets {
        return .zero
    }

    fileprivate var itemsPerRow: CGFloat {
        return 2
    }

    fileprivate var interitemSpace: CGFloat {
        return 5.0
    }

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        let sectionPadding = sectionInsets.left * (itemsPerRow + 1)
        let interitemPadding = max(0.0, itemsPerRow - 1) * interitemSpace
        let availableWidth = collectionView.bounds.width - sectionPadding - interitemPadding
        let widthPerItem = availableWidth / itemsPerRow

        return CGSize(width: widthPerItem, height: widthPerItem)
    }

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

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

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

1
ভাবুন আপনি সেখানে জনসাধারণকে সরাতে পারবেন। সূক্ষ্মভাবে কাজ করা উচিত, এবং অন্যান্য সমস্ত ফানক (গুলি) এর সাথে সামঞ্জস্য করা উচিত।
এডওয়ার্ড পটার

এটি উল্লম্ব স্ক্রোল সংগ্রহ দেখার জন্য কাজ করবে? আমার সংগ্রহের ভিউ রয়েছে যেখানে এটি আইফোন 6 এস এবং 6 এস প্লাসের মতো ডিভাইসে 2 টি অনুভূমিকভাবে দেখানো উচিত, তবে এটি 5 এস, 5 এবং এসই এর চেয়ে কম কোনও কিছুর জন্য কেবল একটি ঘর দেখানো উচিত। আমার বর্তমান কোডটি কাজ করছে তবে s এস প্লাস ডিভাইসে কোষগুলির মধ্যে ব্যবধানটি খুব বেশি এবং কুশ্রী দেখাচ্ছে এবং আমি সেই ফাঁকটি হ্রাস করার চেষ্টা করছি এবং অন্য নকশাগুলি আমার নকশা অনুসারে কাজ করছে বলেই এটি কেবলমাত্র প্রয়োজনীয়।
আনবিস

11

ব্যবধানের জন্য সহজ কোড

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.minimumInteritemSpacing = 10 // Some float value

3
অনুভূমিক কক্ষের ব্যবধানের জন্য ব্যবহার করা উচিত: ন্যূনতমলাইনস্পেসিং
আলফি

9

ভোট দিয়েছেন উত্তর (এবং দ্রুতগতি সংস্করণ ) একটি ছোট সমস্যা রয়েছে: ডান দিকে একটি বড় ব্যবধান থাকবে।

এটি কারণ ফ্লো লেআউটটি ভাসমান বামদিকে রেখে ঘর ফাঁক করে দেওয়ার জন্য নির্ভুল করা হয়েছে আচরণের ।

আমার সমাধানটি বিভাগটি ইনসেটটি হেরফের করা, যাতে বিভাগটি কেন্দ্রটি সারিবদ্ধ করা হয়, তবুও ব্যবধানটি ঠিক যেমনটি নির্দিষ্ট করা হয়েছে তেমন।

নীচের স্ক্রিনশটে আইটেম / লাইন ব্যবধানটি হুবহু 8pt, যখন বিভাগ বাম এবং ডান ইনসেটটি 8pt এর চেয়ে বড় হবে (এটি কেন্দ্রের সাথে সংযুক্ত করতে):

সমানভাবে ব্যবধানযুক্ত কক্ষ

সুইফট কোড যেমন:

private let minItemSpacing: CGFloat = 8
private let itemWidth: CGFloat      = 100
private let headerHeight: CGFloat   = 32

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Create our custom flow layout that evenly space out the items, and have them in the center
    let layout = UICollectionViewFlowLayout()
    layout.itemSize = CGSize(width: itemWidth, height: itemWidth)
    layout.minimumInteritemSpacing = minItemSpacing
    layout.minimumLineSpacing = minItemSpacing
    layout.headerReferenceSize = CGSize(width: 0, height: headerHeight)

    // Find n, where n is the number of item that can fit into the collection view
    var n: CGFloat = 1
    let containerWidth = collectionView.bounds.width
    while true {
        let nextN = n + 1
        let totalWidth = (nextN*itemWidth) + (nextN-1)*minItemSpacing
        if totalWidth > containerWidth {
            break
        } else {
            n = nextN
        }
    }

    // Calculate the section inset for left and right. 
    // Setting this section inset will manipulate the items such that they will all be aligned horizontally center.
    let inset = max(minItemSpacing, floor( (containerWidth - (n*itemWidth) - (n-1)*minItemSpacing) / 2 ) )
    layout.sectionInset = UIEdgeInsets(top: minItemSpacing, left: inset, bottom: minItemSpacing, right: inset)

    collectionView.collectionViewLayout = layout
}

1
আমি একটি 'এনএসআইএনওডিয়ালআরগমেন্টএক্সেপশন' পেয়েছি, কারণ: '*** সেটঅবজেক্ট ফরকি: অবজেক্ট শূন্য করা যাবে না (কী: <এনএসআইডেক্সপথ: 0xc0000000000016> {দৈর্ঘ্য = 2, পথ = 0 - 0})' ব্যতীত ব্যতিক্রম।
দফতউলি

... যদি আমি ভুল না হয়ে থাকি তবে আপনার সময় লুপ সমান: let n = Int((containerWidth + minItemSpacing)/((itemWidth+minItemSpacing)))
দফটওয়ুলি

কোডটি যেমনটি ব্যবহার করেন নি, তবে এটি আমাকে সংগ্রহের দৃশ্যের জন্য আমার আউট প্রবাহ বিন্যাসটি বাস্তবায়নের জন্য সেরা রেফারেন্স দিয়েছে। চিয়ার্স
দিমা গিমবার্গ

8

UICollectionViewDelegateFlowLayoutআপনার শিরোনাম ফাইলে প্রোটোকল সংজ্ঞায়িত করুন।

UICollectionViewDelegateFlowLayoutপ্রোটোকলের নিম্নলিখিত পদ্ধতিটি এর মতো প্রয়োগ করুন :

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section
{
    return UIEdgeInsetsMake(5, 5, 5, 5);
}

UIEdgeInsetMakeপদ্ধতির অ্যাপল ডকুমেন্টেশন দেখতে এখানে ক্লিক করুন


3

আপনি যদি প্রকৃত ঘরের আকারের স্পর্শ না করে স্পেসিংটি টুইট করতে চান তবে এই সমাধানটি আমার পক্ষে সবচেয়ে ভাল কাজ করেছে। # এক্সকোড 9 # টিভিওএস 11 # আইওএস 11 # সুইফট

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

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

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

3

স্টোরিবোর্ড অ্যাপ্রোচ

আপনার স্টোরিবোর্ডে কালেকশনভিউ নির্বাচন করুন এবং আকার পরিদর্শকের কাছে যান এবং ঘর এবং লাইনগুলির জন্য ন্যূনতম ব্যবধান 5 হিসাবে সেট করুন

সুইফট 5 প্রোগ্রামগতভাবে

lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal

        //Provide Width and Height According to your need
        let width = UIScreen.main.bounds.width / 4
        let height = UIScreen.main.bounds.height / 10
        layout.itemSize = CGSize(width: width, height: height)

        //For Adjusting the cells spacing
        layout.minimumInteritemSpacing = 5
        layout.minimumLineSpacing = 5

        return UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
    }()

2

আমি মনোোটুচ ব্যবহার করছি, সুতরাং নাম এবং কোডটি কিছুটা আলাদা হবে তবে আপনি সংগ্রহ ভিউয়ের প্রস্থের সমান (x * সেল প্রস্থ) + (x-1) * x = পরিমাণের সাথে ন্যূনতম স্পেসিং করে এটি করতে পারেন প্রতি সারিতে কোষের।

আপনার ন্যূনতমInteritemSpacing এবং ঘরের প্রস্থের উপর ভিত্তি করে কেবল নিম্নলিখিত পদক্ষেপগুলি করুন

1) আমরা ঘরের আকার + বর্তমান ইনসেট + ন্যূনতম ব্যবধানের ভিত্তিতে সারি প্রতি আইটেমের পরিমাণ গণনা করি

float currentTotalWidth = CollectionView.Frame.Width - Layout.SectionInset.Left - Layout.SectionInset.Right (Layout = flowlayout)
int amountOfCellsPerRow = (currentTotalWidth + MinimumSpacing) / (cell width + MinimumSpacing)

2) এখন আপনার কাছে সংগ্রহ দেখার জন্য প্রত্যাশিত প্রস্থ গণনা করার জন্য সমস্ত তথ্য রয়েছে

float totalWidth =(amountOfCellsPerRow * cell width) + (amountOfCellsPerRow-1) * MinimumSpacing

3) সুতরাং বর্তমান প্রস্থ এবং প্রত্যাশিত প্রস্থের মধ্যে পার্থক্য

float difference = currentTotalWidth - totalWidth;

4) এখন ইনসেটগুলি সামঞ্জস্য করুন (এই উদাহরণে আমরা এটি ডানদিকে যুক্ত করি, সুতরাং সংগ্রহের দৃশ্যের বাম অবস্থানটি একই থাকে

Layout.SectionInset.Right = Layout.SectionInset.Right + difference;

2

আমি একটি অনুভূমিক UICollectionViewএবং subclassed আছে UICollectionViewFlowLayout। সংগ্রহের ভিউতে বড় কক্ষ রয়েছে এবং এটি একবারে কেবল তাদের এক সারি দেখায় এবং সংগ্রহের দৃশ্যটি পর্দার প্রস্থে ফিট করে।

আমি iago849 এর উত্তর চেষ্টা করেছি এবং এটি কার্যকর হয়েছে, তবে আমি জানতে পেরেছিলাম যে তার উত্তরও আমার দরকার নেই। কিছু কারণে, সেটগুলি minimumInterItemSpacingকিছুই করে না। আমার আইটেম / সেলগুলির মধ্যে ব্যবধানটি পুরোপুরি নিয়ন্ত্রণ করা যায়minimumLineSpacing

কেন এটি এইভাবে কাজ করে তা নিশ্চিত নয়, তবে এটি কাজ করে।


1
এটি সত্য বলে মনে হচ্ছে - অদ্ভুতভাবে "রেখাগুলি" মানটি আসলে একটি অনুভূমিক বিন্যাসের ক্ষেত্রে আইটেমগুলির মধ্যে বিভাজক।
ফ্যাটি

আরে @ user3344977 - দুর্দান্ত সন্ধান। আমি এই বিষয়টিকে একটি পৃথক প্রশ্নে আলাদা করার সিদ্ধান্ত নিয়েছি যা অনুভূমিক স্ক্রোল সংগ্রহের ভিউগুলিকে সরাসরি সম্বোধন করে যাতে কিছু লোকের সন্ধান করা আরও সহজ হয়। আমি আপনার উত্তর সেখানে উল্লেখ। আমার প্রশ্নটি এখানে: stackoverflow.com/q/61774415/826946
অ্যান্ডি ওয়েইনস্টেইন

1

আমি ওপি-র মতো একই সমস্যায় হোঁচট খেয়েছি। দুর্ভাগ্যক্রমে গৃহীত উত্তরগুলি আমার পক্ষে কার্যকর হয়নি যেহেতু এর বিষয়বস্তু collectionViewসঠিকভাবে কেন্দ্রীভূত হবে না। অতএব, আমি একটি ভিন্ন সমাধান যা শুধুমাত্র প্রয়োজন যে সব আইটেম নিয়ে এসেছেন collectionViewহয় একই প্রস্থ , যা প্রশ্নে ক্ষেত্রে মনে করা হয়:

#define cellSize 90

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
    float width = collectionView.frame.size.width;
    float spacing = [self collectionView:collectionView layout:collectionViewLayout minimumInteritemSpacingForSectionAtIndex:section];
    int numberOfCells = (width + spacing) / (cellSize + spacing);
    int inset = (width + spacing - numberOfCells * (cellSize + spacing) ) / 2;

    return UIEdgeInsetsMake(0, inset, 0, inset);
}

এই কোডটি নিশ্চিত করবে যে এর দ্বারা প্রদত্ত মানটি ...minimumInteritemSpacing...প্রতিটিটির মধ্যে হ'ল ফাঁক হবে collectionViewCellএবং তদুপরি গ্যারান্টি দেয় যে সমস্ত কক্ষগুলি একসাথে কেন্দ্রে থাকবেcollectionView


যে বেশ শান্ত. তবে আমি ভাবছিলাম যে উপাদানগুলির মধ্যে উল্লম্ব ব্যবধানে একই ধরণের সমাধান প্রয়োগ করা যেতে পারে
p0lAris

আপনার অনুভূমিক স্ক্রোলিংয়ের ক্ষেত্রে উল্লম্ব ব্যবধান?
luk2302

1

উপরে সমাধান দ্বারা vojtech-Vrbka সঠিক কিন্তু এটি একটি সতর্কবার্তা আরম্ভ করে:

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

নিম্নলিখিত কোডটি এটি ঠিক করা উচিত:

class CustomViewFlowLayout : UICollectionViewFlowLayout {

   let cellSpacing:CGFloat = 4

   override func layoutAttributesForElementsInRect(rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
       let original = super.layoutAttributesForElementsInRect(rect)

       if let original = original {
           let attributes = NSArray.init(array: original, copyItems: true) as! [UICollectionViewLayoutAttributes]

           for (index, attribute) in attributes.enumerate() {
                if index == 0 { continue }
                let prevLayoutAttributes = attributes[index - 1]
                let origin = CGRectGetMaxX(prevLayoutAttributes.frame)
                if(origin + cellSpacing + attribute.frame.size.width < self.collectionViewContentSize().width) {
                    attribute.frame.origin.x = origin + cellSpacing
                }
            }
            return attributes
       }
       return nil
   }
}

2
এই পদ্ধতির ব্যবহার করে এমন অন্যান্য উত্তরগুলির মতো এটিও কালেকশনভিউয়ের প্রস্থ জুড়ে ঘর ফিটিংয়ের কাজ করে তবে মাঝে মাঝে, পরিবর্তনশীল-উচ্চতার ফাঁকগুলি এখনও সারিগুলির মধ্যেই থেকে যায়। এটি কালেকশনভিউ আসলে যেভাবে রেন্ডার করে তার সীমাবদ্ধতা হতে পারে।
Womble

1

সুইফট 3 সংস্করণ

কেবলমাত্র একটি ইউআইসিকলিকেশনভিউফ্লোলয়আউট সাবক্লাস তৈরি করুন এবং এই পদ্ধতিটি আটকে দিন।

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        guard let answer = super.layoutAttributesForElements(in: rect) else { return nil }

        for i in 1..<answer.count {
            let currentAttributes = answer[i]
            let previousAttributes = answer[i - 1]

            let maximumSpacing: CGFloat = 8
            let origin = previousAttributes.frame.maxX

            if (origin + maximumSpacing + currentAttributes.frame.size.width < self.collectionViewContentSize.width && currentAttributes.frame.origin.x > previousAttributes.frame.origin.x) {
                var frame = currentAttributes.frame
                frame.origin.x = origin + maximumSpacing
                currentAttributes.frame = frame
            }
        }

        return answer
}

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

1

আমি iago849 এর উত্তর চেষ্টা করেছি এবং এটি কার্যকর হয়েছে।

সুইফট 4

open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    guard let answer = super.layoutAttributesForElements(in: rect) else {
        return nil
    }
    let count = answer.count
    for i in 1..<count {
        let currentLayoutAttributes = answer[i]
        let prevLayoutAttributes = answer[i-1]
        let origin = prevLayoutAttributes.frame.maxX
        if (origin + CGFloat(spacing) + currentLayoutAttributes.frame.size.width) < self.collectionViewContentSize.width && currentLayoutAttributes.frame.origin.x > prevLayoutAttributes.frame.origin.x {
            var frame = currentLayoutAttributes.frame
            frame.origin.x = origin + CGFloat(spacing)
            currentLayoutAttributes.frame = frame
        }
    }
    return answer
}

গিথুব প্রকল্পের লিঙ্কটি এখানে। https://github.com/vishalwaka/MultiTags


0

পূর্ববর্তী সংস্করণ সত্যিই বিভাগগুলিতে সহজেই কাজ করে নি> 1. তাই আমার সমাধান এখানে পাওয়া যায়নি https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/ । অলসদের জন্য:

override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
    let attributesForElementsInRect = super.layoutAttributesForElements(in: rect)
    var newAttributesForElementsInRect = [UICollectionViewLayoutAttributes]()
    // use a value to keep track of left margin
    var leftMargin: CGFloat = 0.0;
    for attributes in attributesForElementsInRect! {
        let refAttributes = attributes 
        // assign value if next row
        if (refAttributes.frame.origin.x == self.sectionInset.left) {
            leftMargin = self.sectionInset.left
        } else {
            // set x position of attributes to current margin
            var newLeftAlignedFrame = refAttributes.frame
            newLeftAlignedFrame.origin.x = leftMargin
            refAttributes.frame = newLeftAlignedFrame
        }
        // calculate new value for current margin
        leftMargin += refAttributes.frame.size.width + 10
        newAttributesForElementsInRect.append(refAttributes)
    }

    return newAttributesForElementsInRect
}

0

স্বীকৃত উত্তর নিয়ে আমার সমস্যা আছে, তাই আমি এটি আপডেট করেছি, এটি আমার পক্ষে কাজ করছে:

@interface MaxSpacingCollectionViewFlowLayout : UICollectionViewFlowLayout
@property (nonatomic,assign) CGFloat maxCellSpacing;
@end

.m

@implementation MaxSpacingCollectionViewFlowLayout

- (NSArray *) layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray *attributes = [super layoutAttributesForElementsInRect:rect];

    if (attributes.count <= 0) return attributes;

    CGFloat firstCellOriginX = ((UICollectionViewLayoutAttributes *)attributes[0]).frame.origin.x;

    for(int i = 1; i < attributes.count; i++) {
        UICollectionViewLayoutAttributes *currentLayoutAttributes = attributes[i];
        if (currentLayoutAttributes.frame.origin.x == firstCellOriginX) { // The first cell of a new row
            continue;
        }

        UICollectionViewLayoutAttributes *prevLayoutAttributes = attributes[i - 1];
        CGFloat prevOriginMaxX = CGRectGetMaxX(prevLayoutAttributes.frame);
        if ((currentLayoutAttributes.frame.origin.x - prevOriginMaxX) > self.maxCellSpacing) {
            CGRect frame = currentLayoutAttributes.frame;
            frame.origin.x = prevOriginMaxX + self.maxCellSpacing;
            currentLayoutAttributes.frame = frame;
        }
    }
    return attributes;
}

@end

0

Swift 3ইনস্টাগ্রামের মতো সেল লাইনের ব্যবধানে আমার সমাধান :

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

lazy var collectionView: UICollectionView = {
    let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = UIColor.rgb(red: 227, green: 227, blue: 227)
    cv.showsVerticalScrollIndicator = false
    layout.scrollDirection = .vertical
    layout.minimumLineSpacing = 1
    layout.minimumInteritemSpacing = 1
    return cv
}()

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

    switch UIDevice.current.modelName {
    case "iPhone 4":
        return CGSize(width: 106, height: 106)
    case "iPhone 5":
        return CGSize(width: 106, height: 106)
    case "iPhone 6,7":
        return CGSize(width: 124, height: 124)
    case "iPhone Plus":
        return CGSize(width: 137, height: 137)
    default:
        return CGSize(width: frame.width / 3, height: frame.width / 3)
    }
}

প্রোগ্রামিয়ালিলি ডিভাইস কীভাবে সনাক্ত করবেন: https://stackoverflow.com/a/26962452/6013170


0

ঠিক আছে, আপনি যদি একটি অনুভূমিক সংগ্রহের দৃশ্য তৈরি করেন তবে ঘরগুলির মধ্যে স্থান দেওয়ার জন্য, আপনাকে সম্পত্তিটি সেট করতে হবে minimumLineSpacing


-1

এই পদ্ধতিটি নিয়ে চারপাশে খেলার চেষ্টা করুন:

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView
                    layout:(UICollectionViewLayout*)collectionViewLayout
    insetForSectionAtIndex:(NSInteger)section {

    UIEdgeInsets insets = UIEdgeInsetsMake(?, ?, ?, ?);

    return insets;
}

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