Functions for subview abstracted to different .h and .m files - objective-c

I have MasterViewController.h and MasterViewController.m files and within those files I load a subview on top of part of that view when the a button is pressed. I want the functions of that subview (IBActions, etc.) to be in different files (ContactUs.h and ContactUs.m) so I can abstract this program and break it into smaller/simpler pieces.
How can I go about doing this? The .xib file is loaded in the MasterViewController.m with:
[[NSBundle mainBundle] loadNibNamed#"ContactUs_GeneralContact" owner:self options[NSDictionary dictionary]];

Create a new subclass of UIView (via File - New ) and move the methods to the new subclass.
open your xib in Interface Builder
in the inspector on the right select the identity inspector and insert your class name as custom class
All done.

I am not sure i have understood your question:)...What you can do is take two view controllers 1. MasterViewController
2. ContactUsViewController
and two Views
1. MasterView(MasterViewController's View) main view
2. ContactUsView(ContactUsController's View) subview which is loaded on top
Write what ever function u need
in ContactUsViewController
import it in MasterViewController , instantiate it when ever you want and load it where ever you want:):)
Thus Master and ContactUs are completely independent of each other..:)have a nice day

Related

Why I can't drag outlets from a custom UIView Class?

I have a TableViewController With a dynamic cell and a view I added above it.
I've created a UIView class and added it as a custom class for that view ( just like I do with a custom cell) but I can't drag labels etc from that UIView to its .h file. Only to the main TableViewController.h file. Any idea what's the problem?
A table view in a UITableViewController takes up the whole screen, so the view you added is actually in the table view, not above it, so that's why you can connect to the table view controller. If you want to add a view above the table, use a UIViewController instead, and resize the table view so it doesn't take up the whole screen.
I've noticed this too (for an OS X project) in Interface Builder. I'm not sure if it is a bug or not in IB.
What you will have to do is enter the #property declarations in your .h file manually and then you will be able to connect them.

Change a UIViewController to a UITableViewController inside a storyboard?

I've made a view in my storyboard which I've now decided I'd rather display its data via static table cells.
I can't use static table views in a UIViewController (Static table views are only valid when embedded in UITableViewController instances). So, I need to convert my existing UIViewController to a UITableViewController somehow. I've changed the .h file's parent, but that hasn't done it.
Is there another way to get this going? I'd really rather not have to make a new VC in the storyboard and move everything over, it's a big hassle.
I'll add to this, since the question is about how to change a UIViewController into a UITableViewController, and given that this question is over a year old and the original answer, while valid and may or may not have been the only solution at the time, doesn't actually answer the question and is not the only solution.
It IS possible to do this, you just have to set up the table view delegate and datasource outlets in IB, and manually edit the storyboard XML, which sounds scary but is actually very easy.
First, change your class's parent to be a UITableViewController. UITableViewController already adopts the UITableViewDatasource and UITableViewDelegate protocols, so if your class does too you can remove them:
#implementation MyTableViewController : UITableViewController
...
#end
Next, create new referencing outlets on your UITableView for its dataSource and delegate. The easiest way to do this is to control-drag from the UITableView to itself. The popup will give you the dataSource and delegate options.
Lastly, you need to change the storyboard XML. The storyboard file can get pretty big pretty fast. The easiest way to find the scene you are looking for is by setting Storyboard Identifier in the Identity Inspector. To view the XML directly, right click on the storyboard file in the project navigator and select "Open As -> Source Code". Now just search for whatever you set the reuse identifier to earlier. You'll see something similar to this:
<!-- My Table View Controller -->
<scene sceneID="EuE-XX-cCb">
<objects>
<viewController storyboardIdentifier="MY_TABLE_VIEW_IDENTIFIER" ... >
// Lots of other stuff
</viewController>
</objects>
</scene>
All you need to do is change the opening and closing view controller tags
<viewController>
</viewController>
to be tableViewController instead
<tableViewController>
</tableViewController>
That's it! No need to create a new UITableViewController scene or embed a UITableViewController in a container view.
EDIT:
I should also add that the UITableView MUST be the root view. It cannot be embedded inside another UIView.
If you want your static cell table view not to take up the entire screen, then using a container view is the easiest way to go. Start with a regular UIViewController and drag a container view (next to normal UIView in the object list) into its view. Resize it however you want -- the storyboard will automatically provide a view controller connected to this container view with an embed segue. Delete that controller, drag out a table view controller and right-drag from the container view to this table view controller to make a new embed segue. This table view controller can be accessed from the UIViewController with its childViewControllers property (and conversely, you can access the UIViewController from the table view controller with parentViewController if you need to).
What I did, is creating a UITableViewController in IB, open the Storyboard with a text editor, and copy all the nodes inside from the UIViewController to the UITableViewController.
I think that with this way there's less risk of deleting something important.
Before copying the sections objects, make sure that both tableviews (UIViewController and UITableViewController) have the same properties set like: static or dynamic cells, style (plain or grouped), etc.

