Soru UICollectionView flowLayout'taki hücreler arasındaki mesafeyi nasıl belirlersiniz


Akış düzeni ile bir UICollectionView var ve her hücre bir kare. Her satırdaki her hücre arasındaki mesafeyi nasıl belirlerim? Bunun için uygun ayarları bulamıyorum. Ben bir koleksiyon görünümü için nib dosyası üzerinde bir min aralığı öznitelikleri görüyorum, ama bunu 0 olarak ayarladım ve hücreler bile yapışmaz.

enter image description here

Başka bir fikrin var mı?


44
2017-10-22 18:15


Menşei


Ayrıca bakınız stackoverflow.com/questions/22539979/... - Cœur


Cevaplar:


Güncelleme: Bu cevabın hızlı versiyonu: https://github.com/fanpyi/UICollectionViewLeftAlignedLayout-Swift


alma @ matt'ın kurşun Öğelerin HER ZAMAN sola hizalanmış olmasını sağlamak için kodunu değiştirdim. Bir öğenin kendi başına bir satırdan çıkması halinde, akış düzeni tarafından ortalanacaktı. Bu sorunu çözmek için aşağıdaki değişiklikleri yaptım.

Bu durum, yalnızca, genişlik açısından değişen hücrelere sahipseniz, aşağıdaki gibi bir düzen ile sonuçlanabilecekse ortaya çıkar. Son çizgi her zaman davranışı nedeniyle hizalanmış kaldı UICollectionViewFlowLayoutMesele, kendileri tarafından herhangi bir satırda olan sonuncu maddede yatar.

@ Matt'in koduyla görüşüyordum.

enter image description here

Bu örnekte, hücrelerin kendi başlarına kalmaları halinde ortalanacağını görüyoruz. Aşağıdaki kod, koleksiyon görünümünüzün bu şekilde görüneceğini garanti eder.

enter image description here

#import "CWDLeftAlignedCollectionViewFlowLayout.h"

const NSInteger kMaxCellSpacing = 9;

@implementation CWDLeftAlignedCollectionViewFlowLayout

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray* attributesToReturn = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes* attributes in attributesToReturn) {
        if (nil == attributes.representedElementKind) {
            NSIndexPath* indexPath = attributes.indexPath;
            attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
        }
    }
    return attributesToReturn;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes* currentItemAttributes =
    [super layoutAttributesForItemAtIndexPath:indexPath];

    UIEdgeInsets sectionInset = [(UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout sectionInset];

    if (indexPath.item == 0) { // first item of section
        CGRect frame = currentItemAttributes.frame;
        frame.origin.x = sectionInset.left; // first item of the section should always be left aligned
        currentItemAttributes.frame = frame;

        return currentItemAttributes;
    }

    NSIndexPath* previousIndexPath = [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];
    CGRect previousFrame = [self layoutAttributesForItemAtIndexPath:previousIndexPath].frame;
    CGFloat previousFrameRightPoint = previousFrame.origin.x + previousFrame.size.width + kMaxCellSpacing;

    CGRect currentFrame = currentItemAttributes.frame;
    CGRect strecthedCurrentFrame = CGRectMake(0,
                                              currentFrame.origin.y,
                                              self.collectionView.frame.size.width,
                                              currentFrame.size.height);

    if (!CGRectIntersectsRect(previousFrame, strecthedCurrentFrame)) { // if current item is the first item on the line
        // the approach here is to take the current frame, left align it to the edge of the view
        // then stretch it the width of the collection view, if it intersects with the previous frame then that means it
        // is on the same line, otherwise it is on it's own new line
        CGRect frame = currentItemAttributes.frame;
        frame.origin.x = sectionInset.left; // first item on the line should always be left aligned
        currentItemAttributes.frame = frame;
        return currentItemAttributes;
    }

    CGRect frame = currentItemAttributes.frame;
    frame.origin.x = previousFrameRightPoint;
    currentItemAttributes.frame = frame;
    return currentItemAttributes;
}

@end

68
2018-03-21 17:51



