I have a ViewController with xib,.h,.m files. Now i want to display it as a popUpView in another viewController. so I did like this...
Second *view2 = [[Second alloc] initWithNibName:#"Second" bundle:nil];
[view2.view setFrame:CGRectMake(20, 20, 280, 400)];
{self.view addSubview:view2.view];
but the problem here I am able to set frame randomly, but the viewController contains a textField and button. They are not getting added at random positions on the view like some textField comes out of the frame of view added.
After some googling i find this, but this not enough to solve my issue.
Adding a ViewConroller's View as subview programmatically
How to solve it...
It seems that you are changing the frame of the view in your view controller but not handling the repositioning of the elements inside the view. What you can do is override the layoutSubviews method in the view so that when the frame changes the text fields reposition themselves.
You will have to create an actual UIView subclass which will layout the text fields,
#interface SecondView : UIView{
}
#implementation SecondView{
- (void) layoutSubviews{
//self.frame would be to most up-to-date frame that you just set
}
}
Your UIViewController will just create the view like so,
#interface Second : UIViewController{
}
#implementation Second{
- (void) loadView{
self.view = [[[SecondView alloc] init] autorelease];
}
}
Related
I have one UIViewController without NIB file. Now i have one my customized UIView. I want to make UIViewController's view inherit from my customized UIView, is it possible ? I know that if I have XIB file than I can make Custom Class from there but without XIB can it be done?
Thanks in Advance
If you are using a UIViewController subclass, and don't want to use a nib file, then override the loadView method in your subclass:
#implementation MyViewController
- (void)loadView {
self.view = [[MyView alloc] init];
// additional view setup here
}
If you are just using a generic UIViewController (not a subclass), then you might be able to just assign to the view controller's view property, like this:
vc.view = [[MyView alloc] init];
But I'm not sure if that works properly outside of loadView. I haven't seen any documentation that says it is or is not allowed.
Replace your view controller's view like this:
// ViewController.m, in viewDidLoad
self.view = [[MyCustomView alloc] initWithFrame:self.view.bounds];
A more conventional alternative is to fill the default view with the custom subview, like this:
MyCustomView *myCustomView = [[MyCustomView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:myCustomView];
I think you need to load a custom view programmatically, for that you need to override the loadView method of your view controller.
-(void)loadView
{
[super loadView];
CustomView *view = [[CustomView alloc]initWithFrame:self.view.bouds];
[self.view addSubview:view];
}
Replace this in your .h file
#interface ViewController : UIViewController
with
#interface ViewController : Customized View Controller
I have a UIView designed in XIB file. Basically with a navigation bar and a button to close the UIVIew. I want to show this UIView in several UIViewControllers across the app.
Below is the code I have imp[emnted so far.However the UIView doesn't show up.
My ViewControllers are designed in storyboard however I needed a simple UIView that is why I created a new custom subclass of UIView alongwith a xib file of the same name.The File's Owner is also set to custom subclass. What else is required here?
#interface BottomSlidingView : UIView //this is my UIView
{
}
#implementation BottomSlidingView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setUserInteractionEnabled:YES];
NSLog(#"Bottom View Loaded"); //I get this log entry but the view doesn't showup.
}
return self;
}
- (BOOL)loadMyNibFile {
if (![[NSBundle mainBundle] loadNibNamed:#"BottomSlidingView" owner:self options:nil]) {
return NO;
}
return YES;
}
And this is how I call the custom UIView in my UIViewController.
-(void)shareButton:(UIBarButtonItem *)button
{
NSLog(#"share button clicked");
BottomSlidingView *bsv = [[BottomSlidingView alloc] initWithFrame:CGRectMake(20, 480, 280, 420)];
[bsv loadMyNibFile];
[self.view insertSubview:bsv belowSubview:self.optionsToolBar]; //this toolbar is a subview that I am adding to this view controller.
}
I see a couple problems with your approach:
Create the view instance from a nib file, rather than instantiating it with initWithFrame:. For example (if the custom view is the only root-level object in the nib file):
+ (instancetype)bottomSlidingView
{
return [[[UINib nibWithNibName:#"BottomSlidingView" bundle:nil] instantiateWithOwner:nil options:nil] lastObject];
}
Implement awakeFromNib or initWithCoder: instead of initWithFrame: (which isn't called when loading from nibs) in your UIView subclass.
In your view controller, you would use something like the following to create the view:
- (void)shareButtonPressed:(id)sender
{
BottomSlidingView *slidingView = [BottomSlidingView bottomSlidingView];
[slidingView setFrame:CGRectMake(20, 480, 280, 420)];
[[self view] insertSubview:slidingView belowSubview:[self optionsToolBar]];
}
Hope that helps.
Where ever you want to reuse a UIView of a UIViewController in another view controller you need to use this....
YourViewController * child = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];//View controller of view , you want to reuse
[self.view addSubView:child.YourView]; //YourView = Name of view, you want to reuse
[self addChildViewController:child];
[child release];
After adding childViewController All IBActions will be work in child.
And after removing this view You have to remove YourViewController from parentViewController other wise there will be memory issues.......
So i'm adding UIView with UIScrollView in it to another view by pressing segment tool:
UIView.h
#interface gettingELORolesViewController : UIViewController{
UIViewController *currentController;
NSMutableArray *viewControllers;
}
- (IBAction)SegmentToggle:(UISegmentedControl *)sender;
#property (strong, nonatomic) IBOutlet UIView *containerView;
UIView.m
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Storyboard_iPhone"
bundle:nil];
firstView *FirstView = [sb instantiateViewControllerWithIdentifier:#"firstOne"];
secondView *SecondView = [sb instantiateViewControllerWithIdentifier:#"secondOne"];
viewControllers = [NSMutableArray arrayWithObjects:FirstView,SecondView,nil];
currentController = FirstView;
[containerView addSubview:FirstView.view];//containerView = self.view
and then depends on what segment is chosen, it shows different view:
- (IBAction)SegmentToggle:(UISegmentedControl *)sender {
UIViewController *selectedView=nil;
if (sender.selectedSegmentIndex==0) {
selectedView= [viewControllers objectAtIndex:0]; // retrieve object at index 0 from viewControllers array
}
else if(sender.selectedSegmentIndex==1){
selectedView= [viewControllers objectAtIndex:1]; // retrieve object at index 1 from viewControllers array
}
[currentController.view removeFromSuperview]; // remove Current displaying view from superView
currentController=selectedView; // make selected View to be the current View
[containerView addSubview:selectedView.view]; // Add newly selected view on container View
}
secondView is tableViewController and everything is working great when i choose second segment. When i choose first one it shows up but scroll doesn't work and i don't know why.
firstView.m viewDidLoad method looks like this:
-(void)viewDidLoad{
[super viewDidLoad];
mainScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[mainScrollView setContentSize:CGSizeMake(320, 600)];
[mainScrollView setScrollEnabled:YES];
}
Paging is enabled in storyBoard. And it hooked up with .h file of firstView.
Please tell me what am i doing wrong.
When you call -SegmentToggle:,
you create a local variable called selectedView
you assign a view controller to selectedView depending on what segment is selected
the method ends, selectedView goes out of scope
In short, you're not doing anything. You should, at least, replace a view in the current view hierarchy with the view of the selected controller (and maybe stash a reference to the selected controller in an instance variable for later lookup?)
But taking a step back, it looks like you're trying to create a view controller that manages other view controllers. There are now very specific rules around that as of iOS 5. Please watch the WWDC 2011 video called "Implementing UIViewController Containment" for more information and examples.
I'm looking to create a sizeable subview that's draggable like this:
If there is an IBAction that takes you to the next View (SecondViewController) and when it does, there's another IBAction there and when you click on that one, it creates a SubView that's about half of the size of the current screen you're in (SecondViewController) that shows the third view controller that would be created? Also, how would you make that subView draggable? Thank you for helping.
Sorry, just to be clear, you want your second view controller to have a button that when tapped, adds your third view controller taking up half the screen at the bottom?
If this is the case then you can do this with the new view controller containers in iOS5.
Ok, so you have three view controllers. For the sake of this lets say your class are called FirstViewController, SecondViewController and ThirdViewController.
I assume from what you say that you already have you instance of FirstViewController with a button, that moves you on to an instance of SecondViewController, and that the issue is then getting SecondViewController to add an instance of ThirdViewController to the bottom half of the screen when a button is pressed.
The .m file for SecondViewController will need to do something like this:
#import "ThirdViewController.h"
#interface SecondViewController ()
#property (retain) ThirdViewController *thirdViewConroller;
- (void)buttonTap;
#end
#implementation SecondViewController
#synthesize thirdViewConroller = _thirdViewConroller;
- (void)dealloc {
self.thirdViewConroller = nil;
[super dealloc];
}
- (void)loadView {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.titleLabel.text = #"Show third controller";
[button addTarget:self action:#selector(buttonTap) forControlEvents:UIControlEventTouchUpInside];
button.frame = // Some CGRect of where you want the button to be
[self.view addSubview:button];
}
- (void)buttonTap {
// When the button is tapped, create an instance of your ThirdViewController and add it
self.thirdViewConroller = [[ThirdViewController alloc] initWithFrame:/* Some CGRect where you want the controller to be */ ];
[self.thirdViewConroller willMoveToParentViewController:self];
[self addChildViewController:self.thirdViewConroller];
[self.thirdViewConroller didMoveToParentViewController:self];
}
#end
This should give you a button on your second controller, that will create and add you third controller. Make sure yo us till have all the standard methods that you had before, this should be in addition to what you have.
In your interface for ThirdViewController:
#interface ThirdViewController : UIViewController <NSObject>
- (id)initWithFrame:(CGRect)frame;
#end
Then in the implementation of your ThirdViewController:
- (id)initWithFrame:(CGRect)frame {
self = [super initWithNibName:nil bundle:nil];
if (self) {
self.view.frame = frame;
// Do your init stuff here
}
return self;
}
It should then handle adding the views and such forth.
Make sure your thirdViewController class has a valid initWithFrame: initialiser method.
This should do the trick, if you need any further help let me know :)
I want to create a 'detail view' in my navigation-based app similar to the address book app.
I want to create a UIView that has an UIImageView and a UILabel that I can pass to a UITableVIew's tableHeaderView property when pushed by a navigation controller. The label text and image must take information from the managed object context when it loads.
I started trying to do this using IB, but go fed up when the label text wouldn't update, regardless of where I put the myView.UILabel.text = #"some new text". It just kept presenting the text I entered in the IB inspector window.
So without using IB, how would I go about creating a UIView that has a UILabel and a UIImageView in it?
Should I be creating a new class that is a sub-class of UIViewController or just UIView?
How do I go about creating the sub-views for the label and image?
Where should the text and image URL be set in code? (viewDidLoad or loadView or viewWillLoad)(UIView, UIViewController, detailViewController)?
If you started using IB and the UILabel text wouldn't update, sounds like the IBOutlet of your view controller isn't correctly connected to the label in IB.
Hopefully that will fix your problem with using IB. And in the viewController code, you should update that text in viewDidLoad.
But if you want to do this programmatically, I would make a subclass of UIView (not UIViewController).
And I would override initWithFrame and do all the setup there.
Something like the following:
myView.m
#implementation myView
#synthesize imageView, myLabel;
- (id) initWithFrame:(CGRect) frame
{
if (self = [super initWithFrame:frame]) {
// Setup your image view and add it to the view.
self.imageView = [[[UIImageView alloc] initWithFrame:initWithFrame:frame] autorelease];
self.imageView.image = ...
[self addSubview:self.imageView];
// Setup your label
self.myLabel = [[[UILabel alloc] initWithFrame:frame] autorelease];
self.myLabel.text = #"whatever you like";
[self addSubview:self.myLabel];
}
return self;
}
Make sure to clean up memory properly in the dealloc method of course depending on whether you like make class properties vs class variables.