Embedding Custom View with controls in NSScrollView - macos

I'm trying to create a scrollable view with multiple controls inside it. For this I'm wrapping a Custom View control inside a NSScrollView and set the size of the custom view to about the same as the scroll view.
However if I place other controls inside the custom view in Interface Builder they don't appear in the custom view when running. Why is that?
If I place a button in a Custom View that is not wrapped in a NSScrollView it works but I want the custom view to be scrollable in case the window height is too small to show all controls.

After dragging in an NSScrollView in Interface Builder, look at the outline view in the xib window. You'll see that you now have a Bordered Scroll View, which contains a ClipView, which then contains a NSView.
a. Make sure your Custom View have been added as a subview to the NSView. If you add them at a higher level, you wont get the behavior you want.
or
b. Another option is to simply change the class of the NSView to your custom view class. Select the View that is inside the BorderedScrollView->ClipView, then click the 3rd tab from left (in the upper right of Xcode window) where you can type in your custom class name in the field labeled "Class".

Related

macOS/ Xcode / Swift 3, how can I have a storyboard scene inside a NSScrollView?

I am new to storyboards and just learning swift. My document based app has a main document view where all the action is (user mouse clicks, keyDown, etc). It's size can vary based on either user menu command or model state changes. It also has subviews that may come and go. This needs to be the document view of an NSScrollview.
This document view needs its own view controller.
Starting with the main storyboard if I add a scroll view to the main view controller view, I can set my custom view to be the document view. But there doesn't seem to be anyway to give it it's own view controller, within the storyboard paradigm.
Previously, (under objective c, if that matters), I was able to create my document view and it's view controller in a XIB, then in code assign this document view to the NSScrollview's document view.
Presumably, I could still do this in code in Xcode 8/Swift 3, but isn't there a way to do it with storyboards?
Added Later: I seem to get close to what I want by replacing the scroll view's document view with a container view. I'm using a centering clip view, and apparently the container view cannot have constraints, or it defeats the centering!
I can then drag a new view controller onto the container view. The new view controller and it's view can be my custom view controller and it's custom view.
This looks like it will work OK, so far, but it seems a bit of a kludge to me. Is this the standard way to embed a custom view controller with its view in an NSScrollView?

Custom NSView embedded in NSSscrollView

Is there a way for a custom NSView to know whether it is embedded in a NSScrollView or not?
I am creating a custom NSView for displaying some content.
When my view is placed in a window or another view, its size is fixed and the content is clipped to available size.
When my view is placed in a NSScrollView its size must be adjusted according to content so it can be scrolled if necessary.
I know I can add a member in my view that specifies the NSScrollView that hosts my view and set this member manually in code, but I was wondering if there is another way?
You didn't check the methods of NSView?
#property(readonly, strong) NSScrollView *enclosingScrollView;
or
var enclosingScrollView: NSScrollView? { get }
The nearest ancestor scroll view that contains the current view.
If the current view is not embedded inside a scroll view, the value of this property is nil. This property does not contain the current view if the current view is itself a scroll view. It always contains an ancestor scroll view.

Make the viewController's view a NSVisualEffectsView

I create a new viewController on storyboard. I want that viewController's view to shown thru the window. So, as far as I understood, I have to transform that view to a NSVisualEffects view.
How do I do that using interface builder?
I already have a lot of objects on that view added using interface builder, so, it will be nice to solve that using interface builder.
thanks
1) You can delete the view in the outline view and then add a visual effects view as the view controller's view.
2) Add a effects view as the subview of the view.
3) Change the class type of the view controller's view in the inspector window.
Options one and two will let you see the effects view in Xcode. I would recommend using option 3.

How to show different views in same window in cocoa?

Is it possible to do navigation within the same window in a mac application ?(Like it is possible in ios apps).I want to show each view in the same window instead of opening different windows on a button click.
e.g When a user clicks a button then the next page should be loaded in the same window.(The next page will have nothing in common with the current page.)
You may use Tab View for easy switching between views on a same window.
UPDATE:
You may also customize your tab view , make it tabless (In the attributes inspector set style to tabless) and use your buttons to switch between views.
You may take help from the following link : http://devcry.heiho.net/2012/01/nstabview-tutorial.html
OR
You may add or remove subviews from your window on button clicks, using
[[yourWindow contentView] addSubview: yourSubview]; // Add subview to window
[yourSubview removeFromSuperview]; //Remove subview
UPDATE:
Steps to swap between views using a tabless tab view.
Drag a NSTabView to your xib.
Set the no. of tabs in attribute inspector to no. of views you want.
Design each view of the tab as per your requirement.
Now in the attribute inspector of tabview, set style to tabless.
Now drag the buttons you want to use for swapping between views. Suppose Button0 and Button1 are for 1st and 2nd view of your tab view.
Create a IBOutlet for your NSTabView in your .h file. Bind it to the referencing outlet of you tabview.
IBOutLet NSTabView* tabview;
Set a IBAction for both your buttons in your .h class file.
In the button action method for button1, use
- (IBAction)button1clicked:(id)sender
{
[tab selectTabViewItemAtIndex:0];
}
Similarly in button2 action method use:
[tab selectTabViewItemAtIndex:1];
In this way you can have any no. of views and you may select any view on button click using
[tab selectTabViewItemAtIndex:(index of the view you want to load)];
In general you want to google for view swapping.
There are tons of examples out there. Some from Apple and lots elsewhere.
Much of it is very similar to iOS.
You need to read the docs a bit too.
Understand NSView and how to load views from nibs, how to create view objects in code, how to add a subview and how to remove a view.
There are many approaches to having different views for different reasons. The right approach is a combination of style, experience and what your app actually needs to do.
Cocoa includes NSBox, NSTabView, and lots of others. Those two can be configured to not display any visual indication that they are containers.
You will also need to understand at least a little about NSWindow to understand its content view (the root container of other views generally)

Replace subview of NSSplitview with custom view

I still have a lot to learn with cocoa so I may have missed something obvious here. I have a custom view I would like to display in an nssplitview which replaces the current subview there.
I have a MessageView.xib file, and a MessageView .h/.m which subclasses NSView. I created a custom view instance for my main window (the one which contains the nssplitview) through Xcode 4's built in gui builder. I created an outlet to this instance of MessageView in my window's controller.
In my controller for the window when I want to swap out the subview for the splitview it runs this
[splitView replaceSubview:[[splitView subviews] objectAtIndex:1] with:viewMessage];
viewMessage is the outlet to the MessageView.
When this code is run the display of that subview changes to be blank. I'm not sure if there is something wrong with my custom view or there is some size issue. Is there something I need to do to fit the view into the split screen view or is my custom view just not displaying correctly? I have had a difficult time finding a tutorial on creating custom subviews with Xcode 4 so I'm not sure if something could be wrong with that. The custom view just has a label and a textfield in it.
Generally, you shouldn't need to replace NSSplitView's subviews with your own. Rather, you add your own custom view(s) as child views of the default subviews on each side of the divider. You can do this in code with addSubview:, but it's probably easier to just use Interface Builder in Xcode. Drag a "Custom View" into the splitview, then in the Identity Inspector, under Custom class, change the class to the name of your custom NSView subclass:
I think (off the top of my head, not tested), if you really do need to replace the default NSSplitView subviews with your own class, you can probably do it in Interface Builder using this same method, but selecting the default subview itself and changing its class in the inspector. This doesn't work for all AppKit classes, but it may work for NSSplitView.

Resources