Проблемы с перерисовкой NSCell
-
11-12-2019 - |
Вопрос
Я создаю NSCell
подкласс, который рисует некоторые объекты непосредственно в представлении (используя drawInRect:fromRect:operation:fraction:respectFlipped:hints:
), а также рисует NSButton
экземпляр, просто используя NSView addSubview:
селектор.
Хотя все объекты, нарисованные с использованием первого метода, прорисовываются правильно, у меня возникают проблемы с рисованием NSButton
правильно.Проблема в том, что мой NSButton
экземпляры будут рисоваться в нужных местах, но несколько раз.
Я некоторое время исследовал это в Интернете, и некоторые люди предлагали использовать кеш, но я не уверен, что это эффективно.(использование массива, содержащего кнопки, с использованием цикла for определенно приведет к медленной прокрутке, поскольку я показываю много данных...)
Как бы вы это сделали?Я лаю не на то дерево?
Это соответствующий код:
- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
NSRect _controlRect = cellFrame;
float _Y = cellFrame.origin.y;
NSRect _accessoryRect = NSMakeRect(_controlRect.size.width - 70.0f, _Y + 9.0f, 50.0f, 23.0f);
_switch = [self _choiceSwitch];
[_switch setFrame:_accessoryRect];
[controlView addSubview:_switch];
}
Решение
Короче: Друзья не позволяют друзьям addSubview
, пока рисую.
Это фундаментальное и не особенно хорошо объяснено аспект управления интерфейсами управления, но с ним важно разобраться.
Позвольте вашим контроллерам диктовать «порядок» подпредставлений, и вы можете спать спокойно, зная, что с этой кнопкой не следует откровенно испортить (что НЕ тот случай, если ее толкают внутри ваших пользовательских процедур рисования).
В этом переулке легко застрять, потому что, типа, эй, я добавил NSImageView
в моем initWithFrame
и вроде все в порядке… Но это просто как-то не так, как ты должен это делать, я думаю… и когда вы начинаете создавать подклассы NSControl и т. д.это когда ты начинаешь понимать почему.
Обновлено: Вот действительно хорошая статья о разработке пользовательских элементов управления. с такой же отличный образец проекта присоединенный — который воплощает такую организацию кода, которая может помочь избежать проблем такого типа.Например..в классе контроллера вы заметите, как он сохраняет каждую кнопку отдельной, уникальной и независимой от работы других представлений…
for (int butts = 0; butts < 3; butts++) {
NSRect buttFrame = NSMakeRect(0, butts * 10, 69, 10);
ExampleButt *butt = [[ExampleButt alloc]initWithFrame:buttFrame];
[mainView addSubview:butt];
}
Другие советы
"Рисунок" NSButton
добавлять его экземпляр в иерархию представлений каждый раз, когда вы рисуете саму ячейку, определенно плохая идея.Вместо этого создайте NSButtonCell и настройте его по своему вкусу.Тогда в вашем -[NSCell drawInteriorWithFrame:inView:]
используйте ivar ячейки, чтобы нарисовать ее внешний вид.
Если вы хотите иметь кликабельный NSButton
экземпляр в каждой ячейке табличного представления, старайтесь избегать вызова addSubview:
когда возможно.Каждый раз, когда вы это делаете, представление элемента управления может аннулировать свой макет и перерисовывать все с нуля, создавая в вашем случае своего рода рекурсию.