uem
uem

Reputation: 735

Scrolling an NSScrollView while trying to preserve the position of a subview

I have a subclass of NSScrollView. Within that scrollView's documentView I have a couple of NSViews. Finally, I add an NSView called aView to the documentView.

I want aView to be at the bottom of the documentView as long as there's no scrolling needed. Scrolling is only possible along the y-axis.

If the documentView is too high for the contentView - so that scrolling is needed - I want aView to be displayed at the bottom of the contentView.

This works fine with the code that you see below.

Here's my Problem: The moment I start to scroll, I want aView to stay at the bottom of the contentView but aView just scrolls with all the other views within documentView. In other words: I want aView's position to be fixed at the bottom of the visible rect of my scrollView if scrolling is needed and to stick to the bottom of the documentView if the contentView is high enough to show the whole documentView.

Is there a way to do that? Where do I go wrong?

Here's the code in my subclassed NSScrollView:

    [documentView addSubview:aView];

    aView.translatesAutoresizingMaskIntoConstraints = NO;

    NSLayoutConstraint *documentAViewBottom = [NSLayoutConstraint constraintWithItem:documentView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:aView attribute:NSLayoutAttributeBottom multiplier:1 constant:0];
    documentAViewBottom.priority = NSLayoutPriorityDefaultHigh;
    [documentView addConstraint:documentAViewBottom];

    NSLayoutConstraint *aViewMaxYEdge = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:aView attribute:NSLayoutAttributeBottom multiplier:1 constant:5];
    [self addConstraint:aViewMaxYEdge];

    [documentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[aView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(aView)]];

Upvotes: 0

Views: 337

Answers (1)

lead_the_zeppelin
lead_the_zeppelin

Reputation: 2052

I am kinda oldschool and NSLayoutConstraints don't appeal to me, so here is a alternate proposed manual solution

from your subclass of NSScrollView when you set up the document view,

[self.contentView setPostsBoundsChangedNotification:YES];

then subscribe to the bounds changed

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(contentViewDidScroll:)
                                                     name:NSViewBoundsDidChangeNotification object:self.contentView];

then in

-(void)contentViewDidScroll
{
    double widthOfAView = aView.frame.size.width;
    double heightOfAView = aView.frame.size.height;
    [aView setFrameOrigin:NSMakePoint(NSMinX(self.contentView.bounds) - widthOfAView, NSMaxY(self.contentView.bounds) - heightOfAView)];
}

All of this assuming your isFlipped is overridden to YES, of course.

Upvotes: 2

Related Questions