Apply an affine transformation to view in Interface Builder - iphone

Is it possible to apply an affine transformation to a view directly in Interface Builder? I know I can attach an outlet and assign it to the transform in code, but I'd like the convenience of visually tweaking the transform in Interface Builder.

Nope. Sorry.
There are several properties that would be nice to set in IB. Occasionally Apple adds them, and then IB warns you that it's "only supported in iPhone OS 3.0 and above" or similar (I think this is the case for contentEdgeInsets on some class or other).
There's a very small chance that you can edit the XML, guess the right property name, and set it to the right string (probably whatever NSStringFromCGAffineTransform returns), but I think if it was possible, Apple would've included it.
There's a slightly larger chance that you can edit the xib, add a custom property, and use a category to override -[UIView initWithCoder:] and load your custom property. You can also write an InterfaceBuilder plugin for a custom view class which supports setting the transform in IB...

Related

Re-using complex custom UI elements - Xcode Storyboard

In Xcode on the StoryBoard I built a complex UI element consisting of many sub-views.
I encapsulated it all into a UIView subclass but each element has to be built out on the storyboard wherever it is used.
Is there a way to build it in such a way that all a developer would need to do to use it is to add a UIView of the appropriate sub-class and not need to layout all of the subviews? Similar to how we do not need to interact with the underlying structure of buttons or labels.
This is possible, but it requires a bit of a workaround. It basically requires you to create a UIView subclass, which loads all it's subviews from a separate nib file
This question has the answers for you.

Is there an easy way to convert the constraints that are already defined in storyboard into Swift code?

I have designed a ViewController in my Storyboard and I have adjusted all of its constraints respectively.
Now, I would like to animate most of these constraints.
So :
I should define them again using Swift codes
and write some codes to do the animations.
But it is very annoying to define the constraints again in Swift code while I already have them in Storyboard.
So, I was hoping someone could introduce me an easy way to achieve this automatically.
No, there are no built-in ways to render the IB constraints into Swift code. You could iterate through them and grab all their properties and do something like that, but that will get messy. There are too many different ways to create constraints programmatically, and even if some automated tool existed, I bet the code wouldn’t be very elegant. (As a general rule, tools that generate code programmatically don’t result in very good code.)
I wonder about the whole concept. We often animate constraints generated by IB without going through all of this. The typical approach is to give these IB constraints #IBOutlet references and then you can programmatically change their constant values and then put the call to layoutIfNeeded in the animation closure. Or, if you must, you can deactivate them (again, using the outlets) and then do whatever animation you want and, if appropriate, re-activate those constraints later, if needed.
But we can’t advise on to how to best achieve your animation in an IB view with constraints without more details about the nature of the animation.
But this is an example of how you can animate change the position of a view that has constraints defined in IB: https://stackoverflow.com/a/28329399/1271826

Create custom action in a class for use in Interface Builder

