I've subclassed UITextField and added two variables and a convenience function. One variables holds a String key and the other holds a reference to another TextField which is used to create a custom tab order.
All good except I've run into a small problem. Using the storyboard I'm not able to bind the IBOutlet in the controller to the text field elements that implement this subclass even though they are both the same type. I've had to set the IBOutlet variable to be a UITextField type, bind them and then set the IBOutlet back to the subclass.
This all works in Xcode5 using Objective-C so I assume this is an issue with the beta of XCode6 but just wanted confirm I wasn't missing something.
I am also playing with swift.. I can share what I checked when faced some problems, you can check these. Not sure though it is the solution for your problem.
1. Check class defined for subclass and main class
2. Check delegates defined for text fields.
3. Check if prototyping can solve your problem.
Beta 2 Release of XCode 6 has resolved this issue.
Related
I have a UITableView which has static cells, inside one of those cells is a UISegmentedControl. I've hooked up and IBOutlet to the control itself to the containing table view controller class. However, when I break in ViewDidLoad, the outlet isn't even set, it's nil. All other IBOutlets in that class are being set except for the UISegmentedControl.
Is this a bug? Has anyone else experienced this?
Thanks
Omg, this was all to do with localization. It seems after turning on localization none of my storyboard changes were being honored. I had to remove base localization and then re-add the storyboard to the project to fix this.
I hope this helps somebody else who may end up in the same situation.
Good evening all,
I'm slowly working through my first OS X app. I have been having a hard time getting my Swift class to interact with an NSPopUpButton. Just to make sure I was doing it right, I created a new project and successfully erased all entries and entered text into the NSPopUpButton via AppDelegate. However, as soon as I try to move the same functionality to my own class, I can't even get the IBOutlet connection across to the new class.
Is a particular subclass type required of a new class to work properly with interface builder?
Here is a screenshot of the class I have created, as well as AppDelegate where I am trying to call the function belonging to this class.
Finally, here is the IB element in question, should I be able to select my own class under the 'Custom Class' inspector?
I am an iOS developer, but I would imagine the same principles would apply to your situation.
A ViewController class and an interface created in interface builder are two seperate things. While it may appear that they are connected via an iboutlet, they are actually independent and one can be instantiated without the other.
Currently, you are only creating an instance of your ViewController class in your App Delegate - and that's all. The system has no idea that your xib even exists! The outlets will only be connected once your app connects your xib to your ViewController class.
How do we do this? It's actually quite simple. Instead of instantiating our view controller like this:
let viewcontroller = ViewController()
We would connect our view controller to our xib in the instantiation:
let viewcontroller = ViewController(nibName: "MainWindow", bundle: NSBundle().mainBundle)
The nibName is telling the system the file name of your xib, and the NSBundle().mainBundle is telling the system where to look for the xib.
This will all only work if your xib has been assigned a custom class, like you mentioned. In your xib in interface builder, select the entire view controller. Then, in the custom class inspector type in the name of your ViewController class (in your case: ViewController - it should autocomplete). This will make sure your outlets are connected.
And you should be set up!! Let me know if you have any more problems come up.
Good luck!
EDIT:
This replaces the first part of my answer, however the part about hooking things up in Storyboard remains true. Upon reconsidering, I've believe I've realized that we are only creating the view controller, and not adding it to our view. Despite this, I believe we can take a short cut solution by adding one method to your view controller subclass (the one we set in the Storyboard). Start typing in viewDidLoad, and it should autocomplete. Type in super.viewDidLoad() at the beginning of the method. After that, type self.listUpdate(). This should work if the classes are hooked up correctly in Storyboard. This means you can delete the variables you created in the App Delegate.
Reference: You might also find Apple's documentation on creating a view controller handy (it's in Objective C online, but can be easily converted to Swift - it's the concept that counts): NSViewController Class Reference
I'm going through a book and one of the challenges are setting the autoresizingMask programmatically.
The only problem is I can't check if my code is correct because it seems like the setAutoresizingMask: gets overridden by what I set in the IB.
So actually two questions:
1) Is there any way to turn off autoresizingMask in IB? I removed all settings in IB and instead of the code taking over, it seems like Xcode interprets it as autoresizingMask set to default.
2) Are my codes correct? So here's what I did.
In the view controller file...
#property (nonatomic) IBOutlet UISlider *slider;
And then I made connection in IB from File Owner to Horizontal Slider and referred to "slider."
In the app delegate file I have the viewController set as rootViewController.
[viewController.slider setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin];
Still when I simulate and change orientation, the width of the slider doesn't change.
Thanks guys!
** Actually it seems like my codes are wrong somehow... NSLogging autoresizingMask right after setting the code returns 0... Can't seem to figure out what's wrong..
You are using an obsolete tutorial. we use NSAutolayoutConstraints now (adoption guide). you would be better served figuring out how to use that.
If you really do want to use setAutoresizingMask: then turn off autolayout in your nib first, or set translatesAutoresizingMaskIntoConstraints to NO on your views.
So I'm just trying to create a very simple app for demo purposes here:
Created a Single View Application, using storyboards
Added a UIView to the storyboard
Added the following code to my controller's header file:
#property (weak, nonatomic) IBOutlet UIView *myView;
Now, I understand that I can link the UIView to the controller by:
arranging my code such that the header file is next to the storyboard
holding down Ctrl key and dragging it to the property in the header file
My question is this: can I do this without Ctrl-drag? And if so, how?
More specifically - it's annoying to have to put both my header file and storyboard on screen at the same time, and it seems there should be a way to make this connection without doing so.
I also understand that I can manually place the view by creating it inside my controller's viewDidLoad function, but I'd really like to use the interface builder to simplify / visualize things.
Edit: Is the answer to my question affected whether I use storyboards or xib/nib files? (I'd switch to use the one where it works)
you should be able to right click the element, and drag the "referencing outlet" item to the view's "File's Owner" in interface builder. There, it will give you a list of all available IBOutlets (matching the object's type).
In addition to Dima's answer, you can just as well use the Connection inspector in the Utilities pane
I just created a new Xcode project. In the AppControl class Header file I have the following objects defined (and some other ones, too):
IBOutlet NSImageView *inputImageView;
IBOutlet NSImageView *outputImageView;
IBOutlet NSTextField *myNoiseLevel;
IBOutlet CGFloat *mySharpness;
After putting the basic code into the .h and .m files, I then went into Interface Builder and created my UI. I was able to bind the two NSImageView controls in IB to the corresponding NSImageView objects listed above. And I was able to bind a couple of other objects/controls, also. But I am NOT able to bind the last two items listed (myNoiseLevel and mySharpness) to the NSSlider controls I have on the application main window. I'm not sure why. I know this kind of thing is probably hard to diagnose, because it is not "strictly code related," but if there is something "tricky" about binding sliders please let me know what the main "suspects" are that I should check.
This is my first attempt to use a slider control through IB. I have a book (Cocoa programming for Mac OS X, 3rd ed., by A. Hillegass) that I am using to learn about the basic way to do this stuff. And he has a slider example in there. But his slider example is "continuous" and it uses key path binding. I think this is overkill for what I want/need to do -- I just want to pull the value from the slider when another button is pushed (no need for "continuous" update). So I am trying to directly bind the "outlets" listed when I right-click on my App Control object (one for each of those items shown above), to the slider controls on my window. But when I cntl-drag from the AppControl outlet up to the corresponding slider, the slider will not "accept" the arrow I'm dragging.
Does this make sense? Any idea what I'm doing wrong and/or what I need to do to make the binding work? I have tried saving / building / closing & reopening IB and Xcode -- all to make sure IB has the latest version of everything. Still no luck, though.
One last thing ... What I really need are CGFloat numbers, from the slider. Can I simply declare the Outlet as CGFloat type ... or do I need to define it as NSTextField (or something else), and then convert it to Float in my program? You can see in the IBOutlets I pasted above, that I was trying different data types for the outlets (trying to see if my defining them as CGFloat was somehow preventing the bindings).
Make the outlet an NSSlider*. You should then be able to connect to it. When you need the value (eg, in response to the button press you mention) call [yourSliderOutletName doubleValue].
More generally: an IBOutlet is an ivar that can be filled in with a pointer to the actual object awoken from a NIB file. As such, it needs to be of an appropriate type to hold that pointer -- the object's actual class, or one of its superclasses or protocols, or (least informatively) id. You can't just arbitrarily connect an object to any old variable, like your CGFloat. There's no implicit conversion -- how is the system supposed to know what you want?