UICollectionView ішіндегі ұяшық аралығы

UICollectionView бөліміндегі ұяшық аралығын қалай орнатуға болады? Мен minimumInteritemSpacing сипатын бар екенін білемін. Мен оны 5-ке дейін қалдырды, бірақ аралықта көрінбейді 5.0. Мен жіберуші делегат әдісін қолдандым.

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

    return 5.0;
}

Мен әлі де нәтижеге қол жеткізе алмаймын. Мен оның ең төменгі аралық деп ойлаймын. Ең үлкен аралықты орнатуға болатын қандай да бір жол жоқ па?

simulator sc

168
иә, делегатқа кіріп жатырмын, IB-де мен 5-ке дейін ұяшықтардың аралықтарын белгіледім. Бірақ ең төменгі кеңістік - бұл маған көмектесетін қасиет деп ойлаймын, өйткені жасушалар арасындағы ең аз бос орын 5 болуы керек егер коллекциялық көріністе қосымша бос орын болса, онда қосымша орын бар. Максималды ұяшық аралығы сияқты нәрсе болуы керек
қосылды автор Vishal Singh, көзі
Мен оны бірнеше есептеулер жасай отырып бекітіп қойдым.
қосылды автор Vishal Singh, көзі
Менде бірдей мәселе бар. 5px жұмыс істемейді. Мен мұны UITableView арқылы жасай аламын, бірақ UICollectionView көмегімен емес ...
қосылды автор jerik, көзі
2016 ЕСКЕРТПЕСІ бұл оңай: stackoverflow.com/a/28327193/294884
қосылды автор Fattie, көзі
делегат әдісіне кіре ме, жоқ па екендігін тексерді ме? тоқтау нүктесін қою арқылы.
қосылды автор Prashant Nikam, көзі

23 жауаптар

Бастапқы сұрақты қолдау. UICollectionView жүйесінде 5px интервалына қол жеткізуге тырыстым, бірақ бұл UIEdgeInsetsMake (0,0,0,0) арқылы жұмыс істемейді ...

UITableView-те мұны тікелей, x, y координаттарын тікелей көрсете отырып жасай аламын ...

enter image description here

Менің барлық UICollectionView коды:

#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;
}

Жаңарту: Мәселе шешілді, келесі кодымен.

enter image description here

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
175
қосылды
@erner: Бұл код үшін Swift нұсқасы деген не?
қосылды автор Jayprakash Dubey, көзі
Мен бұл элементтің ені + аралығындағы ені uicollectionview еніне тең болғанда ғана жұмыс істей алады.
қосылды автор xi.lin, көзі
@JayprakashDubey, мен қазіргі уақытта жылдам емес. Сіз оны сынап көріңіз. Іске сәт
қосылды автор jerik, көзі
@MobileBloke Бұл кодты жазғанымнан бері көп уақытым бар. Менде желім жоқ, мен ұяшықтардың енін 4px немесе 2px дейін төмендетті деп ойлаймын.
қосылды автор jerik, көзі
5px ұяшықтары арасындағы ені қайда көрсетіледі?
қосылды автор Mobile Bloke, көзі
Бұл әлдеқайда жақсы жауап. UICollectionViewDelegateFlowLayout параметрінде реттеуге болатын кері қоңырауларға көз жүгіртіп, оны қалай реттеуге болатынын көре аласыз.
қосылды автор cynistersix, көзі
Қуатты 2.0-де жұмыс істемеуі мүмкін
қосылды автор Nhon Nguyen, көзі
Негізінен, UICollectionViewLayout субклассификациясы тек бір әдісті болдырмау үшін, артықшылығын жоғарылату сияқты, қабылданғаннан гөрі, әлдеқайда жақсы жауап болып табылады, және басқа да әдістерді ескермеу қажет.
қосылды автор Cindeselia, көзі

Мен тақырыбы ескі екенін білемін, бірақ егер сізге бәрібір дұрыс жауап керек болса, сізге қажет:

  1. Override standard flow layout.
  2. Add implementation like that:

    - (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;
    }
    

