How to implement ScrollView in cocoa app? - objective-c

I'm trying to add ScrollView to my app. But when I place it to the window and add some objects inside, it doesn't scroll! What should I do to make it work?
Link to image: https://i.stack.imgur.com/ZcLCn.png
-> three buttons inside the ScrollView, while one of them is outside of the window's bounds

You should set the height of the contentSize of the scrollview larger than the height of the scrollview so that the scrollview can scroll vertically.To let the button outside the window be shown,the height of the contentSize should be larger than the maxY of the button

Related

How to addSubview to NSSrollView correctly?

My code:
#IBOutlet weak var scroller: NSScrollView!
var showSettingsButton = NSButton(frame: NSMakeRect(0, 860, 60, 40))
showSettingsButton.title = "Settings"
scroller.addSubview(showSettingsButton)
The button looks as intended by the scrollview keeps static, but when I scroll the ScrollView, the button just looks like this:
I want to put this button always in the down-left corner regardless of scroller's scrolling.
So which view should be the superView of this button?
It should be in your View. Put it underneath the Scroll View - Text View, but make sure it will be siblings with the Scroll View - Text View, and not a child.
If you're going to add it in code, add it like
view.addSubview(showSettingsButton)
For your requirement , you should subclass NSScrollView and override the "tile" method. There you can specify your buttons frame
When you want your Button not to scroll, why do you add it to the scroll view then?
Add it to view, the superview of scrollview. So make it a sibling of the scrollview. Just add the scrolliview first and the button next so that the button overwrites the scrollview and appears on top.
ViewController
-> View
-> ScrollView
-> TextView (and anything that you want to scroll)
-> Button
You may want to do parts of this programmatically because IB or Storyboard Editor respectivey may change the view hierarchy again by making the button a subview of your scroll view.

Scrollview vertical only with fixed width in Autolayout

In swift how can I set the width of the scroll view to be the width of the screen size?
I tried setting right leading and trailing bounds, but my aspectscalefill image keeps stretching the entire frame.
I am trying to force the view to be the width of the screen and allow vertical scrolling only.
If you want to make a scroll view with auto layout try this. No code at all so you will have to drag things out of the library to the right of Xcode.
In your view controller drag and place the scroll view size it to whatever you want but it looks like you want to make it the size of the screen. Pin all edges to the edges of the view controller. Pin trailing, leading, top, and bottom.
Now, instead of placing your items in the scroll view, place another view in the scroll view. With this new view you will place all of your items. You will most likely have to move the view up or down to place them all and resize the view. You can then place whatever constraints you want on your items. When all items are in their place, set the frame of the new view back to x = 0 and y = 0.
You will then place constraints as follows. Select the new view and pin to top, bottom, trailing, and leading and then center in container. This will make a constraint that is vertical with some negative number. In the storyboard outline select this constraint and set it to zero.
You will now be able to scroll vertically. Let me know if you have any questions.
I created a single view application, and added a UIScrollView in the storyboard with four constraints (top, left, right, bottom). And I add the following code in the viewDidLoad(). Everything works just fine. My image is only scrolling vertically, but not horizontally. No additional settings are needed.
#IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Just as an example, I make a size with same with of the view
// and twice the height of the view.
let size = CGSizeMake(
self.view.frame.size.width,
self.view.frame.size.height * 2);
// Load an image and make a image view
let image = UIImage(named: "im.jpg")!
let imageView = UIImageView(image: image)
imageView.frame = CGRect(
origin: CGPoint(x: 0, y: 0),
size: size);
imageView.contentMode = UIViewContentMode.ScaleToFill;
// Add the image view to scroll view
scrollView.addSubview(imageView)
scrollView.contentSize = size;
}
Your problem i caused by the fact that you add your elements to the scrollView from the storyBoard.
In the storyBoard you need:
1) Add the scrollView, if you need to be in the width of the screen then set it's trailing and leading spaces to superView to 0
2) uncheck the "allow horizontal scrolling" in the attribute inspector
In your code
1) set the scrollView's contentSize to what ever size you want it to be.
1.1) in your code you need to set the size of the contentView like so
scroller.contentSize = CGSizeMake(your width, your height);
This is a very important step, the scrollView will not be able to scroll if you don't set the size. Think about the scrollView as the window and the contentView as the view. If the contentView if the same size as the scrollView then the scrollView can't scroll anywhere (all of the contentView fits into the scrollView) in order to create the scrolling you need to make the contentView bigger then the scrollView itself
2) start adding your elements to the scrollView's contentView by calling
[scroller addSubView:<your view>];
this will add your views to the scrollView's contentView and will be

NSScrollView content and scroller insets

What would be the best way to create content and scroller insets on an NSScrollView like one can set on a UIScrollView?
I'd like to be able to add a footer which is not spanned by the vertical scroller like that found at the bottom of Mail.app's sidebar
Have an NSView that contains both your NSScrollView and your footer's view, with the scroll view's frame set to not overlap the footer.

Make subview of a UIScrollView fixed while the other subviews scrollable

I want to make a View with three subviews stacked on top of each other with the middle subview scrollable with the others fixed.
How can I achieve this programmatically? I have tried
to set the contentsize of the root view to the size of the scrollable view but that makes all the views scroll.
-set the contentsize of the middle subview without setting any property for the root view but that makes all the views unscrollable.
Please help. I am new to iOS.
Thanks in advance
You can use the scrollViewDidScroll: delegate callback on the UIScrollView to adjust your view's position. In the callback, get the contentOffset of the scrollview and use that to set your fixed view's position.
For example, if you want your fixed view to always remain 100 px from the top of the scrollview, set its initial frame to (0, 100, width, height), and then in the callback set the frame to (0, contentOffset.y + 100, width, height).
The result is that the subview will appear fixed at a given height.
If your UIScrollView has a superview (i.e. a container view), you can add your 'fixed' view as a subview of the superview instead of the UIScrollView. You'll only have to calculate your frame coordinates once.
You can do it moving sub view from UIScrollView to super view of scrollview like:
Place/set your button over scroll view (not inside scroll view) as shown here in this snapshot. And also set button constraints (position) with respect to super view of your scrollview.
Here is ref. snapshot of hierarchy of position of each view over each-other.

NSScrollView clipping overlaid UI elements

I have a button that sits on top of an NSScrollView, not within. When the scrollview scrolls, the button get's clipped with part of the button going along with the scrolling and the other part staying positioned.
To better describe the issue here's a video of the issue:
http://dl.dropbox.com/u/170068/ScrollTest.mov
The planned goal was to have a button sit in the top right corner of a text view but stay there when the text view scrolls. So if anyone has any thoughts on how to achieve this it would be greatly appreciated.
You should subclass NSScrollView and override "tile" method to position sub-controls of the scroll view.
- (void)tile
{
[super tile];
if (subControl)
{
NSRect subControlFrame = [subControl frame];
// adjust control position here in the scrollview coordinate space
// move controls
[subControl setFrame:subControlFrame];
}
}
I have used this way to implement a custom ScrollView with zoom control and background color selector embedded.
Overlapping views isn't recommended for non-layer-backed views. I think Interface Builder will even warn you about this. The easiest way to work around this would be to make your button layer-backed.