9

How do I center an NSView within an NSScrollView like the way "Preview" does?

rhombus
  • 145
  • 1
  • 6

2 Answers2

11

Read the Scroll View Programming Guide section on scrolling to a specific position. There are examples there for top or bottom. You'd just change the math to calculate the origin based on middle of your NSView. Something like:

-(void)scrollToCenter:(NSScrollView*)scrollView
{
    const CGFloat midX = NSMidX([[scrollView documentView] bounds]);
    const CGFloat midY = NSMidY([[scrollView documentView] bounds]);

    const CGFloat halfWidth = NSWidth([[scrollView contentView] frame]) / 2.0;
    const CGFloat halfHeight = NSHeight([[scrollView contentView] frame]) / 2.0;

    NSPoint newOrigin;
    if([[scrollView documentView] isFlipped])
    {
        newOrigin = NSMakePoint(midX - halfWidth, midY + halfHeight);
    }
    else
    {
        newOrigin = NSMakePoint(midX - halfWidth, midY - halfHeight);
    }

    [[scrollView documentView] scrollPoint:newOrigin];
}
nall
  • 15,899
  • 4
  • 61
  • 65
  • 4
    This doesn't work when the document view is smaller than the scroll view. The document view is pinned to the bottom left (or top left if flipped). – Nicolas Miari Nov 04 '13 at 01:21
1

In Swift:

extension NSScrollView {
    func scrollToCenter() {
        guard let docView = documentView else { return }
        let center = CGPoint(
            x: docView.bounds.midX - contentView.frame.width / 2,
            y: docView.bounds.midY - (docView.isFlipped ? -1 : 1) * contentView.frame.height / 2
        )
        docView.scroll(center)
    }
}
duan
  • 8,515
  • 3
  • 48
  • 70