Konu dışı soru, nasıl Seninki gibi bir etiket UI öğesi uygularım, herhangi bir açık kaynak projesi önermek? Teşekkürler - x.y
, GitHub üzerinde özel UIButtons sürü sadece Objective-C kategorisinde "Düğme" için arama vardır bir hedef olmadan UIButton kullan (ya durumunda bir hedef ile bir tane gerekir) - GangstaGraham
Ekran görüntüsünde gördüğünüz şeyler UICollectionViewCelliçinde bir UICollectionView. Dokunma olayları temsilci yöntemleri tarafından ele alınır. Sonra buna göre sadece mavi bir kenara, gerilebilir bir arka plan kullanılarak tarz, bir hücre içinde sadece bir görüntüdür. Bildiğim kadarıyla açık kaynak şeyler yok ama bu oldukça basit. UICollectionView, zor kısmı onları bu şekilde hizaya getiriyordu ve bu sizin için burada yapıldı;) - Chris Wagner
Bunun için çok teşekkürler! İnanılmaz derecede yardımcı oldu ve bana bir ton zaman kazandırdı. Eğer Şu anda UITableViewCells içinde UICollectionViews koyuyorum ve dikey yönde yakalanmadan (ve zaten iyi ux olmaz) yatay olarak bu akışı yapmak konusunda herhangi bir tavsiye varsa ben gerçi merak ediyorum. - AdamG
Kodda olası bir gelişme için buraya bakın: stackoverflow.com/review/suggested-edits/4003993 - Robert Harvey♦


Maksimum interitem aralığı elde etmek için UICollectionViewFlowLayout alt sınıfını ve geçersiz kılmayı layoutAttributesForElementsInRect: ve layoutAttributesForItemAtIndexPath:.

Örneğin, ortak bir sorun şudur: Bir koleksiyon görünümünün satırları, sola dayalı son satır haricinde, sağa ve sola yaslıdır. Diyelim ki istediğimizi herşey sola yaslanacak çizgiler, böylece aralarındaki boşluk 10 diyelim. İşte kolay bir yol (UICollectionViewFlowLayout alt sınıfınızda):

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
    NSArray* arr = [super layoutAttributesForElementsInRect:rect];
    for (UICollectionViewLayoutAttributes* atts in arr) {
        if (nil == atts.representedElementKind) {
            NSIndexPath* ip = atts.indexPath;
            atts.frame = [self layoutAttributesForItemAtIndexPath:ip].frame;
        }
    }
    return arr;
}

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewLayoutAttributes* atts =
    [super layoutAttributesForItemAtIndexPath:indexPath];

    if (indexPath.item == 0) // degenerate case 1, first item of section
        return atts;

    NSIndexPath* ipPrev =
    [NSIndexPath indexPathForItem:indexPath.item-1 inSection:indexPath.section];

    CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
    CGFloat rightPrev = fPrev.origin.x + fPrev.size.width + 10;
    if (atts.frame.origin.x <= rightPrev) // degenerate case 2, first item of line
        return atts;

    CGRect f = atts.frame;
    f.origin.x = rightPrev;
    atts.frame = f;
    return atts;
}

Bunun bu kadar kolay olmasının nedeni, düzenin ağır kaldırılmasını gerçekten gerçekleştirmememizdir. UICollectionViewFlowLayout'un bizim için zaten yapmış olduğu düzen çalışmasını destekliyoruz. Her bir satıra kaç tane maddenin girdiğine karar vermişti; ne demek istediğimi görürseniz, sadece o satırları okuyoruz ve eşyaları bir araya getiriyoruz.


32
2017-11-06 20:02



Sadece bir soru şu anda kodunuzu test etme imkanım olmadığından. Bu cevap, burada yaşadığım sorunu düzeltmeme yardımcı olacak mı? stackoverflow.com/questions/13411609/... - Joakim Engstrom
Başar, kodun dikey sürümünü buraya ekledim: stackoverflow.com/questions/14482882/...  Müthiş kod için teşekkürler - Rob R.
Çözüm için teşekkürler. Küçük bir nokta: (collectionView.contentSize.width hücre genişliğinden çok daha büyüktür) sıra başına yatay öğelerin büyük bir set ile bir koleksiyon görünüm varsa bu kodu içinde tekrarlama pahalı olabilir. - ricosrealm


