I know how to place a nib file in the "main" view controller:
when I execute this method a new nib file will be displayed.
Is it possible to place that nib file in a UIView controller instead?
I want to place that nib file in that view controller instead of in the main view. How could I do that?
Edit:
I tried doing what you mention Paul I don't know what am I doing wrong. Anyways here is what I did:
I created another view controller with the properties an methods you mentioned.
I hooked up my IBoutlet UIView *exampleView to the base view:
then from here I am lost I don't know where to place the other methods. I would like to place that exampleView into:
that view.
I have tried placing them in pgBackground.m but it does not work. I want to place them inside an IBaction so that I can load that with a touch up inside event with a button.
I managed to place a nib file in a uiview control but I have the problem that the subview will not rotate if the device does. I am currently working on a solution to this but so far here is a question that can show you how to add the view from another nib file to a uiview control.
If I follow I think you will need to:
Create a UIView sub class with associated xib
ExampleView.h
ExampleView.m
ExampleView.xib
Set up a property to contain the View hierarchy (everything you want to be hooked up in Interface builder)
ExampleView.h
#property (nonatomic, retain) IBOutlet UIView *exampleView;
ExampleView.m
#synthesize exampleView = _exampleView;
In the ExampleView.m you need to add:
- (void)awakeFromNib
{
[super awakeFromNib];
[[NSBundle mainBundle] loadNibNamed:#"ExampleView" owner:self options:nil];
[self addSubview:self.exampleView];
}
You use awake from nib so you can use this sub class in Interface Builder. If you also want to instantiate it in code you need to hook up the xib in the init method. In this case I would probably extract the nib loading like so:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self loadNibIntoView];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self loadNibIntoView];
}
- (void)loadNibIntoView
{
[[NSBundle mainBundle] loadNibNamed:#"ExampleView" owner:self options:nil];
[self addSubview:self.exampleView];
}
In the ExampleView.xib file make sure to hook up your IBOutlet UIView *exampleView to the base view.
Now in any xib file where you want to use your custom view simply drag it into your window and change the class to your subclass. This is how I got it working I look forward to some people suggesting improvements.
can u tell me what u want to do? if u want to change orientation then first u declare a bool en type variable in app delegate file then define in app delegate.m file if orientation change then detect and make Boolean type variable true for landscape and false for portrait. this process use for next all views. and u want u execute nib in main view controller then u have two ways one is dynamically and other by interface builder. in interface builder u Select navigation controller and drop in main window file . after that u change the view of navigation controller's view by press cmd+4 and select view which u want to display first.
-(IBAction)btnSubmit_click{
UIDeviceOrientation orientation = [[UIDevice currentDevice]orientation];
if (orientation == UIDeviceOrientationLandscapeLeft) {
// Do stuff
}
else if (orientation == UIDeviceOrientationLandscapeRight) {
// Do stuff like [self setCordinateLandscape];
}
}
-(BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation) interfaceOrientation
{
// Return YES for supported orientations
//set as per requirements ====>>
return (interfaceOrientation == UIDeviceOrientationLandscapeRight);
// Or return TRUE;
}
Related
I am trying to create a custom Picker view ,connected the touchupinside event to my PickerViewViewController.h class as funcion
- (IBAction)Done:(id)sender;
added funcion in .m
- (IBAction)Done:(id)sender {
NSLog(#"Done");
}
Added the view to my main view as
PickerViewViewController *pic=[self.storyboard instantiateViewControllerWithIdentifier:#"Pickerview"];
[self.view addSubview:pic.view];
but when i click done button it crashes ,i had done it before using XIB easily ,help?
First of all try renaming your function something like
- (IBAction)doneButtonPressed:(id)sender
Done might be reserved by the system for something (not sure, but it happened to me before)
You could just drop the storyboard ... and make a normal ViewController with a .xib :). Actually there is no need of a ViewController. Just make a UIView and a .xib linked to your UIView.
To attach a .xib to a UIView you can use:
+ (CustomViewName *)getNewCustomView {
NSArray *xib = [[NSBundle mainBundle] loadNibNamed:#"CustomViewName" owner:nil options:nil];
for (NSObject *obj in xib) {
if ([obj isKindOfClass:[CustomViewName class]]) {
return (CustomViewName *)obj;
}
}
return nil;
}
and intialise it like :
CustomViewName *customView = [CustomViewName getNewCustomView];
customView.frame = CGRectMake(...);
self.view addSubview:customView;
also in your .xib file you must set the name of your class ... but on the VIew not on the file's owner like so:
I want to present a modalView (it can be a viewController) that I draw in Storyboard. I don't want to have to make the whole thing programmatically. Is there a way to do this without it being a full screen view?
I guess another way to ask the question is: how do I [self.view addSubView:mySubView] where mySubView is drawn in InterFaceBuilder/Storyboard?
To do this properly, you should look at View Controller containment in the docs. Basically you would addChildViewController after instantiating the viewController from your storyboard and then add the viewController's view to your current view hierarchy.
To just get it working however, the following will get you going:
UIViewController *childViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"<identifier you set in Interface Builder>"];
[self.view addSubView:childViewController.view];
Note that one of the reasons to do it 'properly' will be to ensure that autorotation and presentation callbacks are sent to the sub view controller.
Override the initWithCoder method in the object-c class.
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super initWithCoder:aDecoder])) {
[self addSubview:[[[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil] objectAtIndex:0]];
}
return self;
}
I've been struggling with this for a while and I think the solution is really simple, but I just can't get it right. I have a UIViewController, which has its view and now I would like to add a subview to it. Subview should be loaded from a nib. I've followed the steps described here, ie.:
1. Create MyView class which is a subclass of UIView
2. Declare IBOutlet properties in MyView
3. Make .xib file, where File Owner is set to UIViewController and View class set to MyView
4. Connect outlets
5. In MyViewController, viewDidLoad method :
NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:#"MyView" owner:self options:nil];
MyView *mView;
for (id view in nibViews) {
if ([view isKindOfClass:[MyView class]]) {
mView = (MyView*) view;
}
}
[self.view addSubview:mView];
mView is loaded successfully, but when I try to add it as a subview I get EXC_BAD_ACCESS. I've even added: mView = [(MyView*) view retain]; but that doesn't help.
What am I doing wrong?
Don't worry...
You don't need to take separate nib file and referencing to the myView class again. Simply you can drag UIView from library into your current viewController's xib, and then u can simply connect the view from current view to the xib.
See below images:
i'm not sure of your point 3:
Make .xib file, where File Owner is set to UIViewController and View class set to MyView
the file owner shouldn't be the uiviewcontroller, but the MyView class
In my case, I didn't want my view controller to have any knowledge of the IBOutlets from my view's .xib. I wanted my view subclass to own the IBOutlets. Unfortunately UIView doesn't have an initWithNibName: method, so I just created my own category.
Here's what I did:
In IB, click on your main UIView, and in the Identity Inspector, set the class to your subclass
In IB, click on File's Owner, and in the Identity Inspector, set the class to your subclass
Use your new category method initWithNibName: to instantiate your view.
And here's the category I created:
- (instancetype)initWithNibName:(NSString *)nibName
{
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil];
if (arrayOfViews.count < 1) {
return nil;
}
self = arrayOfViews[0];
return self;
}
Inspired by this post.
Note though, that so far the frame will adjust automatically, so unlike the code in the post, I haven't yet had to explicitly set the frame.
Also, unlike the post's code, I needed to set owner:self so the IBOutlets would be wired up correctly.
I'm trying to make a custom Callout view for AnnotationView. I had seen this answer, and seems a good solution (it works). I'm trying to load a UIView from a nib file, and the UIView appears, but his buttons don't work, don't get pushed.
Is there a way of doing this?? How can I load the UIView from a nib file and get the buttons working??
Or maybe anyone help me finding a good solution.
Thanks
Here's the code I'm using:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
//Add custom view to self...
calloutView = [[[NSBundle mainBundle] loadNibNamed:#"MyCustomView" owner:self options:nil] objectAtIndex:0];
[self addSubview:calloutView];
}
else
{
//Remove custom view...
if (calloutView) {
[calloutView removeFromSuperview];
}
}
}
Thanks in advance
The nib for your custom UIView should have a backing UIView class (MyCustomView.h/.m). In Interface Builder you will want to set the custom class value under the identity inspector to your custom class. Once this is done you would hook up the UIButton in the nib to your desired IBAction by dragging the connection (touch up inside likely) from the bottom to the main view under the objects section (NOT the file's owner as you may be used to).
Hopefully that helps
~Good Luck
I found a solution for my problem: gik-animated-callout
I have a UIView subclass -
#interface DatePickerPopup : UIView
UIToolbar *toolbar;
UIDatePicker *datePicker;
#end
#implementation
- (id)initWithFrame:(CGRect)frame
{
NSArray *xib =
[[NSBundle mainBundle]
loadNibNamed:#"DatePickerPopup"
owner:self
options:nil];
self = [xib objectAtIndex:0];
if (self) {
}
return self;
}
#end
and the nib looks like -
In my UIViewController containing the DatePickerPopup (datePopup):
- (void)viewDidLoad
{
datePopup = [[DatePickerPopup alloc] initWithRect:CGRectZero];
CGRect newFrame = datePopup.frame;
newFrame.y = 200.0f; //lets say this aligns it to the bottom in portrait
datePopup.frame = newFrame;
// Normally happens when accessory button pressed but for brevity...
[self.view.superview addSubview:datePopup];
}
- (void)willAnimateRotationToInterfaceOrientation:
(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration
{
CGRect screen = [[UIScreen mainScreen] bounds];
if (toInterfaceOrientation == UIInterfaceOrientationPortrait ||
toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
self.datePopup.frame =
CGRectMake(0.0f, newHeightPortrait, screen.size.width, 260.0f);
}
else
{
self.datePopup.frame =
CGRectMake(0.0f, newHeightLandscape, screen.size.width, 260.0f);
}
}
However, this gets stretched out for some reason when the orientation changes the view gets stretched to the height of the screen bounds - the navigation bar...
after viewDidLoad
after willAutorotate...
Since your view controller appears to be managed by a navigation controller, calling [self.view.superview addSubview:datePopup]; adds your popup as a subview of a UIViewControllerWrapperView, which is one of the private classes UIKit uses to implement the functionality of UINavigationController. Messing with UIKit's private view hierarchy is always risky. In this case, based on the behavior you're seeing, it seems likely that UIKit expects any subview of UIViewControllerWrapperView to be a view controller's view, so it resizes your popup accordingly.
I think the safest way to resolve this is to have your view controller's view be a wrapper that contains your tableView and, when necessary, your popup view. Unfortunately using a wrapper view means that the view controller can't be a UITableViewController. You'll have to change the superclass to UIViewController, set a custom tableView property, and manually adopt the UITableViewDataSource and UITableViewDelegate protocols.
Note: You might be tempted to add your popover as a subview of your window, but I'm not recommending that because UIWindow only autorotates its topmost subview corresponding to a view controller. This means that if you add your popover to your window, it won't autorotate.
EDIT: BTW, by reassigning self = [xib objectAtIndex:0]; in initWithFrame:, you're leaking the object that was originally alloc'd. If you're going to reassign self in this way, you should release the existing object first.
Add the
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
method in the viewController class and return YES. If this method returns YES, only then will the device support landscape orientation. Try out this extra code and see if it helps...
You can set the frame size for landscape in this method itself instead of the current method. PS: I just saw you've used a UIView instead of controller...you might want to change to controller.