Create an outlet in storyboard to an inherited property - swift

I'd like to create a basic view controller class BasicController with two subclasses SubclassController and AnotherSUbClassController. BasicController controls view that have a button inside them, so there should be a
weak var buttonThing: UIButton?
property in it. In the actual implementation I want to use the subclasses in various parts of the interface: I want to draw them in storyboard, put buttons in that drawings, and connect the buttons to the inherited buttonThing property via an outlet. But wait, the buttonThing property was announced in the superclass and doesn't even appear in the code of the subclasses. So how do I connect the buttons to that outlet?

You can ctrl-drag the UIButton from your storyboard to your BasicController for each subclass you have laid out in your storyboard. You can then use the buttonThing in each subclass as usual.
Remember to link your subviewcontrollers to their respective viewcontrollers in the storyboard.

Related

Swift difference between IBOutlet/IBAction and programatically constructing a view?

im kinda new to swift, and I don't understand what is the difference between the Interface Builder Outlet/Actions and programatically constructing a view. If I have IBOutlet why I don't need to still add them as subviews of the self.view and why do I don't need to instantiate them? As well, to not create two questions, why in the case of a creating a custom UiView I have to load the xib file with Bundle.loadNib?
Thanks,
You cannot initialize a property that is not nil by nature at instantiation time.
Interface Builder outlet, which always initializes after its owner. In this specific case — assuming it's properly configured in Interface Builder — you've guaranteed that the outlet is non-nil before you use it. That is why we can use as below:
#IBOutlet private var searchBar: UISearchBar!
Also, you already added subviews as well.
SearchViewController - ContentView - searchBar
That means ContentView or self.view is already superview of searchBar so you don`t need to add as a subview.
IBAction, IBOutlet, is responsible for connecting with objects on the Storyboard.
IBOutlet is a variable for accessing values, and IBAction can define an action on the event.
With Storyboard, prototypes can be created quickly and are easy to implement. However, if you work with multiple people, it can cause conflicts, so be careful.

Connecting an NSTextField object to an IBOutlet in AppDelegate.swift

Recently, I've been trying to learn Swift, so if this seems to be a relatively simple question do forgive me.
For some reason, control-clicking a NSTextField object in a tab view controller and dragging doesn't give me the option to "insert outlet or action" but rather, "connect binding" when I scroll over a compatible object (in this case it was the superclass declaration).
Why is it that I am not able to insert an outlet or an action, but am able to connect a binding?
side question: what is a binding?
The outlet can only be a property of your nib file / storyboard scene's owner. Which is your view controller in most cases.
This is what happen what your view controller instantiated from storyboard:
Instantiates views using the information in your storyboard file.
Connects all outlets and actions.
Assigns the root view to the view controller’s view property.
Calls the view controller’s awakeFromNib method.
When this method is called, the view controller’s trait collection is empty and views may not be in their final positions.
Calls the view controller’s viewDidLoad method.
Use this method to add or remove views, modify layout constraints, and load data for your views.
Short Version:
UIKit instantiate your view controller for you, and add all subview as you required in storyboard. And connect(binding) subViews to their outlet (if you created one).
How to solve your problem
When you opened your assistant editor. Choose the automatic viewController, if that is not something your create, you should create a subclass of viewController you need (in this case, UITabViewController) and change your scene's class to that.
you need to have same view controller in storyboard when you control-drag a NSTextField to controller
Edit: As Leo mentioned in the comment You can't connect/create any IBOutlet in the AppDelegate file if you are using storyboard, you have to create in it's particular controller where you have placed NSTextField
Storyboard
As shown in the image if you are in storyboard click the top bar on the controller from there you will get the options shown in the image, select Automatic
If you have selected proper view controller in the storyboard it should show same viewcontroller file in the Automatic(viewController.swift) by selecting that file you should able to control-drag IBOutlet
XIB
In the Xib when you select Xib and click 'Asssistant Editor' it will generally take to the proper view controller if not select Automatic for it also as shown in the Storyboard image are that you will able to connect you IBOultet
Binding
When you control-drag IBOutlet it create a connection between your control and property of view controller
From Apple Doc
The Cocoa bindings feature enables you to establish a live connection between an item of data and its presentation in a view. Any change made to the data’s value, either in the view or in the object that stores the data, automatically propagates across the connection.
You can find more information regarding it in Apple Doc

Adding outlets to UIButton

For quickly mocking up UI, I'd like to be able to drag buttons onto a view in interface builder, then drag a connection from that button to the view that should appear when you click it.
A subclass of UIButton is a little inconvenient to use in IB, so I'd prefer to add the behavior to UIButton itself. Unfortunately, it seems like outlets created in a category aren't visible in IB:
#interface UIButton (myextensions) {
IBOutlet UIView *outletDestination;
}
#end
Can extra outlets be added this way?
Can extra outlets be added this way?
Nope. You can't add instance variables by declaring them in a category.
You can, however, add properties, and you can put IBOutlet on properties, so you can add outlets that way. With the modern runtime (the only one available on the iPhone), properties can add instance variables.
I don't think you can do this if you intend to make a custom accessor for the property (you must use #synthesize), but it doesn't sound like this matters for your case: You're just mocking up UI, so you're not going to write custom accessors.
Alternatively, you can create outlets in IB itself on the Classes tab of the Library panel. Select a class there, then the Outlets tab in the pane below, then add an outlet to the list.
You'll need to have a nib open for that other solution, or no classes will show up. That's because it's context-sensitive: A Mac nib will have AppKit classes (like NSButton), whereas an iPhone nib will have UIKit classes.

UIView or UIViewController for custom View

What is the best way to create a custom UIView that I can consume in Interface Builder?
Create a custom UIView in Interface Builder and inherit from UIView in a code file, then somehow use it in another UIView ala like a control. (How do I do this?)
Create a custom UIView in Interface Builder and have a custom UIViewController wire it up. In my main ViewController, place the new view.
Basically, I am trying to create a reusable display view and would like a quick way to change it across all my instances with minimal effort. I already have laid out my XIB in Interface Builder.
The best is the 1st way. And don't forget to place IBOutlet keyword before class member, that you want to see in Interface Builder.
#interface MyViewController : UIViewController {
IBOutlet UILabel *m_MyLabel;
}
....
You'll want to do (1). Presumably you've got an existing IB file in which you'd like to place the custom UIView subclass? In that case, go to that file, drag out a UIView, and then in the "Application Identity" tab of the inspector (4th tab) set the Class to your custom class (as defined in code).

How do you connect the "delegate" outlet of a UITextView to a class that implements UITextViewDelegate protocol?

How do you connect the "delegate" outlet of a UITextView to a class that implements UITextViewDelegate protocol?
I can't seem to find an example in the docs
The weird thing is the UITextView's "delegate" outlet has that drag 'n drop interface thingy, like you can wire it up to another widget but of course, I don't want to wire it up to a widget, I want to wire it up to an existing class.
This is a pretty old question, but I had trouble with it as well and figured I'd share an up-to-date Xcode 5 solution.
You should be able to drag the delegate to the yellow circle with the white square inside of it that's down in that black bar below the view controller on your storyboard. This is not at all obvious, so I've provided a screenshot
To wire up a delegate in Interface Builder:
(1) Drag an appropriate controller into the nibs main window and set the class of the controller to the class of your delegate. For example, if you have an NSObject subclass called "MyDelegateClass", drag an Object controller over and set it's class to "MyDelegateClass".
(2) In the connections inspector for the UITextView, control-click on delegate and connect that to the controller created in step (1).
That's it.
If you mean "how do I make an object that is created with code the delegate for my text view", just set the delegate property (this is what dragging in Interface Builder will do for you):
textView.delegate = yourDelegateObject;