7

Note:Both Horizontal and vertical scrollers are visible on the screen and work fine.But I cant make them move Programatically.

I am working on a cocoa desktop application.I am using the NSScrollview in my Mainmenu.xib file and I am creating an outlet in its owner which is Appdelegate.h . Here is the outlet

@property(nonatomic,retain) IBOutlet NSScrollView* scrollview;

When I try to set a new referencing outlet of my NSScrollview from the interface builder and take the line to file's owner I only see one option "delegate".I dont see the outlet scrollview. So I connect the scrollview to the delegate in file's owner (As I cant see the scrollview outlet).

Now I am trying to do auto scrolling in my code.Here is the code

for(int a=0;a<10000;a++)
{
    NSPoint pointToScrollTo = NSMakePoint ( 100+a,100+a );  // Any point you like.
    [[self.scrollview contentView] scrollToPoint: pointToScrollTo];
    [self.scrollview reflectScrolledClipView: [self.scrollview contentView]];
}

This code does not work and The scroller does not scroll automatically.

I am trying to make a slow scrolling animation with this code.

pkamb
  • 33,281
  • 23
  • 160
  • 191
zzzzz
  • 1,209
  • 2
  • 18
  • 45

4 Answers4

21

NSClipView has a scrollToPoint: method which can be used to scroll programmatically:

- (IBAction)scrollToMid:(id)sender
{
    CGFloat midYPoint = [self.scrollView contentView].frame.size.height/2.0;
    [[self.scrollView contentView] scrollToPoint:NSMakePoint(0.0, midYPoint)];
    [self.scrollView reflectScrolledClipView:[self.scrollView contentView]];
}

If you want animated scrolling, you have to set the boundsOrigin via animator proxy. (Because neither NSScrollView nor NSClipView expose an animatable scroll point property)

- (IBAction)scrollToMidAnimated:(id)sender
{
    [NSAnimationContext beginGrouping];
    [[NSAnimationContext currentContext] setDuration:2.0];
    NSClipView* clipView = [self.scrollView contentView];
    NSPoint newOrigin = [clipView bounds].origin;
    newOrigin.y = [self.scrollView contentView].frame.size.height/2.0;
    [[clipView animator] setBoundsOrigin:newOrigin];
    [NSAnimationContext endGrouping];
}
Hussain Shabbir
  • 14,801
  • 5
  • 40
  • 56
Thomas Zoechling
  • 34,177
  • 3
  • 81
  • 112
  • Thanks Man your method works. Upvoted and selected as the best answer! – zzzzz Nov 06 '13 at 06:39
  • Is there a way I can limit the user from manually scrolling ? – zzzzz Nov 06 '13 at 06:49
  • I dont want the user to scroll.I have hidden the scroll bars but the user is still able to scroll using the mouse scrller.Is this possible? – zzzzz Nov 06 '13 at 06:54
  • I dont want the scrollview to respond to user interaction.I just want to scroll programatically – zzzzz Nov 06 '13 at 06:57
  • Is there a way to give the final points to the clipview ? ie Instead of giving the origin of frame,can I give the x,y points to the clipview? – zzzzz Nov 08 '13 at 15:11
4

Better way to get this, flip the view. I have worked on this to get the scroll view to top.

-(void)scrollToTop:(NSScrollView *)scrollView
{
    NSPoint newScrollOrigin;
    if ([[scrollView documentView] isFlipped]) {
        newScrollOrigin=NSMakePoint(0.0,0.0);
    } else {
        newScrollOrigin=NSMakePoint(0.0,NSMaxY([[scrollView documentView] frame]) -NSHeight([[scrollView contentView] bounds]));
    }

    [[scrollView documentView] scrollPoint:newScrollOrigin];
}

That should be called in windowDidLoad to get the position .

-(void)windowDidLoad
{
    [super windowDidLoad];
    [self scrollToTop:_myScroll];
}
Popeye
  • 11,839
  • 9
  • 58
  • 91
Gowtham
  • 117
  • 12
1

In the identity inspector of your File's Owner, check its class. It must be set to NSApplication. You have to change it to AppDelegate to get the outlet scrollview to which you can connect your scrollview.

But the better option is to have a NSObject in your xib and set its class to AppDelegate. (However xcode create it by default, check if a item "AppDelegate" is present in the box "objects" below "Placeholders" where FileOwner is present). Now drag a Referencing outlet line from your scrollview to that object. It will show the IBOutlet object name of your Appdelegate class.

UPDATE: You cannot create a slow animation using a for loop. The for loop is so fast that you will see only the final result, not the complete scrolling. You need to use core animation for slow animation or NSTimer to delay scrolling to make it slow.

Plus please try using [scrollview documentView] , everywhere in place of [scrollview contentView] . Although i haven't given it a try.

Ok I worked on it, and this is the final result If your scroll bar is on top, the following will move it to end:

[scroll.contentView scrollToPoint:NSMakePoint(0, ((NSView*)scroll.contentView).frame.size.height - scroll.contentSize.height)];
[scroll reflectScrolledClipView: [scroll contentView]];

You may modify the above as per your need.

Also even your code is working, but you need to take the relative points in place of any point.

So instead of placing your code in the for loop, test it by dragging a button on your xib, and in its button action write:

NSPoint pointToScrollTo = NSMakePoint ( 100,100 );  // Any point you like.
[[scrollview contentView] scrollToPoint: pointToScrollTo];
[scrollview reflectScrolledClipView: [scrollview contentView]];

Now run the application, set the scroll of scrollview to some random position. Then click the button and check if scroll moved somewhere.

If it works then your code is fine, your only need to set the points accordingly. It worked for me.

Neha
  • 1,751
  • 14
  • 36
  • I have did what you said and Now I was able to connect the scrollview to the outlet but it still doesnt work – zzzzz Oct 30 '13 at 06:18
  • Still doesnt scroll programatically.I have used document view but it still doesnt work – zzzzz Oct 30 '13 at 06:43
1

I found that if you are using NSViewController, you need to do the 'scrollPoint' in your viewWillAppear method, rather than in viewWillLoad. FYI.

Popeye
  • 11,839
  • 9
  • 58
  • 91
Mark Knopper
  • 353
  • 4
  • 6
  • Mainly because it takes time for NSScollView to link up with the documentView, it's better to use `scrollPoint` or any other scrolling methods in a later stage – Harry Ng Mar 04 '16 at 03:41