هل يمكن nscollectionview تلقائيًا عرض العرض الفرعي لعرض عمود واحد

StackOverflow https://stackoverflow.com/questions/2107755

سؤال

انا لدي NSCollectionView التي تحتوي على مجموعة من CustomViews. في البداية ، قام ببلاطات العرض الفرعية في أعمدة وصفوف مثل الشبكة. ثم قمت بتعيين ملف Columns خاصية في ib إلى 1 ، لذلك الآن يعرضهم واحدًا تلو الآخر في الصفوف. ومع ذلك ، على الرغم من بلدي CustomView عرض 400 بكسل ، تم تعيينه على التلقائي ، NSCollectionView يبلغ عرضه 400 بكسل ، ويتم تعيينه على عمود واحد ، يتم رسم الآراء الفرعية حوالي 80 بكسل.

أعلم أنه يمكنني الالتفاف على هذا عن طريق الاتصال:

CGFloat width = collectionView.bounds.size.width;
NSSize size = NSMakeSize(width, 85);
[collectionView setMinItemSize:size];
[collectionView setMaxItemSize:size];

لكن وضع هذا الرمز في awakeFromNib طريقة بلدي WindowController يحدد العرض الصحيح فقط عند إطلاق البرنامج. عندما أقوم بتغيير حجم النافذة (و NSCollectionView التلقائي كما حددت) ، تبقى CustomViews في عرضها في البداية.

يسعدني أن أعتني بتغيير حجم الرؤية الفرعية بنفسي إذا لزم الأمر ، لكنني جديد تمامًا على الكاكاو ولا يمكنني العثور على أي مقالات تشرح كيفية القيام بمثل هذا الشيء. هل يستطيع احد توجيهي الي الوجهة الصحيحة؟

أنتوني

هل كانت مفيدة؟

المحلول

مدونة مات غالاغر الرائعة الكاكاو مع الحب هو حول لمعالجة هذا. هذا الأسبوع ، شارك تفاصيل الارتباطات لعرض العمود الواحد مثل تلك المعنية:

http://cocoawithlove.com/2010/03/designing-view-with-bindings.html

الإدخال التالي ، يعد بمشاركة بقية التنفيذ ، والذي يجب أن يمنحك ما تبحث عنه.

(يجب أن أشير إلى أنه يقوم بتصنيف NSVIEW مباشرة وإعادة تنفيذ العديد من ميزات NSCOLLECTIONVIEW. يبدو أن هذا أمر شائع ؛ ليس الكثير من الناس مولعين بالفئات الفرعية NSCOLLECTIONVIEW.)

تعديل: يبدو أنه كسر وعده ... لم نتلق هذا المنشور. انظر إجابة Tofutim أدناه بدلاً من ذلك.

نصائح أخرى

الإجابة الحقيقية هي ضبط MaxItemSize على 0،0 (NSZeroSize). خلاف ذلك ، يتم حسابه.

[self.collectionView setMaxItemSize:NSZeroSize];

يمكن ضبط هذا في awakeFromNib.

أعلم أن هذا أ جداً الرد المتأخر لكنني حصلت على نفس المشكلة وآمل أن يساعد حل لي شخص ما. الحل هو الوصول إلى حدود مرفق عرض التمرير وليس عرض المجموعة نفسها. حتى لحلها ، تحتاج إلى استبدال السطر الأول بـ:

CGFloat width = collectionView.enclosingScrollView.bounds.size.width;

لم أستطع الحصول على هذا العمل مع تخطيط افتراضي - لكن من السهل إلى حد ما تنفيذ تصميم مخصص:

/// Simple single column layout, assuming only one section
class SingleColumnLayout: NSCollectionViewLayout {

    /// Height of each view in the collection
    var height:CGFloat = 100

    /// Padding is wrapped round each item, with double an extra bottom padding above the top item, and an extra top padding beneath the bottom
    var padding = EdgeInsets.init(top: 5, left: 10, bottom: 5, right: 10)

