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:
Related
I am using the iCarousel Library and am having some problems.
In the Controls Demo Example Project, a XIB file is used and the view is setup like:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
if (!view)
{
//load new item view instance from nib
//control events are bound to view controller in nib file
//note that it is only safe to use the reusingView if we return the same nib for each
//item view, if different items have different contents, ignore the reusingView value
view = [[[NSBundle mainBundle] loadNibNamed:#"ItemView" owner:self options:nil] lastObject];
}
return view;
}
Because I am using Storyboards I create a View Controller and setup the view like this:
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view
{
NSString * storyboardName = #"MainStoryboard";
NSString * viewControllerID = #"DuuinNewsItem";
UIStoryboard * storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
//create new view if no view is available for recycling
if (!view)
{
DUDuuin *tDuuin = [_duuins objectAtIndex:index];
DUNewsItemViewController * controller = (DUNewsItemViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
controller.duuin = tDuuin;
view = controller.view;
[view setFrame:CGRectMake(0, 0, 314.0f, 415.0f)];
}
return view;
}
When I add an action to any button in the view I get the error:
I have tried a lot of things that are recommended in Stackoverflow, but I cannot find a solution:
I tried:
Setting the outlet to Strong (someone says it's a problem because ARC)
Deleting the sender in the action
Adding the method in the View Controller that have the icarousel
****UPDATE****
Now i see other issue. When i define the Action in the DUNewsItemViewController and try it in the simulator, it says :
-[__NSCFType btnTest:]: unrecognized selector sent to instance 0x1577c650
So, i adde the method in the .m file of the View Controller that have the iCarousel and the problem still the same:
EXC_BAD_ACCESS (code=2)
Some info:
I'm using ARC
It's on Storyboards
The number of views is dynamic
Your main issue here is not with the view specifically but rather with your DUNewsItemViewController instance. You create your controller in the method you have provided and return the view. The view is being retained by iCarousel. Your DUNewsItemViewController on the other hand is not. There is nothing that is strongly pointing to it. Since there are no strong pointers to it, it is being deallocated. Your view is displaying correctly, with all of your buttons, because again, it is being retained outside of your DUNewsItemViewController. When a button is pressed it attempts to access its action method and fails because the controller no longer exists.
To fix this issue you need to create a strong pointer to your controller (not the button as you attempted before). I am not recommending a perfect strategy, rather one that works.
You could create a mutable array (as a property) and add the viewcontrollers into it (if there are more than one) as you create them. This way the controller that is iCarousel's delegate/datasource holds a reference to it:
if (!view)
{
DUDuuin *tDuuin = [_duuins objectAtIndex:index];
DUNewsItemViewController * controller = (DUNewsItemViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
// Add controller to array to hold a strong reference to it.
[self.myMutableArray addObject:controller];
//
controller.duuin = tDuuin;
view = controller.view;
[view setFrame:CGRectMake(0, 0, 314.0f, 415.0f)];
}
Otherwise, if there is only one (or a few) you could create unique outlets:
#property (strong, nonatomic) DUNewsItemViewController *firstVC;
and in your carousel:viewForItemAtIndex:reusingView:view method include a line self.firstVC = controller.
If something does not make sense let me know. Again, there are probably better implementations but this should work. The reason that the XIBs worked in the example is because they are just UIViews not UIViewController subclasses like you are using. Again, your view is working like it should (displaying, just like the example), but your controller is being deallocaed (not like the example, since there is no controller being used).
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 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;
}
I have a nib file say TestView.xib. I added some components to it.
Now I created another nib file AnotherTestView.xib
I want to add the view of TestView.xib into AnotherTestView.xib using interface buidler, so that I dont need to add the same components from TestView again. They are like basic components for all my views.
Is there any way to do that. Like can we set the nib file name for a UIView in IB. Or how can we add this existing view which has a nib file into another nib file.
I wrote up how we embed custom-view Nibs inside other Nibs in a longish blog post. The crux is overriding -awakeAfterUsingCoder: in your custom view, replacing the object loaded from AnotherTextView.xib with the one loaded from the "embedded" Nib (TestView.xib).
Something along these lines:
// TestView.m
- (id) awakeAfterUsingCoder:(NSCoder*)aDecoder {
BOOL theThingThatGotLoadedWasJustAPlaceholder = ([[self subviews] count] == 0);
if (theThingThatGotLoadedWasJustAPlaceholder) {
// load the embedded view from its Nib
TestView* theRealThing = nil;
NSArray* elements = [[NSBundle mainBundle] loadNibNamed: NSStringFromClass([TestView class])
owner: nil
options: nil];
for (id anObject in elements) {
if ([anObject isKindOfClass:[TestView class]]) {
theRealThing = anObject;
break;
}
}
// pass properties through
theRealThing.frame = self.frame;
theRealThing.autoresizingMask = self.autoresizingMask;
[self release];
self = [theRealThing retain];
}
return self;
}