2013-05-18 3 views
1

Мне нужно знать, когда кадр любых подзонов NSSplitView изменился, но только после того, как они закончили изменение размера.NSSplitView - Как я могу получить уведомление ПОСЛЕ того, как представление закончило изменение размера?

В настоящее время я использую это в подклассе NSSplitView:

[[NSNotificationCenter defaultCenter] addObserver: self 
             selector: @selector(didResize:) 
             name: NSSplitViewDidResizeSubviewsNotification 
             object: self]; 

Но проблема у меня есть, что это посылает сотни уведомлений как вид раскола изменения размера или содержательное окно изменяет это размер кадра. Это отрицательно сказывается на производительности!

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

+0

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

ответ

1

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

-(void)splitViewDidResizeSubviews:(NSNotification *)notification { 
    [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(respondToSubviewChange) object:nil]; 
    [self performSelector:@selector(respondToSubviewChange) withObject:nil afterDelay:.1]; 
} 

-(void)respondToSubviewChange { 
    NSLog(@"here"); 
    // Do your work here. 
} 

BTW, если класс, что этот код в это делегат зрения раскола, то вам не нужно регистрироваться для этого уведомления, он автоматически регистрируется.

После Edit:

Я нашел еще один способ, который не использует какой-либо механизм синхронизации, но я не знаю, насколько прочной она. Он полагается на то, что splitView: constrainMinCoordinate: ofSubviewAt: вызывается, когда вы mouseDown в делителе, и снова с помощью mouseUp. Он также называется один раз, когда приложение запускается сначала (или, может быть, когда окно с разделенным видом загружено, или что-то еще - я не тестировал его более чем с одним окном). Таким образом, установка «timeCalled» на -1 (вместо 0) заключается в том, чтобы заставить логику игнорировать этот первый вызов при запуске приложения. После этого предложение if оценивает значение true на каждом другом вызове (который будет на mouseUp) методу делегата.

- (CGFloat)splitView:(NSSplitView *)splitView constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)dividerIndex { 
    static int timesCalled = -1; 
    if (timesCalled % 2 == 1) { 
     NSLog(@"Do stuff"); 
     // Do your work here. 
    } 
    timesCalled ++; 
    return 0 // 0 allows you to minimize the subview all the way to 0; 
} 
0

Вы можете посмотреть на MouseDown mouseDragged и MouseUp событий внутри панели разветвителя в подклассе. В этот момент вы можете использовать это для публикации уведомления из подкласса. Вы можете проверить существующие подклассы NSSplitView, такие как почтенный RBSplitView, и посмотреть, действительно ли они делают то, что вы хотите.

0

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

Этот метод вызывается каждый раз, когда мышь перемещается и еще раз, когда мышь отпущена.

- (Недействительными) splitViewDidResizeSubviews: (NSNotification *) уведомление {

if (notification.object == self.contentSplitView){ //get the right splitview 

    static CGFloat last = 0; //keep tracks with widths 
    static BOOL didChangeWidth = NO; //used to ignore height changes 

    CGFloat width_new = self.tableview_images.frame.size.width; //get the new width 
    if (last == width_new && didChangeWidth){ // 
     [self.tableview_images reloadData]; 

     NSLog(@"finish!"); 
     didChangeWidth = NO; 

    } else { 


     if (last != width_new){ 
      if (last != 0){ 
       didChangeWidth = YES; 
      } 
     } 
    } 
    last = width_new; 

} 

}