Search code examples
objective-czoomingnsscrollview

Zoom image in a NSScrollView in objective-c


I have two NSScrollView's with scroll synchronized with each other (using Apple's example) and it is working. Next I implemented a zoom that would zoom both images (they have the same size by definition). The code for the zoom was adapted using code from here, which I present here:

    if (oldZoomValue > [sender floatValue]) // then we are zooming in
{
    float zoomFactor = 1 + oldZoomValue - [sender floatValue];

    oldZoomValue = [sender floatValue];

    NSRect visible = [synchroS_ScrollView documentVisibleRect];
    NSRect newrect = NSInsetRect(visible, NSWidth(visible)*(1 - 1/zoomFactor)/2.0, NSHeight(visible)*(1 - 1/zoomFactor)/2.0);
    NSRect frame = [synchroS_ScrollView.documentView frame];

    [synchroS_ScrollView.documentView scaleUnitSquareToSize:NSMakeSize(zoomFactor, zoomFactor)];
    [synchroS_ScrollView.documentView setFrame:NSMakeRect(0, 0, frame.size.width * zoomFactor, frame.size.height * zoomFactor)];
    [[synchroS_ScrollView documentView] scrollPoint:newrect.origin];

    NSRect visibleI = [synchroI_ScrollView documentVisibleRect];
    NSRect newrectI = NSInsetRect(visibleI, NSWidth(visibleI)*(1 - 1/zoomFactor)/2.0, NSHeight(visibleI)*(1 - 1/zoomFactor)/2.0);
    NSRect frameI = [synchroI_ScrollView.documentView frame];

    [synchroI_ScrollView.documentView scaleUnitSquareToSize:NSMakeSize(zoomFactor, zoomFactor)];
    [synchroI_ScrollView.documentView setFrame:NSMakeRect(0, 0, frameI.size.width * zoomFactor, frameI.size.height * zoomFactor)];

    [[synchroI_ScrollView documentView] scrollPoint:newrectI.origin];
}
else
{
// the equivalent but for zoom-out
}

If I use the zoom functionality without synchronized Scroll's, both images on the NSScrollView are zoomed nicely as expected. However, if they are synchronized, the program crashes with it seems to be a stack of several calls: on the main thread, it shows a lot of things like

#18 0x0000000100003e37 in -[SynchroScrollView synchronizedViewContentBoundsDidChange:] ()

and on the GDB:

This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000
sharedlibrary apply-load-rules all
[Switching to process 33162 thread 0x0]
[Switching to process 33162 thread 0xac03]
[Switching to process 33162 thread 0x903]
warning: Unable to restore previously selected frame.
warning: Unable to restore previously selected frame.
...
(gdb)

Can anyone point me a direction for debug or have any idea what is happening? Thank you for your help.


Solution

  • I'm not sure where you call the code for zooming the scrollView, but maybe zooming in scrollView A triggers zooming in scrollView B, which in turn triggers zooming in scrollView A again, creating an endless loop. changing the bounds in the synchronizedViewContentBoundsDidChange method would call the same method again and again.

    I know this question is a few months old, but maybe this helps :)