Автоматически регулировать размер NSTableView

У меня есть NSTableView, который должен изменять размер кадра при добавлении строки. Я бы сделал 2 свойства, maxHeight и minHeight, и если какие-либо строки добавляются или удаляются, я бы изменил размер представления таблицы, чтобы оно соответствовало его содержимому, если оно не превышает предела.

Например, панель загрузки Safari (10.7 или более поздняя версия). Кто-нибудь знает, как это сделать? Я хотел бы справиться с этим в подклассе. Так что не возитесь с изменением размера в классе делегата.

По крайней мере, мне нужно знать, какой метод вызывается при перезагрузке табличного представления. reloadTable вызывает только реальный метод перезагрузки, поэтому успеха нет.


person IluTov    schedule 18.11.2012    source источник
comment
Недавно я опубликовал ответ на аналогичную проблему. Вы можете найти его здесь: stackoverflow.com/a/44093345/3184888   -  person JanApotheker    schedule 21.05.2017


Ответы (1)


Я сделал что-то подобное некоторое время назад, и я сделал это на контроллере, а не на подклассе (извините, если это не то, что вы ищете). По сути, я написал метод, который вычислял высоту таблицы, добавляя высоту всех строк. И каждый раз, когда я добавлял или удалял строку из таблицы, я вызывал этот метод. Вот кое-что, с чего можно начать:

- (void)adjustTableSize
{
    NSInteger minHeight = ...
    NSInteger maxHeight = ...

    NSInteger tViewHeight = 0;
    for (int i = 0; i < [tableView numberOfRows]; i++) {
        NSView* v = [tableView viewAtColumn: 0 row: i makeIfNecessary: YES]; // Note that this is for view-based tableviews
        tViewHeight += v.frame.size.height;
    }

    NSInteger result = MIN(MAX(tViewHeight, minHeight), maxHeight);

    // Do something with result here
}

Если вы действительно хотите, чтобы это было в подклассе, это должно быть возможно, но может быть сложно решить, как...

РЕДАКТИРОВАТЬ:

Если вы не возражаете против работы с недокументированными API, вот более простая версия:

- (void)adjustTableSize
{
    NSInteger minHeight = ...
    NSInteger maxHeight = ...
    NSInteger result = MIN(MAX([tableView _minimumFrameSize].height, minHeight), maxHeight);

    // Do something with result here
}

Поскольку это не задокументировано, я не могу обещать, что это сработает, но, судя по моим испытаниям, это работает. И это может быть быстрее, чем создавать представления только для получения их высоты, особенно если у вас много строк.

person Alex    schedule 18.11.2012
comment
Это круто, единственное, что нужно настроить, это найти правильный метод в подклассе NSTableView. Есть тонны, как вы можете видеть в дампе класса выше. У вас есть идея, какой из них использовать? - person IluTov; 19.11.2012
comment
О, и кстати. вы можете просто использовать enumerateAvailableRowViewsUsingBlock: - person IluTov; 19.11.2012
comment
Хорошо, я немного поиграл с ним, и он много глючит. Вы установили рамку NSScrollView? - person IluTov; 19.11.2012
comment
Да, вы правы насчет enumerateAvailableRowViewsUsingBlock. Нет, я действительно не знаю. Но... может быть, вы могли бы создать подкласс realoadData, сначала вызвав super, а затем выполнив это (?) И нет, я добавил некоторые отступы и установил фрейм непосредственно в окно, содержащее табличное представление, что означает, что табличное представление изменяет размеры косвенно. Не забывайте, что если вы меняете рамку таблицы напрямую, вы можете возиться с прокруткой, которая ее содержит (поэтому я думаю, что лучше делать это на контроллере...). Но я ничего не делал и с прокруткой. - person Alex; 19.11.2012
comment
Если подумать, я думаю, что enumerateAvailableRowVjewUsingBlock: может быть не тем, что нам здесь нужно. Этот метод включает все видимые в данный момент представления, которые анимируются или сохраняются табличным представлением. Нет никакой гарантии, что количество просмотров, которые вы получите, совпадает с количеством строк. Если вы используете этот метод и у вас возникли проблемы, попробуйте цикл for. - person Alex; 19.11.2012
comment
Хорошо, ты прав. Но все равно глючит, попробую изменить размер окна. Спасибо - person IluTov; 19.11.2012
comment
Я не нашел лучшего ответа, если найду, дам вам знать :) - person IluTov; 02.01.2013