Frage

Ich habe eine NSView (myView) in einem NSScrollView (myScrollView) gewickelt bekam. Mit Zoom-In / Out-Taste kann der Benutzer die Skala von myView verändern. Wenn der Benutzer gerade an einer bestimmten Stelle in myView gescrollt wird, würde Ich mag auf dem Bildschirm, dass ein Teil der Ansicht zu halten, nachdem die Zoomstattgefunden hat.

Ich habe Code, der wie folgt aussieht:

    // preserve current position in scrollview
    NSRect oldVisibleRect = [[myScrollView contentView] documentVisibleRect];
    NSPoint oldCenter = NSPointFromCGPoint(CGPointMake(oldVisibleRect.origin.x + (oldVisibleRect.size.width  / 2.0),
                                                       oldVisibleRect.origin.y + (oldVisibleRect.size.height / 2.0)));

    // adjust my zoom
    ++displayZoom;
    [self scaleUnitSquareToSize:NSSizeFromCGSize(CGSizeMake(0.5, 0.5))];
    [self calculateBounds];  // make sure my frame & bounds are at least as big as the visible content view
    [self display];

    // Adjust scroll view to keep the same position.
    NSRect newVisibleRect = [[myScrollView contentView] documentVisibleRect];
    NSPoint newOffset = NSPointFromCGPoint(CGPointMake((oldCenter.x * 0.5) - (newVisibleRect.size.width  / 2.0),
                                                       (oldCenter.y * 0.5) - (newVisibleRect.size.height / 2.0)));
    if (newOffset.x < 0)
        newOffset.x = 0;
    if (newOffset.y < 0)
        newOffset.y = 0;

    [[myScrollView contentView] scrollToPoint: newOffset];
    [myScrollView reflectScrolledClipView: [myScrollView contentView]];

Und es scheint irgendwie nahe, aber es ist nicht ganz richtig, und ich kann nicht herausfinden, was ich falsch mache. Meine beiden Fragen sind:

1) Gibt es nicht einen eingebauten in etwas entlang der Linien von:

   [myView adjustScaleBy: 0.5 whilePreservingLocationInScrollview:myScrollView];

2) Wenn nicht, kann man sehen, was ich falsch mache in meinem „langen Weg um“ -Ansatz vor?

Danke!

War es hilfreich?

Lösung

Mit der selben Bildlaufposition nach der Skalierung ist nicht einfach. Eine Sache, die Sie entscheiden müssen, ist, was Sie unter „gleichen“ - wollen Sie den oberen, mittleren oder unteren Rand des sichtbaren Bereichs vor der Skalierung an Ort und Stelle zu bleiben, nach der Skalierung

?

Oder intuitive, wollen Sie die Position, dass ein Prozentsatz des sichtbaren rect gleich den Prozentsatz an seinem Platz bleibt, die Sie gescrollt werden das Dokument nach unten, wenn Sie (zB Start, so dass die Mitte des Daumens des scroller nicht nach oben oder unten während einer Skala, die Daumen wächst gerade oder schrumpft).

Wenn Sie die letztere Effekt wollen, eine Möglichkeit, es zu tun ist, den verticalScroller und horizontalScroller des NSScrollView, und dann ihre ‚floatvalue des lesen. Diese sind normieren von 0 bis 1, wobei ‚0‘ bedeutet, dass Sie am Anfang des Dokuments ist und 1 bedeutet, dass Sie am Ende sind. Das Schöne an dem Stellrad für diese fragen, ist, dass, wenn das Dokument kürzer als die NSScrollView ist, das Stellrad noch eine vernünftige Antwort in allen Fällen zu Ihrer Suche nach ‚floatvalue‘, so dass Sie nicht auf einen speziellen Fall dieses.

Nachdem Sie die Größe, stellen Sie die Bildlaufposition des NSScrollView den gleichen Prozentsatz, um es vor der Waage war - aber leider ist hier, wo ich meine Hände ein wenig Welle. Ich habe das nicht in eine Weile in meinem Code getan, aber wie ich Sie daran erinnern, kann nicht nur die NSScrollers gesetzt ‚floatvalue ist direkt -. Sie werden gescrollt aussehen, aber sie werden nicht wirklich die NSScrollView beeinflussen

So, hast du etwas Mathematik zu schreiben, um den neuen Punkt oben links in Ihrem Dokument zu berechnen, basierend auf dem Prozentsatz, der Du durch sie sein willst - auf der y-Achse, zum Beispiel, wird es so aussehen, " wenn das Dokument jetzt kürzer als die Scroll des content ist, blättert 0-zu-Punkt, andernfalls zu einem Punkt bewegen, das ist ((Höhe der content - Höhe von Document) * oldVerticalPercentage). nach unten Dokument“ X-Achse ist natürlich ähnlich.

Auch ich bin fast sicher, Sie hier nicht einen Anruf müssen -Display, und im Allgemeinen sollte es nicht immer nennen, nie. (-SetNeedsDisplay. Höchstens)

-Wil

Andere Tipps

Me denkt, dass Sie zu viel geben ...; -)

// instead of this:
NSPoint oldCenter = NSPointFromCGPoint(CGPointMake(oldVisibleRect.origin.x +
    (oldVisibleRect.size.width  / 2.0),

// use this:
NSPoint oldCenter = NSMakePoint(NSMidX(oldVisibleRect), NSMaxY(oldVisibleRect));

// likewise instead of this:
[self scaleUnitSquareToSize:NSSizeFromCGSize(CGSizeMake(0.5, 0.5))];

// use this:
[self scaleUnitSquareToSize:NSMakeSize(0.5, 0.5)];

// and instead of this
NSPoint newOffset = NSPointFromCGPoint(CGPointMake(
    (oldCenter.x * 0.5) - (newVisibleRect.size.width  / 2.0),
    (oldCenter.y * 0.5) - (newVisibleRect.size.height / 2.0)));

// use this:
NSPoint newOffset NSMakePoint(
    (oldCenter.x - NSWidth(newVisibleRect)) / 2.f,
    (oldCenter.y - NSHeight(newVisibleRect)) / 2.f);

Dies ist eine alte Frage, aber ich hoffe, dass jemand für diese Suche findet meine Antwort nützlich ...

float zoomFactor = 1.3;

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

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

    [[scrollView documentView] scrollPoint:newrect.origin];
}

-(void)zoomOut
{
    NSRect visible = [scrollView documentVisibleRect];
    NSRect newrect = NSOffsetRect(visible, -NSWidth(visible)*(zoomFactor - 1)/2.0, -NSHeight(visible)*(zoomFactor - 1)/2.0);

    NSRect frame = [scrollView.documentView frame];

    [scrollView.documentView scaleUnitSquareToSize:NSMakeSize(1/zoomFactor, 1/zoomFactor)];
    [scrollView.documentView setFrame:NSMakeRect(0, 0, frame.size.width / zoomFactor, frame.size.height / zoomFactor)];

    [[scrollView documentView] scrollPoint:newrect.origin];
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top