In the new xcode 5 how do in interface builder you use to have a drop down menu there to connect your storyboard viewcontrollers to your classes how is this done now?
Unless I'm misunderstanding what you're asking, it's still there. Here are the steps to assign a custom view controller class to your view controller:
Choose your view controller in the list of scenes on the left side.
Choose the Identify Inspector on the right side.
Choose the custom view controller class from the Class list.
1、manual creating a Cocoa Class to the project
2、open the story board, draw a view controller from tool box to the storyborad
3、click the controller you draw into the storyboard, and specify the 'Customer Class' to the class you create in step 1
4、if you use XIB, nibName could be the controller name, else if you use StoryBoard, you need set a storyboard id for your controller in your storyboard panel, and you can use the id and the storyboard in your superController when you want to new a controller
// XIB
var viewController = UIViewController(nibName: "ViewController", bundle: nil)
// StoryBoard
var viewController = storyboard.instantiateViewController(withIdentifier: "The-Storyboard-ID-You-Set") as! ViewController
Related
I'm learning Cocoa, and
I'm trying to understand the logic (behind the scenes) of the IB.
1) On a new xcode project (cocoa/obj-c) the storyboard starts with a
predefined View Controller (VC) which is "associated" with files ViewController.{h,m}.
2) I add a Push Button with name "Switch" to the the View.
3) I add a Second View Controller (VC2)
4) I connect (click-drag) "Switch" --> VC2 which create a "segue" VC-->VC2.
So far so good. If I click "Switch" on VC, the window of VC2 appears.
5) Now I want to add a label with name "Foo" to VC2 and connect
"Foo" to some IBOutlet in my code.
I'm guessing that I need to create a new class "ViewController2"
which inherits from NSViewController and make the connection
VC2 <--> ViewController2
in such a way that I can click-drag from "Foo" to the interface
of ViewController2 in ViewController2.h in order to create
an IBOutlet.
Question (finally): how do I make the connection
VC2 <--> ViewController2?
More generally: is there a good reference for understanding
the logic behind IB?
You are correct that you have to create a NSViewController subclass for the second view controller. The next step to take is to set the second view controller's class to your subclass. Set the view controller's class using the identity inspector.
After setting the second view controller's class to your subclass, you should be able to create outlets and make connections from user interface elements in the second view controller to that view controller's source code file.
I have this OSX storyboard-based application that starts with a NSSplitViewController like this:
This splitViewController has two viewControllers: master and detail.
Inside the window I have a NSToolbar. I dragged a NSProgressIndicator to that toolbar and Xcode embedded it inside a NSToolbarItem.
Now I need to create an outlet (not an action as explained on other stackoverflow questions) from the NSProgressIndicator to some class. First question is which one?
Xcode will not let I create an outlet. I have tried these options:
dragged from the ToolbarItem to masterController class file, detailController class file and to NSSplitViewController class.
dragged from the ToolbarItem to the delegate class.
dragged from the NSProgressIndicator to masterController class file, detailController class file and to NSSplitViewController class.
dragged from the NSProgressIndicator to the delegate class.
dragged from both the NSToolbarItem and from the NSProgressIndicator to the Window Controller First Responder.
In all cases dragging does not make a window appear to allow me to create the outlet.
For heavens sake, how do I create an outlet like that? To which class I drag it and how do I do that?
I'll assume your setup is more like this image:
Your Window scene is backed, by default, by an NSWindowController, to which you cannot add new outlets. You need to create a subclass of that, associate it with your Window and then you should be able to create outlets in that.
File > New File > Cocoa Class
Specify a name like "SpaceDogsWindowController", as a subclass of NSWindowController.
Then use select the window controller icon (blue circle) and select the Identity Inspector in Xcode. (CMD+ALT+3). Specify the name of your new class in the "Class" field.
Then try to hookup an outlet:
1) Show the Assistant Editor
2) Use the Jump Bar to ensure your custom class is visible (It's at the top of the assistant editor pane, it should say Automatic and you can tap that to then select your new class; If it says 'Manual', change it to Automatic).
3) If your are control-dragging and it's still not offering to make a connection, try dragging from the document outline (also shown in the screen shot).
You could then edit that progress indicator from other view controllers, which are descendants of that window's view hierarchy, using code like this:
if let windowController = self.view.window?.windowController() as? CustomWindowController {
windowController.progressIndicator.doubleValue = 0.4
}
or, in Objective-C, something like this:
CustomWindowController *myWindowControllerSubclass = self.view.window.windowController;
windowController.progressIndicator.doubleValue = 0.4;
Hope that helps.
I'm looking at WWDC 2014 video, "212: Storyboards and controllers on OS X". In this video they claim that Pages UI does/could be arranged using Storyboards on OS X (see below).
However, in Pages UI the inspector view is very long and is embedded in a scroll view (you can verify this my two-finger scrolling in Page.app inspector view), also some inspector items are themselves contained in (some type of custom) disclosure view. It doesn't seem to be possible to embed a storyboard view controller in scroll view because there is no corresponding to "scroll view controller" class. Is that right?
How can a storyboard view controller's view be embedded in a scroll view on a storyboard?
I have tried direct embedding at run time, however, this is very hackish and does't work reliably (problems with auto-layout). This route still might be possible, but I wanted to get advice before going too far. For real UI it might be the case of falling back to XIBs.
- (void)viewDidLoad {
[super viewDidLoad];
// Swap the view controllers' view for a scroll view
NSScrollView *scrollView = [[NSScrollView alloc] initWithFrame:self.view.frame];
scrollView.documentView = self.view;
scrollView.drawsBackground = NO;
self.view = scrollView;
}
I think this answer is not really solving your problem but maybe helps understanding what is up with storyboards and scrollviews. I think Apple still has to fix some storyboard issues. I tried to use a collection view with storyboards, but it's impossible to connect the collectionViewItem in interface builder (which is happening automatically with xibs).
Here is an example with collection views:
Drag and Drop the collection view to a viewController. You will see a collection view and a collectionViewItem appearing. But the collection view item is NOT connected to the collection view. If you try this using IB, nothing happens.
In Identity inspector of IB assign a Soryboard ID. It's a random name which will be used in the code later. Here I am using "MyCollectionView"
If using swift, select your projects name in Module. The code is mostly the same for objC
Connect the collection view to the ViewController, containing the collection view
Do some coding to connect the Collection View item
class IVMyCollectionViewController: NSViewController, NSCollectionViewDelegate {
// manual connections to collection view (which is not working in IB)
#IBOutlet weak var collectionView: NSCollectionView!
class var sharedInstance : IVMyCollectionViewController {
struct Static {
static var instance:IVMyCollectionViewController? = nil
}
if Static.instance != nil {
return Static.instance!
} else {
let bundle = NSBundle.mainBundle()
let infoDict = bundle.infoDictionary!
let sbName = infoDict["NSMainStoryboardFile"] as String
let storyboard = NSStoryboard(name:sbName, bundle:bundle)!
let vcName = "MyCollectionView"
let sbInstance = storyboard.instantiateControllerWithIdentifier(vcName) as IVMyCollectionViewController
Static.instance = sbInstance
return sbInstance
}
}
// implement your controller
}
That means that some UI elements are not properly implemented yet. I would send a bug report to apple. There is still lots of things missing in interface builder.
Right now I would use a mixture of storyboard and xibs to abuse the storyboard in a way like above, by instantiating the connection in the constructor of the controller. You can use the storyboardID to launch views and other views or load from xibs. You can place viewControllers inside a storyboard without connections (segues) to create a pool of views that can be used like xibs. (A viewController is more or less the same like a xib)
// objC
DetailViewController* controller = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:nil];
or instantiate using the storyboardID like above.
Try to create a scroll view in storyboard. Create the views which you like to be shown in viewControllers for each view. Your scrollviews view controller should have a connection to the scroll view itself. In the following example the scroll view's outlet is named "self.contentView":
// instantiate a view controller for your scrolling view
self.scrollingViewController = [[ScrollingViewController alloc] initWithNibName:#"ScrollingView" bundle:nil];
// or do the same with storyboards by instantiating view controllers by ID
self.scrollingViewController = [myStoryboard instantiateControllerWithIdentifier:#"MyScrollingViewID"];
// Then set the view from the controller as content view
[self.contentView setDocumentView:self.scrollingViewController.view];
[self.contentView.contentView scrollPoint:NSMakePoint(0., self.scrollingViewController.view.frame.size.height)];
It's exactly like mixing up objective C and swift code. Apple seems to have entered a transition path which was not walked to the end.
In general you should think of View- or WindowControllers in storyboards is the same like a complete xib file. If you would like to use more views, use container views in storyboards. The FilesOwner in xibs is the viewController in storyboards. Container views offer you the ability to create a couple of views attached to a view controller. The segue mechanism is available for containers. I think the scroll view mechanism of OS X is not elegant. I struggled a lot with it, too.
Good luck!
Create the view that will be the document view of the scroll view.
Select that view
Go to Editor > Embed In > Scroll View
Based on this page of Scroll View Programming Guide for Mac.
I created an empty xib, I dragged a UITableViewController, set Custom class to my class that extends from UITableViewController at both the UITableViewController and File's Owner.
When I run, it says:
'A view can only be associated with at most one view controller at a time! View ; layer = ; contentOffset: {0, 0}> is associated with . Clear this association before associating this view with .'
At connections inspector I see that the UITableViewController element has:
tableView - Table View
view - Table View (greyed)
dataSource - Table View
delegate - Table View
First Responder has nothing.
File's Owner has:
tableView is not attached to anything
view - Table View
If I remove the view connection at File's Owner, it claims that the view outlet is not set.
It is difficult to imagine what happens based on the information provided. However:
The error message says that you have a UIView, and you try at runtime to connect this UIView to two UIViewControllers, which is not possible.
If you just subclass a UITableViewController, without adding properties or implementing methods, then setup a UITableViewController in an empty storyboard, and set the class of this UITableViewController to your subclass, you have only a single UITableViewController, and you will not get this error.
So somewhere in your project you must instantiate a second UITableViewController programmatically, and set its UIView property (which is a UITableView) to the UIView of the other UITableViewController.
You should ensure that you have only a single UITableViewController, namely your custom subclass.
I guess the correct answer is DON'T drag UITableViewController to the interface builder. Have 2 IBOutlets connected, one for the view, one for the table. DO drag a UITableView instead.
Hope this helps other people.
I am using storyboards, xcode 4.6.1. I have created an app, but now I want to go back and add a new view controller to the beginning. How do I assign this view controller to be the first one to load up at run-time?
Choose your viewcontroller in storyboard , click show the attributes inspector
and choose initial scene: is initial view controller
Initial View Controller
Initial View controller allows you to initiate storyboard without Storyboard ID
let storyboard = UIStoryboard(name: String(describing: SomeViewController.self), bundle: nil)
let initialViewController = storyboard.instantiateInitialViewController()
Xcode 10.3
Storyboard -> View Controller
Show Inspectors -> Show the Attributes inspector -> Is Initial View Controller
It will update the Initial view controller in the same .storyboard.