Göz önünde bulundurulması gereken birkaç şey var:

  1. IB'deki minimum aralığı değiştirmeyi deneyin, ancak imleci bu alana bırakın. Xcode'un belgeyi değiştirildiği gibi hemen işaretlemediğine dikkat edin. Yine de farklı bir alana tıkladığınızda, Xcode belgenin değiştirildiğini fark eder ve dosya navigatorda bunu işaretler. Bu nedenle, değişiklik yaptıktan sonra farklı bir alana sekmeyi veya tıklama yapmayı unutmayın.

  2. Bir değişiklik yaptıktan sonra storyboard / xib dosyanızı kaydedin ve uygulamayı yeniden yaptığınızdan emin olun. Bu adımı kaçırmak zor değil, ve sonra kafanızın neden değiştiğini merak ettiniz.

  3. UICollectionViewFlowLayout bir var minimumInteritemSpacing mülkiyet, IB'de belirlediğiniz şeydir. Ancak koleksiyonun temsilcisi de Öğeler arası aralığı belirlemek için bir yöntem. Bu yöntem, mizanpajın mimarıdır, bu nedenle delege uygulamasında uygularsanız, mizanpajınızın özelliği kullanılamaz.

  4. Boşluğun orada olduğunu unutmayın. asgari aralığı. Yerleşim, bu sayıyı (mülkten mi yoksa temsilci yönteminden mi geldiği) en küçük izin verilen alan olarak kullanacaktır, ancak satırda kalan alan varsa daha büyük bir alan kullanabilir. Örneğin, minimum aralığı 0 olarak ayarlarsanız, öğeler arasında hala birkaç piksel görebilirsiniz. Öğelerin tam olarak nasıl yerleştirildiğine dair daha fazla kontrol istiyorsanız, muhtemelen farklı bir düzen kullanmalısınız (muhtemelen kendi yaratımınızdan biri).


16
2017-10-22 19:18



Harika cevap için teşekkürler. Daha fazla baktığım şeyin maksimumInteritemSpacing olduğunu düşünüyorum, böyle bir değer var mı? - adit
Hayır, maksimum bir değer yok. Akış düzeninin ne yaptığını düşünürseniz nedenini görürsünüz. Akış düzeni yine asgari madde aralığını saygı sığabilecek kadar bir hat üzerinde birçok öğe olarak koyar. O noktada, orada olacak n piksel kalan, nerede n 0'dan büyük veya ona eşittir ve bir sonraki öğenin artı minimum aralığın boyutundan küçüktür. Düzen, daha sonra bu n pikselleri alır ve bunları satırdaki öğelere eşit aralıklarla dağıtır. Maksimum boşluk ayarlarsanız bunu yapamazsınız. Ancak, istediğiniz gibi alan öğelerine kendi düzeninizi yazabilirsiniz. - Caleb
+1, ayarlayabilirsiniz minimumInteritemSpacing ve minimumLineSpacing Ayrıca, elde etmeye çalıştığınız şeye bağlı olarak. - iDev
Yatay öğe arası aralığı belirleyebilen düzenin temsilcisindeki kesin yöntemi lütfen belirtebilir misiniz? - Drux
@Drux Üzgünüm - kötü ifadeler. Onu tamir edeceğim. Var UICollectionViewDelegateFlowLayout koleksiyon görünümünün temsilcisinin bir akış düzenini desteklemek için benimseyebileceği protokolü. Yönteme bakın – collectionView:layout:minimumInteritemSpacingForSectionAtIndex:. - Caleb


Birazcık matematik, hile daha kolay. Chris Wagner tarafından yazılan kod, önceki her öğenin düzen niteliklerini çağırdığı için korkunçtur. Böylece ne kadar çok gezinirseniz, o kadar yavaş olur ...

Sadece bu şekilde modulo kullanın (minimumInteritemSpacing değerini maksimum değer olarak kullanıyorum):

- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
    UICollectionViewLayoutAttributes* currentItemAttributes = [super layoutAttributesForItemAtIndexPath:indexPath];
    NSInteger numberOfItemsPerLine = floor([self collectionViewContentSize].width / [self itemSize].width);

    if (indexPath.item % numberOfItemsPerLine != 0)
    {
        NSInteger cellIndexInLine = (indexPath.item % numberOfItemsPerLine);

        CGRect itemFrame = [currentItemAttributes frame];
        itemFrame.origin.x = ([self itemSize].width * cellIndexInLine) + ([self minimumInteritemSpacing] * cellIndexInLine);
        currentItemAttributes.frame = itemFrame;
    }

    return currentItemAttributes;
}

4
2017-09-06 18:57



Bu hücre öğesi genişliği statik olduğunda çalışır. - jasonIM
Benim durumumda önceki hücrenin boyutu önemlidir, bu yüzden önceki hücrenin düzen niteliklerini çağırır. Performansı büyük bir koleksiyon görünümünde test etmedim. Benim kullanım durumum en fazla 11 hücreye sahip, bu yüzden bir sorun değildi. - Chris Wagner


Sola yaslanmak için kolay bir yol, UICollectionViewFlowLayout alt sınıfınızda layoutAttributesForElementsInRect öğesinin değiştirilmesidir:

- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
    NSArray *allLayoutAttributes = [super layoutAttributesForElementsInRect:rect];
    CGRect prevFrame = CGRectMake(-FLT_MAX, -FLT_MAX, 0, 0);
    for (UICollectionViewLayoutAttributes *layoutAttributes in allLayoutAttributes)
    {
        //fix blur
        CGRect theFrame = CGRectIntegral(layoutAttributes.frame);

        //left justify
        if(prevFrame.origin.x > -FLT_MAX &&
           prevFrame.origin.y >= theFrame.origin.y &&
           prevFrame.origin.y <= theFrame.origin.y) //workaround for float == warning
        {
            theFrame.origin.x = prevFrame.origin.x +
                                prevFrame.size.width + 
                                EXACT_SPACE_BETWEEN_ITEMS;
        }
        prevFrame = theFrame;

        layoutAttributes.frame = theFrame;
    }
    return allLayoutAttributes;
}

3
2018-03-13 23:26





Chris çözümünün hızlı versiyonu.

class PazLeftAlignedCollectionViewFlowLayout : UICollectionViewFlowLayout {
    var maxCellSpacing = 14.0
    override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
        if var attributesToReturn = super.layoutAttributesForElementsInRect(rect) as? Array<UICollectionViewLayoutAttributes> {
            for attributes in attributesToReturn {
                if attributes.representedElementKind == nil {
                    let indexPath = attributes.indexPath
                    attributes.frame = self.layoutAttributesForItemAtIndexPath(indexPath).frame;
                }
            }
            return attributesToReturn;
        }
        return super.layoutAttributesForElementsInRect(rect)
    }

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
        let currentItemAttributes = super.layoutAttributesForItemAtIndexPath(indexPath)

        if let collectionViewFlowLayout = self.collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
            let sectionInset = collectionViewFlowLayout.sectionInset
            if (indexPath.item == 0) { // first item of section
                var frame = currentItemAttributes.frame;
                frame.origin.x = sectionInset.left; // first item of the section should always be left aligned
                currentItemAttributes.frame = frame;

                return currentItemAttributes;
            }

            let previousIndexPath = NSIndexPath(forItem:indexPath.item-1, inSection:indexPath.section)
            let previousFrame = self.layoutAttributesForItemAtIndexPath(previousIndexPath).frame;
            let previousFrameRightPoint = Double(previousFrame.origin.x) + Double(previousFrame.size.width) + self.maxCellSpacing

            let currentFrame = currentItemAttributes.frame
            var width : CGFloat = 0.0
            if let collectionViewWidth = self.collectionView?.frame.size.width {
                width = collectionViewWidth
            }
            let strecthedCurrentFrame = CGRectMake(0,
                currentFrame.origin.y,
                width,
                currentFrame.size.height);

            if (!CGRectIntersectsRect(previousFrame, strecthedCurrentFrame)) { // if current item is the first item on the line
                // the approach here is to take the current frame, left align it to the edge of the view
                // then stretch it the width of the collection view, if it intersects with the previous frame then that means it
                // is on the same line, otherwise it is on it's own new line
                var frame = currentItemAttributes.frame;
                frame.origin.x = sectionInset.left; // first item on the line should always be left aligned
                currentItemAttributes.frame = frame;
                return currentItemAttributes;
            }

            var frame = currentItemAttributes.frame;
            frame.origin.x = CGFloat(previousFrameRightPoint)
            currentItemAttributes.frame = frame;
        }
        return currentItemAttributes;
    }
}

Bunu kullanmak için aşağıdakileri yapın:

    override func viewDidLoad() {
    super.viewDidLoad()
    self.collectionView.collectionViewLayout = self.layout
}
var layout : PazLeftAlignedCollectionViewFlowLayout {
    var layout = PazLeftAlignedCollectionViewFlowLayout()
    layout.itemSize = CGSizeMake(220.0, 230.0)
    layout.minimumLineSpacing = 12.0
    return layout
}

2
2017-11-07 20:02



Bu kod gerçekten bana yardımcı oldu. Çok teşekkür ederim. - Tommy


Chris Wagner'in cevabına göre, ilgilenenler için daha temiz bir hızlı versiyon:

class AlignLeftFlowLayout: UICollectionViewFlowLayout {

    var maximumCellSpacing = CGFloat(9.0)

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

        for attributes in attributesToReturn ?? [] {
            if attributes.representedElementKind == nil {
                attributes.frame = self.layoutAttributesForItemAtIndexPath(attributes.indexPath).frame
            }
        }