онда максималды аралық сіз қалаған кез келген мәнге орнатылуы мүмкін. Бұл трюк жасушалардың арасындағы кеңістік максималды максимумға тең болатындығына кепілдік береді !!

127
қосылды
Тамаша!!! Неліктен біз Apple-дің 10 ұпайлық аралықты мәжбүрлейтініне таңғаламын.
қосылды автор Evgeniy Kleban, көзі
Міне, біз оны қайда қойамыз?
қосылды автор Jonny, көзі
Мен осы кодты қоямын, бірақ бұл шақырылмайды?
қосылды автор TamilKing, көзі
Шебер сияқты жұмыс істейді. Бірақ оның қалай жұмыс істейтінін терең түсіндіре аласыз ба?
қосылды автор Karaban, көзі
layoutAttributesForElementsInRect - бұл Flow Layout бағдарламасының жайылмалы әдісі. Мен әрқайсысының әдеттегі кадрларының X нүктелерін жылжытамын (қоңырау супер көресіз), сондықтан кадрлар бір біріне 4 пиксель
қосылды автор iago849, көзі
Эй Джонни, стандартты Flow Layout-дан мұраға алып, осы әдісті өзіңіздің классыңызға көшіріп қойыңыз.
қосылды автор iago849, көзі
Орналасудағы әдепкі аралық, көптеген басқа нәрселер сияқты
қосылды автор iago849, көзі
Жауапта көрсетілгендей ағынның орналасуы
қосылды автор iago849, көзі
Брок Боланд, дұрыс, жақсы кіріспе!
қосылды автор iago849, көзі
Мүмкін, мен бірдеңе дұрыс емес немесе бұл идея 100% жұмыс істемейді, өйткені соңына қарай жылжитын кезде, кейбір ұяшықтардың бір-біріне үстінде екенін көремін :(
қосылды автор pash3r, көзі
Үлкен лауазым мен @chrisoneiota есімімен қосымша кеңістікке ие боламын және оның кодын қолданып отырдым. :-)
қосылды автор Ashok R, көзі
mutableCopy жасаудың қажеті жоқ екенін ескеріңіз: массивтің мазмұнын мутацияламайсыз, бірақ оның ішіндегі нысандарды мутациялайсыз.
қосылды автор Kyle Trauberman, көзі
Ұлы пост. Кейбір жағдайларда қателіктерге тап болдым, ол соңғы сызықтың пішімдеуін бұзды. Мен шешу үшін егер мен қосымша шартты: prevLayoutAttributes.frame.origin.x) {
қосылды автор chrisoneiota, көзі
бұл үшін кез-келген жылдам шешім бар ма? Кеңейтімді жасау және оны дұрыс анықтауды қиын деп таптым
қосылды автор Jeremy Sh, көзі
Бұл жауап MAXIMUM аралығы емес. maximumSpacing айнымалы мәніне орнатыңыз.
Егер нақты максималды интервалға орнатқыңыз келсе, қосымша шарт қажет: if (originX + self.maximumInteritemSpacing + CGRectGetWidth (currentLayoutAttributes.frame) < self.collectionViewContentSize.width && CGRectGetMinX (ағымдағыLayoutAttributes.frame) - originX> self.maximumInteritemSpacing) {
қосылды автор strawnut, көзі

Көлденең ағымның орналасуын пайдалана отырып, мен жасушалар арасында 10 баллдық интервал алдым. Аралықты жою үшін minimumLineSpacing және minimumInterItemSpacing параметрлерін нөлге дейін орнату қажет болды.

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

Сондай-ақ, егер барлық ұяшықтар бірдей өлшемде болса, делегат әдістерін пайдаланудың орнына бұл сипатты ағынын орналасуына орнату оңайырақ және тиімдірек болады.

63
қосылды
ME-да, ұяшықтар арасында көлденең айналдыру және нөлдік аралығы қажет, ал minLineSpacing = 0 кілті.
қосылды автор Wingzero, көзі
Мен minimumInteritemSpacing арқылы бұл нәтижені жоқ ала алдық. Менің көлденең орналасу кезінде minimumLineSpacing = 0 параметрін баптау элементтер арасында көлденең аралықты жойды.
қосылды автор Ziewvater, көзі
Таңқаларлықтай, MinLineSpace ұяшықтар арасындағы көлденең кеңістікке әсер етеді.
қосылды автор Matt H, көзі
Егер сіз бұл туралы ойласаңыз, элементтер арасындағы көлденең қашықтық көлденең ағынды орналасу үшін жол аралығын білдіреді. Жол аралығы - әдеттегі, тігінен ағып жатқан элементтердің арасындағы тік қашықтық.
қосылды автор lancejabr, көзі

Есіңізде болсын, ең аз интервал аралығы немесе ұяшық кеңістігі емес, минималды бос орын . Сіздің коллекцияңыздың айналдыру бағыты HORIZONTAL болғандықтан.

Егер бұл тік болса, ұяшықтар арасында көлденең кеңістік және ұяшықтар арасында тік кеңістік үшін жол аралығы үшін ұяшық кеңістігін немесе интервал аралығын орнату керек.

objective-cнұсқасы

- (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
}
36
қосылды
енді 0-ге қайтып келгенде төменгі кеңістік жоғалып кетеді; оң жақ кеңістікті қалай алып тастау керек?
қосылды автор Bangalore, көзі
Бұл көлденең және тік үшін ең төменгі жол аралығы.
қосылды автор Swati, көзі
Эй, сенің сұрағыңды өте жақсы түсіндім. Бірақ мен insetForSectionAtIndex деп ойлаймын. - (UIEdgeInsets) collectionView: (UICollectionView *) коллекцияVi & zwnj; ew орналасуы: (UICollectionViewLayout *) collectionViewLayout insetForSectionAtIndex: (NSInteger) бөлімі {return UIEdgeInsetsMake (5, 10, 5, 10); }
қосылды автор Vincent Joy, көзі

Әрбір элемент арасында 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;
}
34
қосылды
Пожалуйста, кодының кодын блок ретінде пішімдеңіз, сондықтан SO-де жақсы көрінеді.
қосылды автор Conduit, көзі

Swift version of the most popular answer. Space between the cells will be equal to 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
    }
}
29
қосылды
Мұны қолданатын барлық басқа әдістер сияқты, бұл бірнеше жол үшін дұрыс жұмыс істемейді. Кездейсоқ, дөңгелектеу-қателік жолындағы бос орындар тіпті тиісті делегат әдістерімен және 0-ге тең орнатылатын қасиеттермен бірге сақталады. Бұл UICollectionView көрсету мәселесі болуы мүмкін.
қосылды автор Womble, көзі
super.layoutAttributesForElements (in: rect) кез-келген идеяны қайтармайды?
қосылды автор Ashok R, көзі

