How to make a .xib show up in a custom class - iphone

I was wondering how to connect my custom class and my .xib. In Interface Builder I have changed the class of the Files Owner to my custom class. I then created an IBOutlet and connected it to the view of the .xib. I then added an instance of my custom class to my UIViewController. My custom class is a subclass of UIView, so I set the background of it to black and can see it appear on top of my UIViewController. What I can't see is my .xib???? Here is my code for my custom class... (FreeThrow is my custom class... FetView is my .xib)
#interface FreeThrow : UIView {
IBOutlet UIView *mySquareView;
}
#property(nonatomic, retain)IBOutlet UIView *mySquareView;
-(void)createMe;
#end
#implementation FreeThrow
#synthesize mySquareView;
-(void)createMe {
[self addSubview:mySquareView];
[self setBackgroundColor:[UIColor blackColor]]; // I did this to know my UIViewController is showing this class... which it is
}
#end
Here is my code for what I call from my UIViewController...
freeThrowView = [[FreeThrow alloc] init];
[freeThrowView createMe];
freeThrowView.frame = CGRectMake(8, 42, 335, 230);
[self addSubview:freeThrowView];
What code do I need to add? What do I need to do? What is the problem? Why is my .xib not showing up.

Sadly apple doesn't give us a way to truly link a xib to a view via IB alone. You'll have to do it via instantiation. Here are some past answers to similar questions:
How do I associate a nib (.xib) file with a UIView?
Loading .xibs into a UIView

Related

How to resize a UITableView

In my application, I have a button that pushes a custom view controller (MenuViewController) on click.
#interface MenuViewController : UITableViewController
I wasn't able to resize the tableview. I tried:
self.tableView.frame=CGRectMake(0, 0,100, 100);
self.View.frame=CGRectMake(0, 0,100, 100);
in viewDidLoad and viewWillAppear. Neither of these methods worked.
I have an idea of creating a UIView initwithframe:.. and add MenuViewController as a subview.
Is this the proper way to do it?
MenuViewController is basically a general control that will handle variable init inputs
and will display the cells according to the inputs, the problem is the frame of the table view.
I believe that if you inherit from UIViewController and expose the UITableView as a property and also on the Interface then you can resize it. When you are using UITableViewController then it will always display in full size mode.
UPDATE:
So instead of doing something like this:
#interface TasksViewController : UITableViewController
{
}
You can do something like this:
#interface TasksViewController : UIViewController<UITableViewDelegate>
{
}
#property (nonatomic,weak) IBOutlet UITableView *tableView;
Also make sure that in interface builder you have a UITableView which is hooked to the tableView property in the TasksViewController. Now in your implementation file implement the cellForRowAtIndexPath method and return the cell.

Common views in viewControllers - Code re-usability