I want to create a custom action connection in a class, which should be visible in Interface Builder. For example - I add action / target properties to NSView class just like this:
weak open var object: AnyObject?
open var something: Selector?
The action is something and the target is object.
Now I want in Interface Builder to have 'Send Action' link / connection available for something and to be able to make connection to a #IBAction method to some class (for example the controller of the view), just like it can be done for a simple NSButton. Maybe this is not possible, or maybe I must add some keywords in front of the custom action / target pair, the same way we need to make a property #IBInspectable to appear in Attributes Inspector.
Any help is welcome ;-)
I don't think you can do that. You can add #IBInspectable properties to custom NSView subclasses, but there is no selector or action data type for properties. The only allowed types are Boolean, Number, String, Localized String, Point, Size, Rect, Range, Color, Image, Nil.
Interface Builder has hard-wired support for handling the target-action properties of controls.
(BTW you should probably add the Mac OS tag to your quesiton. Most Apple traffic on this board is iOS-related.
EDIT:
As somebody said in a comment, if you're creating an object that has a target/action, it should probably be an NSControl, not an NSView. Controls are the object family that handle target-actions, and there IS a mechanism in Interface Builder for adding target/actions to controls.
In iOS, there is one somewhat cheesy option -- you could have an outlet to a UIBarButtonItem, and someone could then drop a standalone UIBarButtonItem in their xib or storyboard. The UIBarButtonItem can then have the target/action, and your class could then pull the target/action from there in awakeFromNib and assign the values to your own class. That approach may be replicable in MacOS using NSToolbarItem, but I have not tried. It's a kludgy option really, as it requires extra xib objects and may not be too obvious what is going on, but it can work. Basically, the UIBarButtonItem / NSToolbarItem would only be acting as a container for the target/action values.
If you can't subclass NSControl, it would seem the preferred option is to have a delegate, probably. That is usually fine, unless one controller needs to be the delegate for multiple instances of your class, in which case the delegate methods get more tedious. Another option is to have your class have a block property, which is performed upon the action, but blocks must be assigned in code and not set up in Interface Builder.

How do I add functionality to a UI made in storyboard?

I have made a pretty little UI on storyboard but I'm quite new to XCode and Objective C (coming over from Java) and I'm having some trouble adding functionality. I know that I should make a subclass of UITableViewController (storeTableViewController) and set the class of the storyboard controller to that. The problem is that when I do that all my hard work in the storyboard is erased, and I can see where the code is conflicting with the showing of my UI (for instance, the tableView:numberOfRowsInSection returns 0 always), and I think that with enough time and patience I could program the UI, but is there any way that I can use all this work that I've done on the storyboard and still be able to add functionality? I want to set a text box at the top to be the first responder as well as be able to change an image and labels on command programmatically.
You should probably use IBOutlets. Connect the StoryBoard UI Object to IBOutlets and you can modify the properties of the UI objects from the code
You can declare IBOutlet link this
IBOutlet type variableName
Check this tutorial video which will help you a lot.
Video Link
I use the storyboard as a canvas. I plug in the outlets that I want and all the little details and then I go around and built the classes. That being said, you need to declare a urtext field outlet (depending to what you want it to do) then add the delegates necessary and allow it to perform on selector. Then you can declare the function. Linking it in storyboard is easy by control and drag.as far the image you can use an uiimage and declare its function and how it changes depending to what the changes are the code varies. My suggestion is to take screen shot of your storyboard and post it with your question so I/ we can help you with the code. But as far as your question goes I hope this answer satisfies you. Happy coding.:)

Custom iPhone control using UIViewController subclass

I wanted a control like the UISlider, but with two thumbs instead of one so you could specify a range instead of just one value. I read up on other people looking for the same thing and suggestions about making new controls were over my head.
So I decided to setup what I wanted in a nib and then created a view controller to handle its behavior. It actually works really well this way accept for 2 things.
1) To load my 'custom control' into another nib I need to do it through code like this...
MaxMinSliderViewController *feeMaxMinSlider =
[[MaxMinSliderViewController alloc] init];
[self.view addSubview:feeMaxMinSlider.view];
feeMaxMinSlider.view.frame = CGRectMake(20, 20, 280, 54);
...instead of dragging and dropping into other nibs like normal IB controls. Is there an easy way to be able to do this?
2) In all my reading about doing this, its seems as though I was supposed to (to do it the right way) subclass UIView instead of UIViewController. I couldn't setup the UIView correctly and get it working though.
Thoughts?
instead of dragging and dropping into
other nibs like normal IB controls. Is
there an easy way to be able to do
this?
Nope! There's only an incredibly hard way!
Assuming you manage to convert your class into a custom UIView instead of a UIViewController you can do part of this quite easily within Interface Builder (depending upon what kind of init method your custom control has).
Within Interface Builder drag and drop a plain old UIView from the Library Window onto your view and position/size it as required.
Then with the UIView selected, switch to the Identity tab of the Inspector Window (the tab with a little (i) icon on it) and change it from UIView to the name of your custom class. This causes an instance of your custom class to be instantiated when the NIB is loaded, instead of an empty UIView.
You can then hook up the view to an IBOutlet etc as normal.
The advantage of this approach is the ability to position and size your control visually etc. It does however only appear as a rectangle, and you don't get the ability to graphically configure the additional properties of your control as you would with a UIButton or similiar control which Interface Builder has additional support for.
I find this technique great, as I'm not that much of a visual thinker and find it hard to picture in my mind how things will look when I read a section of code containing lots of frame = CGRectMake(20, 20, 280, 54) etc. Being able to do it visually with a mouse is much better for me.
There is an Interface Builder Plug-in Programming guide, but it only mentions Mac OS X, not the iPhone.
Also, as of XCode 3.2.1, there is only a new project template for creating a Mac OS X IB Plug-in; there is no such project template for iPhone (Cocoa Touch). So my guess is this is not applicable for the iPhone.