ХБ көмегімен жасушалар мен жолдар арасындағы аралықты теңшеудің өте оңай әдісін таптым.

Тек UICollectionView-ді storyboard/Xib файлынан таңдап, төмендегі суретте көрсетілгендей Size Inspector түймесін басыңыз.

enter image description here

Кеңістікті конфигурациялау үшін келесі сипаттарды пайдаланыңыз.

1) Жолдар арасында бос орын орнату үшін.

[self.collectionView setMinimumLineSpacing:5];

2) Элементтер/ұяшықтар арасында бос орын орнату үшін.

[self.collectionView setMinimumInteritemSpacing:5];
23
қосылды
Әрқашан көрсетілген мәннен емес, белгіленген мәннен үлкен болатын ең аз кеңістік.
қосылды автор Vishal Singh, көзі

Please note the property name minimumInterItemSpacing . This will be the minimum spacing between the items not the exact spacing. If you set minimumInterItemSpacing to some value you can assure that spacing wont be a value less than that. But there is a chance get a higher value.

Элементтер арасындағы ара қашықтық шынымен itemSize және sectionInset бірнеше факторға байланысты. Коллекция көрінісі осы мәндерге негізделген мазмұнды динамикалық орналастырады. Осылайша сіз дәл аралықты қамтамасыз ете алмайсыз. sectionInset және minimumInterItemSpacing көмегімен кейбір сынақ және қателіктер жасаңыз.