I have few common views in most of my viewControllers. What I noticed is that I can reuse single code for all viewControllers which is absolutely wise. For this I decided to create a class Utils which has static methods like
+(void)createCommonViews:(float)yAxis:(NSString*)text;
In my case common views are three labels and two images.
Problem : I am not able to add these views from Utils. I am wondering how can I send self as a parameter so that I may add the views from Utils. It may be wrong to add views outside the viewController. In that case what can be the solution? Taking all these views in a UIView, setting return type of Utils method as UIView and then adding UIView to viewController (after calling method from viewController) might solve my problem. But what I am looking for is some other solution.
+(void) createCommonViews:(float)yAxis withText:(NSString*) text toTarget:(UIViewController*) target
{
//create views
[target addSuview:view];
}
But I think returning a Uiview and then adding it in the UIViewController afterwards, is a far better solution.
The method you're attempting is to have your view object as a singleton. This is uncommon at best, at worst a crash waiting to happen. Better design is for each of your view controller classes to have its own instance of your custom view, like so:
#interface MyCommonView : UIView
// ...
#end
#interface MyViewController_A : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
// Meanwhile somewhere else...
#interface MyViewController_B : UIViewController {
MyCommonView *commonView;
}
#property (strong, nonatomic) IBOutlet MyCommonView *commonView;
#end
Create a viewController that acts as a parent view for all your common stuff, call it CommonViewController then implement this in all the viewcontrollers you want it to appear
-(void) viewDidLoad
{
[self.view addSubView:[[CommonViewController alloc] initWithRect:..];
}
Or alternatively using xib files

UIView Buttons loaded with XIB do not work

I've loaded a UIView (FirstView.m) with a separate XIB (SecondView.xib), but the buttons in that XIB crash the app. The code for the buttons (IBOutlet & IBAction) are in SecondView.m.
Do I need to point the code from SecondView.m to FirstView.m? I tried using #import and #class... but was unsuccessful.
The code I'm using is completely valid... I'm pretty sure the issue has something to do with the XIB being loaded into the UIView... and then possibly losing its connection to the implementation file. Thoughts?
Thanks in advance!
FirstView.h
#import <UIKit/UIKit.h>
#interface FirstView : UIViewController {
IBOutlet UIView *SecondViewPopUP;
IBOutlet UIButton *openBTN;
}
#property (nonatomic, retain) UIView *SecondViewPopUP;
#property (nonatomic, retain) IBOutlet UIButton *openBTN;
-(IBAction)showPopUp:(id)sender;
FirstView.m
#synthesize SecondViewPopUP;
#synthesize openBTN
- (void)viewDidLoad {
SecondViewPopUP.alpha = 0;
// Add IncidentsViewController to view
SecondView *SecondV=[[SecondView alloc] init];
SecondV.view.frame = CGRectMake(0, 0, 262, 269);
SecondV.view.clipsToBounds = YES;
[SecondViewPopUP addSubview:SecondV.view];
SecondViewPopUP.frame = CGRectMake(0, 76, 262, 269);
[SecondV release];
}
-(IBAction)showPopUp:(id)sender {
NSLog(#"Stats Button was pressed");
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.4];
SecondViewPopUP.alpha = 1;
[UIView commitAnimations];
}
SecondView.h
#import <UIKit/UIKit.h>
#interface ShareViewController : UIViewController {
IBOutlet UIButton *share_facebook;
IBOutlet UIButton *share_twitter;
}
#property (nonatomic, retain) IBOutlet UIButton *share_facebook;
#property (nonatomic, retain) IBOutlet UIButton *share_twitter;
-(IBAction)shareOnFB:(id)sender;
-(IBAction)shareOnTwitter:(id)sender;
SecondView.m
#synthesize share_twitter, share_facebook;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(IBAction)shareOnFB:(id)sender {
NSLog(#"Shared on FB");
}
-(IBAction)shareOnTwitter:(id)sender {
NSLog(#"Shared on Twitter");
}
First of all FirstView (and presumably SecondView) is a UIViewController not a UIView so naming it "FirstViewController" would be much clearer. Views and view controllers are very different things.
Secondly you are adding a UIViewController's view as a subview of another view on the line "[SecondViewPopUP addSubview:SecondV.view];" That's not how UIViewControllers are expected to be used and the UIViewController programming guide recommends against it for good reason.
Each custom view controller object you create is responsible for managing all of the views in a single view hierarchy. In iPhone applications, the views in a view hierarchy traditionally cover the entire screen, but in iPad applications they may cover only a portion of the screen. The one-to-one correspondence between a view controller and the views in its view hierarchy is the key design consideration. You should not use multiple custom view controllers to manage different portions of the same view hierarchy. Similarly, you should not use a single custom view controller object to manage multiple screens worth of content.
Finally if you were to post the error listed when your app crashes we would probably see that you are attempting to send -shareOnFB: or -shareOnTwitter: messages to an instance of "FirstView" which does not implement them because your nib bindings are not configured appropriately ie you set the File's Owner of the nib to be "SecondView" and then loaded it with an instance of "FirstView" as its owner. Impossible to say for sure without more data.

Custom view with nib as subview doesn't seem to be loading

I've created a custom view that loads its content from a nib, like this:
/* PricingDataView.h */
#import <UIKit/UIKIt.h>
#interface PricingDataView : UIView {
UIView *contentView;
}
#property (nonatomic, retain) IBOutlet UIView *contentView;
#end
/* PricingDataView.m */
#import "PricingDataView.h"
#implementation PricingDataView
#synthesize contentView;
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
[[NSBundle mainBundle] loadNibNamed:#"PricingDataView" owner:self options:nil];
[contentView setFrame:frame];
[self addSubview:contentView];
}
return self;
}
/* ... */
In the nib file I set PricingDataView as the type of the File's Owner, and connected the contentView outlet in IB. I placed a regular UIView from the Interface Library onto the full-sized view shown to the user, and then changed it's class name to PricingDataView. It all builds, but at runtime, nothing is rendered where my custom view is supposed to be.
I put breakpoints in PricingDataView.initWithFrame, but they don't hit, so I know I'm missing something that would cause the view to be initialized. What I'm curious about is that in the process of loading my other views from nibs, all the initialization happens for me, but not with this one. Why?
Are you sure your other views aren't using a UIViewController? Here's a quote from the documentation for initWithFrame: from UIView:
If you use Interface Builder to design
your interface, this method is not
called when your view objects are
subsequently loaded from the nib file.
Objects in a nib file are
reconstituted and then initialized
using their initWithCoder: method,
which modifies the attributes of the
view to match the attributes stored in
the nib file. For detailed information
about how views are loaded from a nib
file, see Resource Programming Guide.
when you add files in Interface Builder at runtime it calls the
-(id)initWithCoder:(NSCoder *)aDecoder and not the initWithFrame.
just Undo the class name (PricingDataView) of the view that you add to UIView. In this case the initWithFrame: method would be called.
previously awakeFromNib was called in loop. As your customView and the View you are adding via Nib as a subView are of the same class type.

Custom UIView subclass as a UIViewController property

I had thought I actually had a pretty good handle on the whole view controller model, but something just doesn't seem to making much sense for me. My main issue is with adding a custom UIView subclass as a property of a UIViewController subclass.
Whenever I assign a valid instance of a UIView subclass to that property, nothing happens or the code crashes.
Here's a quick outline:
The main controller inits its own view and that loads fine.
I can then add this UIView subclass to the main controller by instantiating it and addSubview:ivar etc. No problems there...
However... if I wanted to have this custom UIView as a property of the ViewController, that does not seem to work. Can anyone shed some light?
Here's a code summary:
#interface CustomUIView : UIView { }
.
#interface MainViewController : UIViewController {
CustomUIView *someOtherView;
}
#property (nonatomic, copy) CustomUIView *someOtherView;
...
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor greenColor]; // the default controller view
CustomUIView *tmpView = [[CustomUIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
[self.view addSubview:tmpView]; // this works
self.someOtherView = tmpView; // this does NOT work and
self.view = self.someOtherView; // ultimately, this is what i'm after
[tmpView release];
}
Many thanks to this wonderful community!
You can't copy UIViews. Or UIView subclasses. Try retain, instead.