How to call a view within a ViewController? - swift

I have a view, named IndicatorView, a subclass of UIView. I have a xib file for this view as well. I'd like to call this view in my ViewController using UITapGestureRecongnizer, which I have been able to do. My problem lies in how to call the view when I tap. What code should be added to my UIView file so that I can call it from the xib file. Thanks in advance.

To get an object from a xib file programatically you can use: [[NSBundle mainBundle] loadNibNamed:#"MyXibName" owner:self options:nil].
Now, in your click event of UITapGestureRecongnizer add the following code.
ObjC
IndicatorView *objIndicator = [[[NSBundle mainBundle] loadNibNamed:#"IndicatorView" owner:self options:nil] objectAtIndex:0];
[self.view addSubview:objIndicator];
Swift 3
var objIndicator: IndicatorView? = Bundle.main.loadNibNamed("IndicatorView", owner: self, options: nil)[0]
self.view.addSubview(objIndicator)
Note: You can pass the view on which you want to add at the place of self.view

Related

Load XIB into a subview

I have been looking all over fo information on how to do this but have found nothing that I understand.
Basically I want to be able (from ViewController.xib) to load another XIB file on top of that view in a subview. This new subview should be manipulatable, so it can be moved around with multitouch gestures and/or swipe gestures.
I was trying to add a "view" object from ViewController, then load the other XIB into that subview object.
Hopefully someone can help. Thanks!
You should be able to accomplish what you want by making an instance of the other class in your ViewController, and then adding it as a subview to the current view controller.
MyOtherViewController *movc = [[MyOtherViewController alloc] init];
[self.view addSubview:movc.view];
As for handling the gestures, you could either handle them in the MyOtherViewController class, or make a container view and handle them it in your ViewController. Don't forget that they are subviews, and that any movement should be relative to their superviews.
The above code is almost right but except
UIView *newView = [[NSBundle mainBundle] loadNibNamed:#"MyNewXib" owner:self options:nil];
it should be
UIView *newView = [[[NSBundle mainBundle] loadNibNamed:#"MyNewXib" owner:self options:nil] objectAtIndex:0];
and in a view controller simply you can add
[self.view addSubview:newView];
You can define the subview in a xib by creating a xib (select File New... "user interface", "view").
You can load that view like this:
UIView *newView = [[NSBundle mainBundle] loadNibNamed:#"MyNewXib" owner:self options:nil];
That new view can now be treated like any other subview:
// assign it to a property
#property (strong, non atomic) UIView *viewFromXib;
#sythesize viewFromXib=_viewFromXib;
self.viewFromXib = newView;
// add it to your hierarchy
self.viewFromXib.frame = CGRectMake( /* this will start out 0,0 the size from the xib */ );
[self.view addSubview:self.viewFromXib];
// add gesture recognizer
UITapGestureRecognizer *tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(tap:)];
[self.viewFromXib addGestureRecognizer:tapGR];
... and so on

how to access parent view reponder

I have 3 viewcontroller. FirsViewController, SecondViewController and ThirdViewController. The FirstviewController is root viewcontroller and it is adding secondviewcontrooler xib as the subview. like..
[firstviewcontrollerObject.view addsubview:secondViewcontrollerObj.view].
In secondViewcontroller I have one button. When button touch action is called, ThirdViewController is loaded. like..
[SecondViewControllerobj.view addsubview:thirdviewcontrollerobj.view];
Now ThirdViewCOntroller is on the screen. This viewcontroller has nothing only a small button. So I am seeing 2 buttons on screen. First button is of SecondviewCOntroller and second button is of ThirdViewCOntroller. But, I am able to give touch action of 3rdviewcontroller only not 2ndviewcontroller button.
How should I design my view to take touch of both button and I don't want to merge both controller i one.
I think you should implement it without using multiple UIViewControllers.
View Controllers are useful for pushing and poping from a navigation stack: with only one view displayed at time. I did not try, but I think that's why you get the bug.
But you prefered navigationControllers to the benefits of their xib, did't you?
If so, there is a way to use xib with views :
NSArray * arr1 = [[NSBundle mainBundle] loadNibNamed:#"MyView1" owner:nil options:nil];
NSArray * arr2 = [[NSBundle mainBundle] loadNibNamed:#"MyView2" owner:nil options:nil];
NSArray * arr3 = [[NSBundle mainBundle] loadNibNamed:#"MyView3" owner:nil options:nil];
UIView * v1 = [arr1 objectAtIndex:0];
UIView * v2 = [arr2 objectAtIndex:0];
UIView * v3 = [arr3 objectAtIndex:0];
// now you have your 3 views, do what you want with them:
v1.center = CGPointMake(100,100);
[self.view addSubview:v1];
v2.center = CGPointMake(100,200);
[self.view addSubview:v2];
v3.center = CGPointMake(100,300);
[self.view addSubview:v3];
that means your first view controller's contains two view which are from secontroller.view and thirdviewcontroller.view now third is taking press gesture but second is not taking press gesture.
please take two view on the firstviewcontroller.view
and do it like that
firstviewcontroller.secondVW=[[Secondviewcontroller alloc]init].view;
firstviewcontroller.thirdVW=[[Thirdviewcontroller alloc]init].view;
in this manner both the view will take touches.

load view from a nib

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.

Changing Views From Inside App

I have a one View Controller Called ThemeViewController with three nibs, all of which are a different theme.
I want to change the nib simply by hitting a button from within the app. I placed this method from within the ThemeViewController class.
- (IBAction)switchTheme {
self = [[ThemeViewController alloc] initWithNibName:#"theme_1" bundle:nil];
}
Any help or suggestions? Thanks
Use this instead:
[[NSBundle mainBundle] loadNibNamed:#"yourNibName" owner:self options:nil];

How to get a UIView from a UIViewController without adding the controller to the view hierarchy and making it visible?

I want to avoid laying out a view programmatically.
I want to only use a NIB file to do such work.
The problem is that the only way that I know of bringing a NIB file to life is via a controller like so:
ZBarReaderViewController* reader = [[ZBarReaderViewController alloc] init];
ScannerOverlayViewController *sovc =
[[ScannerOverlayViewController alloc] initWithNibName:#"ScannerOverlayView" bundle:nil];
reader.cameraOverlayView = sovc.view;
But this approach doesn't work out so well because stepping through the debugger shows that the views is 0x0 or Nil.
Now this may be because the controller is never added-to/displayed-on the view hierarchy and I'm trying to get a view out of it in order to recycle it as an "overlay view" on another controller that allows me to specify it.
Any thoughts on how this can be accomplished without writing the View programmatically?
You can load view from XIB file:
// I assume, that there is only one root view in interface file
NSString *nibName = #"CustomView";
NSArray *loadedObjects = [[NSBundle mainBundle] loadNibNamed:nibName owner:nil options:nil];
UIView *view = [loadedObjects lastObject];