    var itemCount:Int {
        guard let collectionView = collectionView else {
            return 0
        }

        return collectionView.numberOfItems(inSection:0)
    }

    override func shouldInvalidateLayout(forBoundsChange newBounds: NSRect) -> Bool {
        return true
    }

    override open func layoutAttributesForItem(at indexPath: IndexPath) -> NSCollectionViewLayoutAttributes? {
        let attributes = NSCollectionViewLayoutAttributes(forItemWith: indexPath)
        guard let collectionView = collectionView else {
            return attributes
        }

        let bounds = collectionView.bounds
        let itemHeightWithPadding = height + padding.top + padding.bottom
        let row = indexPath.item

        attributes.frame = NSRect(x: padding.left, y: itemHeightWithPadding * CGFloat(row) + padding.top + padding.bottom , width: bounds.width - padding.left - padding.right , height: height)
        attributes.zIndex = row

        return attributes
    }

    //If you have lots of items, then you should probably do a 'proper' implementation here
    override open func layoutAttributesForElements(in rect: NSRect) -> [NSCollectionViewLayoutAttributes] {
        var attributes = [NSCollectionViewLayoutAttributes]()

        if (itemCount>0){
            for index in 0...(itemCount-1) {
                if let attribute = layoutAttributesForItem(at: NSIndexPath(forItem: index, inSection: 0) as IndexPath) {
                    attributes.append(attribute)
                }
            }
        }

        return attributes
    }

    override open var collectionViewContentSize: NSSize {

        guard let collectionView = collectionView else {
            return NSSize.zero
        }

        let itemHeightWithPadding = height + padding.top + padding.bottom

        return NSSize.init(width: collectionView.bounds.width, height: CGFloat(itemCount) * itemHeightWithPadding + padding.top + padding.bottom )
    }
}

ثم كل ما تحتاجه هو

var layout=SingleColumnLayout()
collectionView.collectionViewLayout = layout

واحد آخر في وقت متأخر - لقد تحولت للتو إلى استخدام NSTableView وتوفير NSView بواسطة delegate طريقة.

يأتي التلقائي مجانًا ، وعمود واحد سهل ، ويجعله بشكل أسرع بشكل كبير.

دعنا نقول أنك تريد مجموعة CollectionViewItem بحجم 200 × 180 بكسل ، ثم يجب عليك تعيين:

[myCollectionView setMinItemSize:NSMakeSize(200, 180)];
[myCollectionView setMaxItemSize:NSMakeSize(280, 250)];

يجب أن يكون حجم الحد الأقصى الخاص بك كبيرًا بما يكفي لتبدو جيدًا وإعطاء مساحة كافية لتمتد لتناسب عرض المجموعة.

إذا كان لديك عدد ثابت من الأعمدة ، فيمكنك على الأرجح استخدام (0،0) ، ولكن إذا كنت تريد عددًا ديناميكيًا من الصفوف والأعمدة كما أردت .. يجب عليك تعيين حجم MIN ثابت وحجم أكبر.

على الرغم من أنك قد تحصل على عرض مجموعة لتتصرف كما تريد ، أعتقد أن لديك مشكلة في التصميم

يجب عليك استخدام أ NSTableView وضبط الأعمدة على 1 وتحجيمها على أي شيء سوى "لا شيء". NSTableView مخصص للبيانات الجدولية ، بالإضافة إلى أنه يمكن إعادة تدوير الخلايا التي تعطي أداءً رائعًا لكمية كبيرة من العناصر. NSCollectionView يشبه التصميم الخطي الذي يرتب العناصر في الشبكة ، مع التمرير الرأسي. يكون من المفيد أن يتغير رقم العمود ديناميكيًا للسماح بعرض المزيد من العناصر على الشاشة ، وعادة ما يعتمد على اتجاه الجهاز وحجم الشاشة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top