2012-06-08 1 views
2

Я прочитал много ответов на вопросы о динамическом изменении размера NSWindows и ничего еще не сработало.Динамически изменяет размер NSWindow на основе высоты NSOutlineView

Я создал «popover», как окно, которое будет отображаться в строке меню, я не мог использовать NSPopover, потому что он не достаточно настраиваемый с точки зрения дизайна. Моя текущая иерархия вид выглядит следующим образом:

NSWindow Subclass 
    - NSView (clears the titlebar rendering, draws popover arrow) 
    - NSView (contentView) 
     - NSOutlineView (main table of content) 
     - NSView (window footer) 

Что мне нужно для окна, чтобы расширяться и сжиматься с элементами в NSOutlineView расширяться и сжиматься, так что окно всегда точно правильная высота для представления контура, нижний колонтитул и стрелка popover вверху.

У меня есть методы для расчета требуемой высоты для контурного представления на основе содержимого. До сих пор я пытался пересчитать размер, когда awakeFromNib вызывается на контроллере представления контента, а затем снова на методах делегатов outlineViewItemDidCollapse: и outlineViewItemDidExpand:, но я никогда не могу правильно изменить размер окна.

Я пробовал много разных способов, и никто не работал. Есть ли «канонический» способ сделать это? Я видел, как люди говорили о -[NSWindow frameForContentRect:] в связи с этой проблемой, но я не могу понять, как это необходимо.

Возможно, я об этом совершенно ошибаюсь, надеюсь, что нет. Похоже, что это должно быть возможно, это просто получение правильных вещей в правильных местах. К сожалению, программирование графического интерфейса для меня не очень важно. Я был бы признателен за любые идеи или решения, которые есть у людей.

Спасибо.

Редактировать: Это было решено частично из-за отмеченного ответа и частично из-за нескольких других вещей. У очищающего NSView не была маска автосохранения, поэтому я установил ее для расширения во всех направлениях, это помогло с некоторыми проблемами изменения размера. Кроме того, метод, который я использовал для расчета требуемой высоты, был не совсем правильным и имел несколько проблем.

С предоставленным ответом, способ найти требуемую высоту хорош для некоторых обстоятельств, но у меня не было элемента «корня», который можно было измерить. Это то, что, возможно, необходимо принять во внимание.

ответ

2

Вот мой метод, он работает очень хорошо, но, вероятно, лучше, чем это.

- (void)outlineViewItemDidExpand:(NSNotification *)notification { 
    [self resizeWindowHeight]; 
} 
- (void)outlineViewItemDidCollapse:(NSNotification *)notification { 
    [self resizeWindowHeight]; 
} 
- (void)resizeWindowHeight { 
    NSRect wRect = [myWindow frame]; 
    NSRect oRect = [myoutlineView rectOfRow:([myoutlineView numberOfRows] - 1)]; //get rect of last row 
    CGFloat n = oRect.origin.y + oRect.size.height + 22; 
    wRect.origin.y = wRect.origin.y + (wRect.size.height - n); 
    wRect.size.height = n; 
    [myWindow setFrame:wRect display:YES animate:YES]; 
} 

Число представляет собой сумму: (верхнее окно - верхний контур) + высота Outline заголовка + высота горизонтальной прокрутки + (нижнее окно - нижняя контур) + высота панели

Мои настройки в IB для этого примера: без горизонтального скроллера и без заголовка, высота Outline = высота содержимогоView окна, поэтому 22 является границей окна.

Если у вас есть панель инструментов или горизонтальный скроллер скрыт автоматически, вам необходимо добавить условия в код, чтобы проверить видимость (панель инструментов и скроллер) и соответственно изменить высоту.

+0

Хорошо, это здорово. Я почти все это работаю. Основная проблема заключается в том, что окно меняет кадр до изменения в NSOutlineView, в идеале их необходимо синхронизировать. Любые идеи, как это можно сделать? – danpalmer

+0

У меня это почти синхронизировано с помощью 'dispatch_async'ing' setFrame: display: animate: 'call. С небольшими изменениями он должен работать. – danpalmer

+0

Хорошо. Теперь он работает красиво, но анимации не совсем своевременно, то есть есть какой-то графический джиттер, который мне не очень нравится. У вас есть какие-либо советы о том, что я могу сделать, чтобы остановить это? – danpalmer

0

Один из подходов состоит в том, чтобы записать начальную высоту контура и начальную высоту окна, а затем, по мере изменения высоты обзора, вычислите новую высоту окна = старая высота + (новая высота контура - старая высота контура). Работая только с точки зрения изменений от исходного состояния, это делает вещи более гибкими. Вам не нужно копировать весь макет кода, как если бы вы пересматривали размер вещей с нуля. Вы можете использовать IB, чтобы выложить окно, и он должен сохранить этот макет, не имея кода, который должен знать о специфике. И вы можете обновить макет в IB, и код все еще работает.

В противном случае я предлагаю вам показать, что вы попробовали, и объяснить, как это неправильно.