كيفية تحديد العناصر في NSOUTLineView دون nstreecontroller؟

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

  •  11-09-2019
  •  | 
  •  

سؤال

أنا استخدم NSOutlineView بدون NSTreeController ونفذت البيانات الخاصة بي الخاصة بي. ما هي أفضل طريقة لتحديد عنصر؟NSOutlineView الدعم بالفعل expandItem: و collapseItem:. وبعد وأنا في عداد المفقودين طريقة مفيدة مثل `selectitem :. كيف يمكنني أن أفعل ذلك برمجيا؟

شكرا لك.

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

المحلول

تذكر أن ننظر في الفائقة عندما لا يمكنك العثور على شيء ما. في هذه الحالة، تأتي إحدى الطرق التي تحتاجها من NSTableView، وهو Superclass NSOUTLine فوريا.

الحل هو احصل على مؤشر الصف للعنصر باستخدام rowForItem:, ، وإذا لم يكن -1 (عنصر غير مرئي / غير موجود)، إنشاء فهرس مجموعة معها مع [NSIndexSet indexSetWithIndex:] وتمرير هذا الفهرس ال selectRowIndexes:byExtendingSelection: طريقة.

نصائح أخرى

وهنا كيف انتهى أخيرا. الاقتراحات والتصحيحات هي موضع ترحيب دائما.

@implementation NSOutlineView (Additions)

- (void)expandParentsOfItem:(id)item {
    while (item != nil) {
        id parent = [self parentForItem: item];
        if (![self isExpandable: parent])
            break;
        if (![self isItemExpanded: parent])
            [self expandItem: parent];
        item = parent;
    }
}

- (void)selectItem:(id)item {
    NSInteger itemIndex = [self rowForItem:item];
    if (itemIndex < 0) {
        [self expandParentsOfItem: item];
        itemIndex = [self rowForItem:item];
        if (itemIndex < 0)
            return;
    }

    [self selectRowIndexes: [NSIndexSet indexSetWithIndex: itemIndex] byExtendingSelection: NO];
}
@end

لا، ليس هناك selectItem: طريقة، ولكن هناك rowForItem: طريقة. إذا جدمت ذلك مع نصيحة بيتر حول استخدام selectRowIndexes:byExtendingSelection: أعلاه، يجب أن يكون لديك كل المعلومات التي تحتاج إليها.

إذا كنت ترغب حقا في الحصول على طريقة لتحديد عنصر، فسوف أوصي بالاتصال setSelectedItem: من أجل الاتساق، يمكنك كتابة شيء مثل هذا في فئة NSOutlineView

- (void)setSelectedItem:(id)item {
    NSInteger itemIndex = [self rowForItem:item];
    if (itemIndex < 0) {
        // You need to decide what happens if the item doesn't exist
        return;
    }

    [self selectRowIndexes:[NSIndexSet indexSetWithIndex:itemIndex] byExtendingSelection:NO];
}

ليس لدي أي فكرة عما إذا كان هذا الرمز يعمل بالفعل؛ أنا فقط انقطعت منه لتوضيح المفهوم.

هنا مقتطف رمز اعتدت على تحديد عنصر برمجيا في PXSOURCELIST.

Sourselist هو كائن PXSoucelist العادي وأردت تحديد العنصر الثاني في المجموعة الأولى من الخطوط العريضة.

    NSInteger itemRow = [sourceList rowForItem:[[(SourceListItem *)[sourceListItems objectAtIndex:0] children] objectAtIndex:1]];
    [sourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:itemRow] byExtendingSelection:YES];

إذا كنت لا تعرف حتى الآن، فإن PXSOURCELIST هو استبدال ممتاز ل NSOutLineView إذا كنت تبحث عن الخطوط العريضة ل iTunes / Mail Style. استلامه هنا:pxsourcelist.

هذا سؤال قديم، لكن الوضع لا يزال هو نفسه. كما كان هناك طلب للحصول على نسخة سريعة، إليك تأخذ بلدي. لم أجد الإجابة المقبولة للعمل بالنسبة لي حيث أعتقد أنك يجب أن تتفاعل مباشرة مع فئة مصدر البيانات الخاصة بك بدلا من تمديد NSOutLineView. من المزعج أن الخطوط العريضة لن يجد الصفوف إلا إذا تم توسيعها وهذا هو السبب في أنه أكثر بساطة لاستخدام DataSource الخاص بك. في حالتي، وجدت أنه يجب عليك توسيع الأصل من العناصر الخاصة بك بترتيب عكسي، بحيث تبدأ في المستوى العلوي والعمل في طريقك نحو العنصر الفعلي الذي تحاول توسيعه. أشعر أنني يجب أن يتم بناؤها، ولكن إلا إذا فاتني شيء - ليس كذلك.

في هذا المثال FileItem هي فئة عنصر مجموعة بيانات البيانات الخاصة بي. يحتوي على خصائص "الأصل" الذي يجب أن يكون صالحا إذا كان جزءا من التسلسل الهرمي المعروض.

func selectItem(_ item: FileItem, byExtendingSelection: Bool = false) {
    guard let outlineView = outlineView else { return }

    var itemIndex: Int = outlineView.row(forItem: item)

    if itemIndex < 0 {
        var parent: FileItem? = item

        var parents = [FileItem?]()
        while parent != nil {
            parents.append(parent)
            parent = parent?.parent
        }

        let reversedTree = parents.compactMap({$0}).reversed()

        for level in reversedTree {
            outlineView.expandItem(level, expandChildren: false)
        }

        itemIndex = outlineView.row(forItem: item)
        if itemIndex < 0 {
            print("Didn't find", item)
            return
        }
    }

    print("Expanding row", itemIndex)

    outlineView.selectRowIndexes(IndexSet(integer: itemIndex), byExtendingSelection: byExtendingSelection)
    outlineView.scrollRowToVisible(itemIndex)
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top