Programmatically Scroll Nsscrollview to the Right

Programmatically scroll NSScrollView to the right

I finally got it to work by scrolling the content view :

scrollView.contentView.scrollPoint(NSPoint(width, 0))

NSScrollview not scrolling programmatically?

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];
}

Programmatically created NSTableView within NSScroll view cannot scroll horizontally

Removed the width constraint and it worked. Sometimes its just too obvious and you still don't see it.

Create NSScrollView Programmatically in an NSView - Cocoa

This code fragment should demonstrate how to create an NSScrollView programmatically and use it to display any view, whether from a nib or from code. In the case of a nib generated view, you simply need to load the nib file to your custom view prior, and have an outlet to your custom view (outletToCustomViewLoadedFromNib) made to File's Owner.

NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:[[mainWindow contentView] frame]];

// configure the scroll view
[scrollView setBorderType:NSNoBorder];
[scrollView setHasVerticalScroller:YES];

// embed your custom view in the scroll view
[scrollView setDocumentView:outletToCustomViewLoadedFromNib];

// set the scroll view as the content view of your window
[mainWindow setContentView:scrollView];

Apple has a guide on the subject, which I won't link to as it requires Apple Developer Connection access and their links frequently break. It is titled "Creating and Configuring a Scroll View" and can currently be found by searching for its title using Google.

NSScrollView Scroll to Point - Swift OSX

The Scroll View Programming Guide for Mac says this:

Two NSView methods support scrolling to reveal a specific location: scrollPoint: and scrollRectToVisible:. These high-level methods scroll the specified point or rectangle to the origin of the content view. You send these methods to the scroll view's document view or to one of its descendants. Scroll messages are passed up through the view hierarchy to the nearest enclosing NSClipView instance.

So the direct equivalent of your iOS code would be

contentView.scrollPoint(CGPointMake(0, 500))

Note that you send the message to the content view, not the scroll view.

Programmatically scroll a UIScrollView

You can scroll to some point in a scroll view with one of the following statements in Objective-C

[scrollView setContentOffset:CGPointMake(x, y) animated:YES];

or Swift

scrollView.setContentOffset(CGPoint(x: x, y: y), animated: true)

See the guide "Scrolling the Scroll View Content" from Apple as well.

To do slideshows with UIScrollView, you arrange all images in the scroll view, set up a repeated timer, then -setContentOffset:animated: when the timer fires.

But a more efficient approach is to use 2 image views and swap them using transitions or simply switching places when the timer fires. See iPhone Image slideshow for details.

How to scroll UIScrollVIew programmatically

Try it and set a new position manually.

Objective-c

  float width = CGRectGetWidth(scrollView.frame);
float height = CGRectGetHeight(scrollView.frame);
float newPosition = scrollView.contentOffset.x+width;
CGRect toVisible = CGRectMake(newPosition, 0, width, height);

[scrollView scrollRectToVisible:toVisible animated:YES];

Swift 4

let scrollView = UIScrollView()
let width: CGFloat = scrollView.frame.size.width
let height: CGFloat = scrollView.frame.size.height
let newPosition: CGFloat = scrollView.contentOffset.x + width
let toVisible: CGRect = CGRect(x: newPosition, y: 0, width: width, height: height)

scrollView.scrollRectToVisible(toVisible, animated: true)

Using ScrollView Programmatically in Swift 3

It is easy to use constraints to define the scroll content size - so you don't have to do any manual calculations.

Just remember:

  1. The content elements of your scroll view must have left / top / width / height values. In the case of objects such as labels, they have intrinsic sizes, so you only have to define the left & top.
  2. The content elements of your scroll view also define the bounds of the scrollable area - the contentSize - but they do so with the bottom & right constraints.
  3. Combining those two concepts, you see that you need a "continuous chain" with at least one element defining the top / left / bottom / right extents.

Here is a simple example, that will run directly in a Playground page:

import UIKit
import PlaygroundSupport