        return attributesToReturn
    }

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
        let curAttributes = super.layoutAttributesForItemAtIndexPath(indexPath)
        let sectionInset = (self.collectionView?.collectionViewLayout as UICollectionViewFlowLayout).sectionInset

        if indexPath.item == 0 {
            let f = curAttributes.frame
            curAttributes.frame = CGRectMake(sectionInset.left, f.origin.y, f.size.width, f.size.height)
            return curAttributes
        }

        let prevIndexPath = NSIndexPath(forItem: indexPath.item-1, inSection: indexPath.section)
        let prevFrame = self.layoutAttributesForItemAtIndexPath(prevIndexPath).frame
        let prevFrameRightPoint = prevFrame.origin.x + prevFrame.size.width + maximumCellSpacing

        let curFrame = curAttributes.frame
        let stretchedCurFrame = CGRectMake(0, curFrame.origin.y, self.collectionView!.frame.size.width, curFrame.size.height)

        if CGRectIntersectsRect(prevFrame, stretchedCurFrame) {
            curAttributes.frame = CGRectMake(prevFrameRightPoint, curFrame.origin.y, curFrame.size.width, curFrame.size.height)
        } else {
            curAttributes.frame = CGRectMake(sectionInset.left, curFrame.origin.y, curFrame.size.width, curFrame.size.height)
        }

        return curAttributes
    }
}

1
2018-03-11 14:52





Evrim tarihçesinden temiz Swift çözümü:

  1. oradaydı mat cevap
  2. oradaydı Chris Wagner yalnızlık düzeltmesi
  3. oradaydı mokagio sectionInset ve minimumInteritemSpacing iyileştirme
  4. oradaydı fanpyi Swift sürümü
  5. şimdi burada benim basitleştirilmiş ve temiz bir versiyonu:
open class UICollectionViewLeftAlignedLayout: UICollectionViewFlowLayout {
    open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return super.layoutAttributesForElements(in: rect)?.map { $0.representedElementKind == nil ? layoutAttributesForItem(at: $0.indexPath)! : $0 }
    }

    open override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        guard let currentItemAttributes = super.layoutAttributesForItem(at: indexPath)?.copy() as? UICollectionViewLayoutAttributes,
            collectionView != nil else {
            // should never happen
            return nil
        }

        // if the current frame, once stretched to the full row intersects the previous frame then they are on the same row
        if indexPath.item != 0,
            let previousFrame = layoutAttributesForItem(at: IndexPath(item: indexPath.item - 1, section: indexPath.section))?.frame,
            currentItemAttributes.frame.intersects(CGRect(x: -.infinity, y: previousFrame.origin.y, width: .infinity, height: previousFrame.size.height)) {
            // the next item on a line
            currentItemAttributes.frame.origin.x = previousFrame.origin.x + previousFrame.size.width + evaluatedMinimumInteritemSpacingForSection(at: indexPath.section)
        } else {
            // the first item on a line
            currentItemAttributes.frame.origin.x = evaluatedSectionInsetForSection(at: indexPath.section).left
        }
        return currentItemAttributes
    }

    func evaluatedMinimumInteritemSpacingForSection(at section: NSInteger) -> CGFloat {
        return (collectionView?.delegate as? UICollectionViewDelegateFlowLayout)?.collectionView?(collectionView!, layout: self, minimumInteritemSpacingForSectionAt: section) ?? minimumInteritemSpacing
    }

    func evaluatedSectionInsetForSection(at index: NSInteger) -> UIEdgeInsets {
        return (collectionView?.delegate as? UICollectionViewDelegateFlowLayout)?.collectionView?(collectionView!, layout: self, insetForSectionAt: index) ?? sectionInset
    }
}

Kullanım: Öğeler arasındaki boşluk, temsilci tarafından belirlenir. collectionView (_:layout:minimumInteritemSpacingForSectionAt:).

Onu github'a koydum. https://github.com/Coeur/UICollectionViewLeftAlignedLayoutAslında hem kaydırma yönlerini (yatay ve dikey) destekleyen bir özellik ekledim.


1
2018-05-25 02:54





Burada NSCollectionViewFlowLayout için

class LeftAlignedCollectionViewFlowLayout: NSCollectionViewFlowLayout {

    var maximumCellSpacing = CGFloat(2.0)