iOS subview widget hooked up to multiple controllers

So, I want to create a reusable widget as a xib and subview that can appear on a set amount of specific screens. This widget will have three buttons, each with an Action.
I want to be able to handle these actions on multiple viewcontrollers.
So say ViewControllerA, ViewControllerD, and ViewControllerF can handle the three button events, each in their own way.
I've created the nib file. How do I import it into the specific viewcontrollers, and then how do I wire up those events?
EDIT: I know that I could potentially get outlets set up via a viewcontroller, but Apple states that UIViewController is for full-screen views only, and my widget is only taking up a small portion of the screen.
You have done correctly. And one thing is, In iOS it's not widget.It's a UIView.
(Sorry there may be any typo in my code.I have written myself in StackOverflow)
Follow Below Steps to finish it..
1) After you have created the xib for the view, then you need to have a UIView subclass files.. For example your xib name likes this CustomView.xib means then create a files like this CustomView.m and CustomView.h
2) In your CustomView.xib , You need to set the fileOwner as your CustomView.h.
3) In your CustomView.m file, there will be a method like initWithFrame: In that method you need to load your xib file like this
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomView" owner:self options:0];
UIView *currentView = [topLevelObjects objectAtIndex:0];
[self addSubView:currentView];
4) Almost over. In any of your view controller, you can use this xib like
CustomView *newSubView = [[CustomView alloc]initWithFrame:CGRectMake(0,0,55,67)];
[self.view addSubView:newSubView];
That's it.. Go on..
You have created a nib file but make sure that you have also created the .h and .m file that will be the controller for that nib file. You will have to look up how to implement delegate methods which your other view controllers can capture and act on in their own way. Here is a great tutorial to get you started on making custom classes with custom delegates: Link

switching views without navigation controller

I have a tab controller and within this tab controller one of the views is called random. Within random, I have added multiple views (without making new .xib files or .m/.h) that I simply create in interface builder and linkup. For example, I created landscape view. I have a button within the original view (random) that takes me to landscape view with a simple line of code: self.view=landscape;. This works. My problem is having a custom "back" button that will take me to the original view. I tried calling self.view=view;
but this did not work. When I check the connection in interface builder with the original view, it simple just says "view". What line of code is needed to return me to the original view ("view")?
Thank you in advance and my apology if this is extremely obvious
I guess you could persist your original view so that you can restore it later. This should do it:
Add this property to your view controller (in your .h header file):
#property (nonatomic, retain) IBOutlet UIView *originalView;
Autogenerate the accessors (in your .m implementation file):
#synthetize originalView
Inside your viewDidLoad method, assign the actual original view from the NIB to it:
self.originalView = self.view
And then to return to your original view after a click on your back button, do this:
self.view = self.originalView

Accessing Views created in Interface Builder

I've created a ChildViewController class, and then a nib that uses that class.
Then I created a BaseView, that includes some buttons, and some text that I'll be changing programmatically.
Then I created two more views (Boy and Girl), that I want to be able to lay behind the baseview so that the background color is different along with some graphics in an ImageView. I've named the views that I created in IB 'Boy' and 'Girl'...
But when I go back to my code where I'm calling ChildViewController, I'm not sure how to access the views I created so I can call insertSubView. Do I need to instantiate them in code? (in ViewDidLoad perhaps?) Does the nib create the instances when it loads?
I'm confused about how to handle multiple views for a single ViewController
edit =================
#Pablo Santa Cruz
Your answer assumes that i have two nibs and two view controllers (one for each view). I want to know if I can use one nib and one controller, and load in UIViews. It seems silly to create another nib and controller, when all want to do is change the background color and some graphics. Can't I programatically load in UIViews into a UIViewController?
Add IBOutlets in your App Controller class in Xcode then link them in IB (ctrl-click or right-click) from the connections tab in the Inspector to the object.
Then you will be able to send method calls to the objects.
The code in Xcode should look like this:
#interface AppController : NSObject
{
IBOutlet Girl girlIvarName1;
IBOutlet Boy boyIvarName2;
}
#end
You can access a UIView programatically by assigning a value to its tag property, which can be set in IB on the first tab of the inspector (Command 1)
The tag value defaults to zero, so if you want to access it specifically, make it non zero and unique. e.g. 100, which I will use in the example code below
Once the tag is set you can access the view using the following code in your UIViewController that was initWithNibName for the NIB containing the tagged view
UIView *aView = [self.view viewWithTag:100];
You can get instances for your IBuilder views with this piece of code:
boyViewController = [[BoyViewController alloc] initWithNibName:#"BoyViewController" bundle:nil];
girlViewController = [[GirlViewController alloc] initWithNibName:#"GirlViewController" bundle:nil];
Assuming your NIB file names are BoyViewController and GirlViewController. With those instances, you can do whatever you need to. I.E., adding them to a parent view (with addSubView message on the parent).