class TestViewController : UIViewController {

let labelOne: UILabel = {
let label = UILabel()
label.text = "Scroll Top"
label.backgroundColor = .red
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

let labelTwo: UILabel = {
let label = UILabel()
label.text = "Scroll Bottom"
label.backgroundColor = .green
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
return v
}()


override func viewDidLoad() {
super.viewDidLoad()

// add the scroll view to self.view
self.view.addSubview(scrollView)

// constrain the scroll view to 8-pts on each side
scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 8.0).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor, constant: 8.0).isActive = true
scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -8.0).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -8.0).isActive = true

// add labelOne to the scroll view
scrollView.addSubview(labelOne)

// constrain labelOne to left & top with 16-pts padding
// this also defines the left & top of the scroll content
labelOne.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 16.0).isActive = true
labelOne.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 16.0).isActive = true

// add labelTwo to the scroll view
scrollView.addSubview(labelTwo)

// constrain labelTwo at 400-pts from the left
labelTwo.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 400.0).isActive = true

// constrain labelTwo at 1000-pts from the top
labelTwo.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 1000).isActive = true

// constrain labelTwo to right & bottom with 16-pts padding
labelTwo.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -16.0).isActive = true
labelTwo.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -16.0).isActive = true

}

}

let vc = TestViewController()
vc.view.backgroundColor = .yellow
PlaygroundPage.current.liveView = vc

Edit - since this answer still gets occasional attention, I've updated the code to use more modern syntax, to respect the safe-area, and to use the scroll view's .contentLayoutGuide:

class TestViewController : UIViewController {

let labelOne: UILabel = {
let label = UILabel()
label.text = "Scroll Top"
label.backgroundColor = .yellow
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

let labelTwo: UILabel = {
let label = UILabel()
label.text = "Scroll Bottom"
label.backgroundColor = .green
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()

let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .cyan
return v
}()


override func viewDidLoad() {
super.viewDidLoad()

// add the scroll view to self.view
self.view.addSubview(scrollView)

// add labelOne to the scroll view
scrollView.addSubview(labelOne)

// add labelTwo to the scroll view
scrollView.addSubview(labelTwo)

// always a good idea to respect safe area
let safeG = view.safeAreaLayoutGuide

// we want to constrain subviews to the scroll view's Content Layout Guide
let contentG = scrollView.contentLayoutGuide

NSLayoutConstraint.activate([

// constrain the scroll view to safe area with 8-pts on each side
scrollView.topAnchor.constraint(equalTo: safeG.topAnchor, constant: 8.0),
scrollView.leadingAnchor.constraint(equalTo: safeG.leadingAnchor, constant: 8.0),
scrollView.trailingAnchor.constraint(equalTo: safeG.trailingAnchor, constant: -8.0),
scrollView.bottomAnchor.constraint(equalTo: safeG.bottomAnchor, constant: -8.0),

// constrain labelOne to leading & top of Content Layout Guide with 16-pts padding
// this also defines the left & top of the scroll content
labelOne.topAnchor.constraint(equalTo: contentG.topAnchor, constant: 16.0),
labelOne.leadingAnchor.constraint(equalTo: contentG.leadingAnchor, constant: 16.0),

// constrain labelTwo leading at 400-pts from labelOne trailing
labelTwo.leadingAnchor.constraint(equalTo: labelOne.trailingAnchor, constant: 400.0),

// constrain labelTwo top at 1000-pts from the labelOne bottom
labelTwo.topAnchor.constraint(equalTo: labelOne.bottomAnchor, constant: 1000),

// constrain labelTwo to trailing & bottom of Content Layout Guide with 16-pts padding
// this also defines the right & bottom of the scroll content
labelTwo.trailingAnchor.constraint(equalTo: contentG.trailingAnchor, constant: -16.0),
labelTwo.bottomAnchor.constraint(equalTo: contentG.bottomAnchor, constant: -16.0),

])

}

}


Related Topics



Leave a reply



Submit