我需要知道任何NSSplitView子视图的帧何时发生了变化,但只有在它们完成大小调整之后才会知道。
目前我在NSSplitView子类中使用它:
[[NSNotificationCenter defaultCenter] addObserver: self
selector: @selector(didResize:)
name: NSSplitViewDidResizeSubviewsNotification
object: self];
但我遇到的问题是,当分割视图被调整大小或包含窗口改变它的帧大小时,这会发送数百个通知。这对性能产生了很大的不利影响!
一旦拆分视图改变了框架(不添加任何开销或杂乱 - 如果调整大小已经停止,则经常检查计时器并不是我想要的解决方案),我怎么能分辨出来。
答案 0 :(得分: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.
}
顺便说一句,如果此代码所在的类是拆分视图的委托,那么您不需要注册此通知,它会自动注册。
编辑后:
我确实找到了另一种不使用任何计时机制的方法,但我不知道它有多强大。它依赖于splitView:constrainMinCoordinate:ofSubviewAt:在你在分隔符中的mouseDown时调用的事实,并且再次使用mouseUp。当应用程序第一次启动时(或者当分割视图所在的窗口被加载,或者某些东西 - 我没有用多个窗口测试它时)它也被调用一次。因此,将“timesCalled”设置为-1(而不是0)是为了让逻辑在应用程序启动时忽略第一次调用。此后,if子句在委托方法的每个其他调用(将在mouseUp上)的计算结果为true。
- (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;
}
答案 1 :(得分:0)
您可以从子类中的窗格拆分器中查找mouseDown mouseDragged和mouseUp事件。此时,您可以使用它来发布子类的通知。 您可以检查现有的NSSplitView子类,如古老的RBSplitView,看看它们是否已经完成了您想要的操作。
答案 2 :(得分:0)
仅实施此委托方法。 当我实现其他调整大小的委托方法时,结果搞砸了。
每次鼠标移动时都会调用此方法,并在释放鼠标时再次调用此方法。
- (void)splitViewDidResizeSubviews:(NSNotification *)notification {
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;
}
}
答案 3 :(得分:0)
viewDidEndLiveResize
在窗口调整大小和分隔线拖动后在 NSSplitView
上调用。您可以使用它发送自定义通知。
extension Notification.Name {
static public let didEndLiveResize = Notification.Name("didEndLiveReze")
}
class SplitView: NSSplitView
{
override func viewDidEndLiveResize() {
super.viewDidEndLiveResize()
NotificationCenter.default.post(name: .didEndLiveResize, object: self)
}
}