18
қосылды
иә Сонымен, ең көп жасушалық аралықты орнатуға болады ма?
қосылды автор Vishal Singh, көзі
@Анил қырлы жәндіктер? : D
қосылды автор NightFury, көзі
insect == bug && жәндік! = inset :)
қосылды автор Nestor, көзі
Сіздің бөліміңізде қателер болуы мүмкін.
қосылды автор Nestor, көзі

Swift 3.0, Xcode 8 үшін жауап

1. Жинау көрінісінің өкілін орнатқаныңызды тексеріңіз

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

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

2.Implement UICollectionViewDelegate емес, UICollectionViewDelegateFlowLayout протоколын орындаңыз.

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
    }
}
14
қосылды
Онда жұртшылықты алып тастай аласыз деп ойлаңыз. Жұмыста жақсы жұмыс істеу керек және барлық басқа func (лер) лерге сәйкес болуы керек.
қосылды автор Edward Potter, көзі
Бұл тік жылжымалы жинақ көрінісі үшін жұмыс істей ме? IPhone 6s және 6s Plus сияқты құрылғыларда 2 ұяшықты көлденең көрсететін жинақ көрінісі бар, бірақ 5-ші, 5-ші және 5-ші деңгейден төмен болатын кез келген нәрсені ғана көрсету керек. Менің ағымдағы кодым жұмыс істейді, бірақ 6с плюс құрылғыда ұяшықтар арасындағы алшақтық тым көп және ұнамсыз көрінеді, мен бұл бос орынды азайтуға тырысамын және барлық басқа құрылғылар менің дизайным бойынша жұмыс істегендіктен, бұл жалғыз талап.
қосылды автор Annjawn, көзі
@EdwardPotter орындалды. Назар аударғаныңыз үшін рахмет.
қосылды автор Vadim Bulavin, көзі

Тақырып кодының UICollectionViewDelegateFlowLayout протоколын анықтаңыз.

Төмендегідей UICollectionViewDelegateFlowLayout протоколының келесі әдісін іске асырыңыз:

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

Click Here to see Apple Documentation of UIEdgeInsetMake method.

8
қосылды

Дауыс берген жауапты (және swift version ) кішкентай мәселе бар: оң жақта үлкен аралық болады.

Өйткені, ағымдық орналасу float left әрекеті арқылы ұяшық аралығын дәлдеу үшін теңшелген.

Менің шешімім секцияның кірістіруін басқарады, сол секция орталықтың ортасында орналасады, бірақ аралық дәл көрсетілгендей.

In screenshot below, the item/line spacing is exactly 8pt, while the section left & right inset will be bigger than 8pt (to make it center aligned):

evenly spaced cells

Жылдам код:

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
}
8
қосылды
Кодты пайдаланған жоқпын, бірақ бұл маған коллекциялық көрініс үшін менің сыртқа шығатын орналасуды жүзеге асыру үшін ең жақсы сілтеме берді. көңіл көтеру
қосылды автор Dima Gimburg, көзі
Мен 'NSInvalidArgumentException', себебін: '*** setObjectForKey: объект болмайды (кілт: {length = 2, path = 0 - 0})' бола алмайды.
қосылды автор DaftWooly, көзі
... егер қателеспесем, while циклі келесіге тең: let n = Int ((containerWidth + minItemSpacing)/((itemWidth + minItemSpacing)))
қосылды автор DaftWooly, көзі

Аралыққа арналған қарапайым код

let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
layout.minimumInteritemSpacing = 10//Some float value
3
қосылды

Мен monotouch-ды қолданамын, сондықтан аттар мен кодтар әр түрлі болады, бірақ сіз коллекциялық көріністің ені (x * cell width) + (x-1) * MinimumSpace x = сомасымен ұяшықтардың әрқайсысы.

MinimumInteritemSpacing және Cell ұяшығына негізделген келесі қадамдарды орындаңыз

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
қосылды

Сол сияқты ОР сияқты проблемаға тап болдым. Өкінішке орай, қабылданған жауап маған жұмыс істемеді, себебі 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);
}

That code will ensure that the value returned by ...minimumInteritemSpacing... will be the exact spacing between every collectionViewCell and furthermore guarantee that the cells all together will be centered in the collectionView

