Swift #IBActions in ViewController Extension - swift

I’ve noticed in Swift/Xcode 11 that you can’t ctrl-drag an IB object into a ViewController extension to create an IBAction, but you can cut/paste it into the ext. after ctrl-dragging to create the IBAction in the ViewController class & it works. Anything wrong w/moving an IBAction to a ViewController extension using copy and paste? And why is the Ctrl drag not working for the VC extension? I was putting UITextView actions in an ext w/other TextView funcs ‬when I noticed this but don’t fully understand why the ctrl-drag won’t work but cut/paste appears to show no prob. Thx for considering the Q.

Unless someone works for Apple I'm not sure we'll get an actual answer here. I can guess and give you an alternative that worked for me though.
From an Xcode feature implementation standpoint, the code that supports these actions probably varies..
From what I've seen control drag works when the class of the VC on the storyboard directly matches the class of the object you're dragging into.
I've never tried dragging into extensions but I can see how that might be complicated given that stored properties are not allowed on extensions which adds complications given you can drag outlets too.
However, I've also done IBAction/IBOutlet's on parent classes and I was able to get that to work when I started dragging FROM the an existing IBAction func (there's a circle to the left of it in the code) TO the storyboard of the child class.
In short, I'm assuming there's a lot of assumptions and code being done to allow you to drag from storyboard onto code, and I'm pretty sure limitations are due to the complications in handling the corner cases. Apple will often opt towards not allowing behavior at all if the possibility for a broken corner case exists. Some of the other ways of creating these connections (like a copy and paste) are prob simpler.

Related

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.:)

Design Pattern for Keyboard Pushing Up Blocked TextView

I do understand how to go about making the UIKeyboard push up the UIView if the active UITextView is blocked by the UIKeyboard as per this question: How to make a UITextField move up when keyboard is present?.
What I'm wondering is, from a design perspective, how do you go about implementing the keyboardDidShow and keyboardDidHide methods so that all of the views in your app, whether they be a UIView, UITableView, or UIScrollView all have this functionality and so you need to implement these methods only once?
The only way I could think of would be to have the view property of the UIViewController always set to a UIView, and if you have a UIViewController that needs a UIScrollView or UITableView, just attach it as a subview to this. Then if the UITextView is being blocked, just move the parent UIView up so it will move all of the views that are attached to it.
Does this sound like a good plan, or is it even worth it? Anyone else have any other ideas?
This is a little old, but it's a great article about using firstResponder methods to tell views to slide up. I, personally, like to put my UITextField in a parent container and move it all up. However, I do NOT suggest putting everything in there and moving it all up, because the UITextField "feels" better just above the keyboard. But I do like the background or certain items to move up with the UITextField.
See below: http://cocoawithlove.com/2008/10/sliding-uitextfields-around-to-avoid.html
This is a nice implementation that moves the field up based on the section of the screen it's in (upper, middle, lower). Works very well. May need to be updated for newest SDK, but should be pretty easy.
In experimenting with this, I noticed that if you want to make a BaseViewController that implements this functionality to work for everything that inherits from it, you have to attach another view on top of the UIViewController's view property in order to get it to work. Reason is, if you push the UIViewController's view property up when the keyboard appears, then it resets itself if the app comes back from being active and it's messy.
The problem with this however, is now in all of your child classes you have to attach your subviews to this new view property instead of the regular view property. Also, you probably have to make a custom UITableViewController which will inherit from your BaseViewController class so it can inherit the keyboard notification methods.
Ultimately, I've found it's not the worst idea to have another view on top of the UIViewController's property for a bunch of different scenarios. Making a custom UITableViewController isn't that big of a deal either. So if you have a lot of text fields in your app, this might not be the worst way to go.

Altering characteristics of 3-party buttons (!) in Xcode

I'm doing an iPad app in Xcode 4.3
So, I am triggering a function and inside that function, I want to be able to alter the characteristics of other buttons. For example, upon clicking my button (that I made in Interface Builder) linked to the function, I want to have a load of other buttons (also in IB) change text/color.
I've tried the developer book and a good amount of time on google, but I can't find the question asked or answered in the way i'm trying to phrase it (I decided this was the most clear one in the end)
I know I can easily edit the name of the button I've used to call the function
[MYBUTTON setTitle:(NSString *) TITLE forState:(UIControlState) STATE];
but I can't figure out how on earth to edit other buttons I've added in the interface builder. Is this possible, or do I need to deal with the buttons more programmatically?
so far in my function, I've called the IBAction and made a load of tags to relate to the buttons that I want to change - am I heading along the right road?
Hope this is clear about what I'm trying to achieve, and be gentle with me, my objective C isn't that good yet!
You can mark button properties or instance variables with the IBOutlet marker and then hook the buttons in Interface Builder up to your object.
Also, it isn't a good idea to have all capital letter variable names. In C convention, those are usually reserved for preprocessor macros.
create IBOutlet properties for each button in your view controller, link them in IB or Storyboard and finally change their properties in your method :)

Does storyboard eliminate the need for .nib

With the introduction of storyboard, I wouldn't select to create a .xib/.nib when I create a subclass of UIViewController, because I can just drag out a viewcontroller in interface builder and assign it to the new class.
So, with storyboard, when would i need to use the .xib/.nib file?
Thank you.
Storyboards don't completely remove the need for NIB files. One common example is when creating subviews to go inside a UIScrollView. You can't create the subviews separately in a storyboard; instead you have to create separate NIB(s) for the subviews and attach them to the scroll view programatically.
In fact, on almost any occasion where you have a need for subviews which change at runtime you'll want to use separate NIBs.
Storyboards are great for certain kinds of apps, but for anything even remotely complicated the old way works very well still. An additional benefit is that they co-exist nicely. You can put placeholder views in your storyboard and fill them programatically with NIB-defined views later on.
I guess, storyboard contains the .xib/.nib files for all your views. It present relationships between them and helps you to avoid confusion if you have a LOT of views. Also it saves your time and nerves when writing code.
I have tried out storyboarding lately and I do have mixed feelings about its use:
Pro's
Convenience: You might have to write much less code. So you can for example show a static view without having to write any code.
Overview: You can quickly see how the ViewControllers relate to each other
Efficiency: For the simple use cases I find the Storyboarding much more efficient than "the old way".
Example 1: Editor > Embed In > Navigation Controller and voilà, no more instantiating and configuring is required.
Example 2: You can make "Prototype Cells" for TableView which speeds up the creation of static table views dramatically. AFAIK this is not possible with nib files
It's cool :-)
Con's
I find that the re-usability somehow suffers with storyboards. Although I can segue to a given ViewController from multiple points, it is still limited since in one case I might use the VC as a Popover and in another as a Master-ViewController.
Assuming that you are working in a big team and different people are changing different parts of your application, having one monolithic storyboard which you then have to merge might pose a big problem team-work-wise.
I really would like to have some mechanism to include or reference existing nib files into the storyboard which is currently not possible.
So considering these points I still find storyboarding very appealing but it makes sense to combine both approaches which is not really a big deal. Additionally, this technology it is still quite new so it might improve in the (near) future.
If you use storyboards, you generally won't need to create separate .xib files. You can still use a .xib file if you want to -- it might be useful e.g. if you have a particularly complex view that you'd like to configure by itself. Most of the time, though, there won't be a need to do that.

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.