    override func layoutAttributesForElementsInRect(rect: NSRect) -> [NSCollectionViewLayoutAttributes] {

        let attributesToReturn = super.layoutAttributesForElementsInRect(rect)

        for attributes in attributesToReturn ?? [] {
            if attributes.representedElementKind == nil {
                attributes.frame = self.layoutAttributesForItemAtIndexPath(attributes.indexPath!)!.frame
            }
        }
        return attributesToReturn
    }

    override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> NSCollectionViewLayoutAttributes? {

        let curAttributes = super.layoutAttributesForItemAtIndexPath(indexPath)
        let sectionInset = (self.collectionView?.collectionViewLayout as! NSCollectionViewFlowLayout).sectionInset

        if indexPath.item == 0 {
            let f = curAttributes!.frame
            curAttributes!.frame = CGRectMake(sectionInset.left, f.origin.y, f.size.width, f.size.height)
            return curAttributes
        }

        let prevIndexPath = NSIndexPath(forItem: indexPath.item-1, inSection: indexPath.section)
        let prevFrame = self.layoutAttributesForItemAtIndexPath(prevIndexPath)!.frame
        let prevFrameRightPoint = prevFrame.origin.x + prevFrame.size.width + maximumCellSpacing

        let curFrame = curAttributes!.frame
        let stretchedCurFrame = CGRectMake(0, curFrame.origin.y, self.collectionView!.frame.size.width, curFrame.size.height)

        if CGRectIntersectsRect(prevFrame, stretchedCurFrame) {
            curAttributes!.frame = CGRectMake(prevFrameRightPoint, curFrame.origin.y, curFrame.size.width, curFrame.size.height)
        } else {
            curAttributes!.frame = CGRectMake(sectionInset.left, curFrame.origin.y, curFrame.size.width, curFrame.size.height)
        }

        return curAttributes
    }
}

0
2018-03-02 21:05





İle "sorun" UICollectionViewFlowLayout hücreler için doğrulanmış bir hizalama uygular: Bir satırdaki ilk hücre sola hizalı, bir satırdaki son hücre sağa hizalı ve aradaki tüm diğer hücreler eşit bir şekilde eşit aralıklarla dağıtılır. minimumInteritemSpacing.

Bu yazının alt sınıflara göre bu sorunu çözdüğü birçok büyük yanıt var. UICollectionViewFlowLayout. Sonuç olarak, hücreleri hizalayan bir düzen elde edersiniz. ayrıldı. Hücreleri sabit aralıklarla dağıtmak için geçerli olan diğer bir çözüm, hücreleri hizalamaktır. sağ.

AlignedCollectionViewFlowLayout

Bir tane oluşturdum UICollectionViewFlowLayout tarafından da önerildiği gibi benzer bir fikir izleyen alt sınıf mat ve Chris Wagner ya hücreleri hizalayabilir

  ayrıldı:

Left-aligned layout

veya   sağ:

Right-aligned layout

Buradan buradan indirebilir, düzen dosyasını projenize ekleyebilir ve AlignedCollectionViewFlowLayout koleksiyon görünümünüzün düzen sınıfı:
https://github.com/mischa-hildebrand/AlignedCollectionViewFlowLayout

Nasıl çalışır (sol hizalı hücreler için):

 +---------+----------------------------------------------------------------+---------+
 |         |                                                                |         |
 |         |     +------------+                                             |         |
 |         |     |            |                                             |         |
 | section |- - -|- - - - - - |- - - - +---------------------+ - - - - - - -| section |
 |  inset  |     |intersection|        |                     |   line rect  |  inset  |
 |         |- - -|- - - - - - |- - - - +---------------------+ - - - - - - -|         |
 | (left)  |     |            |             current item                    | (right) |
 |         |     +------------+                                             |         |
 |         |     previous item                                              |         |
 +---------+----------------------------------------------------------------+---------+

Buradaki konsept, endeksli mevcut hücrenin olup olmadığını kontrol etmektir. ben ve endeksi olan önceki hücre i-1 aynı çizgiyi işgal et.

  • İndeksli hücre yoksa bensatırdaki en soldaki hücredir.
    → Hücreyi, toplama görünümünün sol kenarına taşıyın (dikey konumunu değiştirmeden).
  • Yaparlarsa, endeksi olan hücre ben satırdaki en soldaki hücre değil.
    → Önceki hücrenin çerçevesini alın (dizinle birlikte i-1) ve mevcut hücreyi yanına taşıyın.

Sağ hizalı hücreler için ...

... aynısını versin, yani Sonraki indeksi olan hücre i 1 + yerine.


0
2018-04-14 23:40