1
қосылды
Бұл өте әдемі. Бірақ мен ұқсас шешімді элемент арасындағы тік аралыққа қолдануға болатынын сұрадым
қосылды автор p0lAris, көзі
Көлденең айналдыру жағдайында тігінен қашықтық
қосылды автор luk2302, көзі

Осы әдіспен ойнап көріңіз:

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

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

    return insets;
}
1
қосылды
Бұл тек бөлімдер арасында емес, ұяшықтар арасында жұмыс істейді
қосылды автор Diego A. Rincon, көзі

Swift 3 нұсқасы

Жай ғана UICollectionViewFlowLayout қосалқы сыныбын жасап, осы әдісті қойыңыз.

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

        for i in 1..< 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
}
1
қосылды
Осыдан кейін кодта қалай қолдануға болады?
қосылды автор NiravS, көзі
Бұл көлденең орналасу үшін жұмыс істейді, бірақ кемшіліктер жолдар арасында қалады, тіпті егер minimumLineSpacingForSectionAt 0 мәніне орнатылса және layout.minimumLineSpacing параметрі 0 мәніне орнатылса да. Сонымен қатар, коллекцияның соқпауы бағдарламаның бірінші санын болдырмау себебінен апатқа ұшырайды ауқымы.
қосылды автор Womble, көзі

жоғары шешім арқылы vojtech-vrbka дұрыс, бірақ ескертуді іске қосады:

ескерту: UICollectionViewFlowLayout индекстік жол үшін кэштелген жақтау сәйкессіздігі бар - кэштелген мән: Бұл, мүмкін, ағымдық орналасудың ішкі классы Орналасу - UICollectionViewFlowLayout қайтаратын атрибуттарды оларды көшірместен өзгертеді

Келесі код оны түзетуі керек:

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
   }
}
1
қосылды
Бұл әдісті қолданатын SO-тағы басқа жауаптар сияқты, бұл cellView жиегінің ені бойынша ұяшықтарды орналастыру үшін жұмыс істейді, бірақ үзіліссіз, айнымалы биіктіктегі бос орындар әлі де жолдар арасында қалады. Бұл CollectionView шын мәнінде беретін жолдың шектеуі болуы мүмкін.
қосылды автор Womble, көзі

If u want to tweak the spacing without touching the actual cell size, this is the solution that worked best for me. #xcode 9 #tvOS11 #iOS11 #swift

Сонымен, UICollectionViewDelegateFlowLayout ішінде келесі әдістерді енгізіңіз, бұл екі амалды да қолдануы керек және құжаттама осы бағытта ойлануды көрсетпеді. : D

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
}
1
қосылды

Previous versions did not really work with sections > 1. So my solution was found here https://codentrick.com/create-a-tag-flow-layout-with-uicollectionview/. For the lazy ones:

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
қосылды

Менің көлденең UICollectionView және ішкі сынып UICollectionViewFlowLayout бар. Жинау көрінісінде үлкен ұяшықтар бар және олардың бір уақытта тек бір жолын көрсетеді, ал жиынтық көрінісі экранның еніне сәйкес келеді.

Мен iago849-ның жауабын көрдім және ол жұмыс істеді, бірақ содан кейін мен оның жауапына да мұқтаж емес екенін білдім. Қандай себеппен minimumInterItemSpacing параметрін орнату ештеңе жасамайды. Менің элементтерім/ұяшықтарым арасындағы аралықты minimumLineSpacing арқылы толық бақылауға болады.

Неліктен ол осылай жұмыс істейтініне сенімді емес, бірақ ол жұмыс істейді.

0
қосылды

Instagram-дегі Swift 3 ұяшық желісінің аралықтағы шешімі:

enter image description here

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

How to detect device programmaticlly: https://stackoverflow.com/a/26962452/6013170

0
қосылды

Менде қабылданған жауапқа байланысты мәселе бар, сондықтан оны жаңарттым, бұл мен үшін жұмыс істейді:

.h

@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
қосылды

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

Here is the link for the github project. https://github.com/vishalwaka/MultiTags

0
қосылды