I want to add a view from a nib file as a subview of my main view at the click of a button, but it has to be in a frame (0,108,320,351). I've tried the following code:
-(IBAction) displayJoinmeetup:(id)sender
{
[meetups removeFromSuperview]; //removing the older view
CGRect myFrame = CGRectMake(0, 108,320,351);
[joinmeetup initWithFrame:myFrame]; //joinmeetup declared in header file as IBoutlet UIView*joinmeetup
[self.view addSubview:joinmeetup];
}
This displays only a blank screen, otherwise if I remove the frame the subview displays covering the whole screen, how can I properly do this?
You should never call init... on an object after it has been created. If you can change a setting, there will be a setter for it. In this case, it is setFrame:
-(IBAction) displayJoinmeetup:(id)sender {
[meetups removeFromSuperview]; //removing the older view
CGRect myFrame = CGRectMake(0, 108,320,351);
[joinmeetup setFrame:myFrame]; //joinmeetup declared in header file as IBoutlet UIView*joinmeetup
[self.view addSubview:joinmeetup];
}
initWithFrame is not called for a view loaded from nib. See the UIView class ref for details.
You need to set the view size properties in interface builder (inspector).
You can try thi as follow:
-(IBAction) displayJoinmeetup:(id)sender
{
if(meetups)
{
[meetups removeFromSuperview]; //removing the older view
//also here you should release the meetups, if it is allocated
meetups = nil;
}
UIView *tempView = [[UIView alloc] initWithFrame:CGRectMake(0, 108,320,351)];
joinmeetup = tempView;
[tempView release];
[self.view addSubview:joinmeetup];
}
I suggest you try this:
[joinmeetup setFrame:CGRectMake(0, 108,320,351)];
[self.view addSubview:joinmeetup];
Related
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.......
UIView *view =[[UIView alloc] initWithFrame:CGRect(0,0,300,70)]; //--(View created)
someViewController *someViewControllerObject = [..]; //View Controller Object created.
[view addSubview:[someViewControllerObject.view]];
I want to fit the view controller's view in the UIView's object. The above code doesn't work correctly. Can you help me figure this out?
The simplest would be to just set the frame of the controller view to the bounds of the outer view;
UIView *view =[[UIView alloc] initWithFrame:CGRect(0,0,300,70)]; //--(View created)
someViewController *someViewControllerObject = [..]; //View Controller Object created.
someViewController.view.frame = view.bounds;
[view addSubview:[someViewControllerObject.view]];
#david's answer is correct to set the initial frame of the view controller's view. set the autoResizingMask to get the behavior you want when the superview changes.
someViewControllerObject.view.frame = view.bounds;
someViewControllerObject.view.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
[view addSubview:someViewControllerObject.view];
This code will make it the same size as your current view.
someViewControllerObject.view.frame = view.bounds;
[view addSubview:[someViewControllerObject.view]];
I have a xib with a subview that I set to Class: S7GraphView (if I select it and click on the identity inspector)
When all I have in the (void) didViewLoad { ...
s7graphView = [[S7GraphView alloc] initWithFrame:[self.view bounds]];
//[self.view addSubview:s7graphView];
s7graphView.dataSource = self;
...
}
In the nib, I control-hold the file's owner to the subview and select - S7GraphView and it still shows up empty in the simulator.
If I comment all this out, I get a black subview (I do set the background to black) but not graph:
// s7graphView = [[S7GraphView alloc] initWithFrame:[self.view bounds]];
// //[self.view addSubview:s7graphView];
// s7graphView.dataSource = self;
// [s7graphView release];
If I remove the subview from my view and instead add it programmatically, it works when I add it like this:
s7graphView = [[S7GraphView alloc] initWithFrame:CGRectMake(20., 70., 280.0, 240.0 )];
[self.view addSubview:s7graphView];
s7graphView.dataSource = self; [s7graphView release];
I should be able to add it via the xib too, right? What do youz think I'm doing wrong?
Thanks!!
Have you implemented the delegate and the datasource?
I'm partially through adding a scrollview, by way of instantiating a class that subclasses uiscrollview (below called ScrollViewManager) to override touchesEnded. The problem is although my class now has scrolling and touch, I can't see my view/nib file anymore, even though it's responding to touches and scrolling fine.
My thoughts are to add back the MyClass nib as a subview? or don't know... Seems as though it's there but just hidden behind this scrollView.
The excerpt from 'Myclass : UIViewController ' has these lines of code in viewDidLoad to get the scroll action with touch response.
Thank you so much. So so much.
scrollView = [[ScrollViewManager alloc] initWithFrame:self.view.frame];
scrollView.contentSize = CGSizeMake(320, 600);
[scrollView setUserInteractionEnabled:TRUE];
[scrollView setScrollEnabled:TRUE];
self.view = scrollView;
//trying with this line to add my nib for this class on top of the scroll view
//which doesn't work: 'Accessing unknown 'view' class method'
[scrollView addSubview:Myclass.view];
[scrollView release];
self.view = scrollView line makes your view pointed by view controllers the scrollview.
ie self.view & scrollView now point to same object
after that when you are trying to [scrollView addSubview:Myclass.view]; what actually happening is you are adding scrollView to your scrollView & accessing view property of scrollview.
Just remove the self.view = scrollView line & do this
[self.view addSubView:scrollView];
[scrollView release];
Hopefully it'll work.
for some reason I can't add comments to your post. It didn't work.
Apple talks about adding the subview here: but doesn't explain how. Their code is below for adding the scroll aspect, as I did above. I'm now messing around with trying to add my view as a subview:
UIView *newView = [[NSBundle mainBundle] loadNibNamed:#"MyClassView" owner:self options: nil];
[scrollView addSubview:newView];
but that crashes and goes not where. Don't know what to do now. Apple's code here with original comments:
(void)loadView {
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
self.view=scrollView;
scrollView.contentSize=CGSizeMake(320,758);
scrollView.contentInset=UIEdgeInsetsMake(64.0,0.0,44.0,0.0);
// do any further configuration to the scroll view
// add a view, or views, as a subview of the scroll view.
// release scrollView as self.view retains it
self.view=scrollView;
[scrollView release];
}
EDIT: This question is due to a big lack of understanding how Interface Builder and properties in classes works.
Why can't i just set self.mySubView = anoterhView; like one can set self.view = anotherView; ?
## .h
#interface TestController : UIViewController {
IBOutlet UIView *mySubView;
}
#property (nonatomic, retain) IBOutlet UIView *mySubView;
##.m
#implements TestController
#synthesize mySubView;
- (void)viewDidLoad {
AnotherController *anotherController = [[AnotherController alloc] initWithNibName:nil bundle:nil];
anotherView = anotherController.view;
// if i do
self.view = anotherView;
// result: replaces whole view with anotherView
// if i instead do
self.mySubView = anotherView;
// result: no change at all
// or if i instead do:
[self.mySubView addSubview:anotherView];
// result: mySubView is now displaying anotherView
}
NOTE: I'm using interfacebuilder. I'm sure everything is hooked up allright because self.view, and self.mySubView addSubview: is working allright..
To make it automatically appear on your self.view you need to overwrite your setter method, e.g.:
- (void)setMySubView:(UIView *)view {
[mySubView removeFromSuperview]; // removing previous view from self.view
[mySubView autorelease];
mySubView = [view retain];
[self.view addSubview: mySubView]; // adding new view to self.view
}
mySubview is a property which is a reference to an UIView object. So when you assign an UIView object to it, you are merely changing what mySubview is referring to and no more as in this case,
self.mySubview = anotherView;
The original UIView object that mySubview was referring to is still referred to within view's subviews property. Nothing changes.
But when you add anotherView as a subview of mySubview, anotherView belongs to the view hierarchy and is displayed on screen. So this works.
view (parent of) mySubview (parent of) anotherView
However when you assign anotherView directly to the view, You not only change the UIView object view was referring to but it also adds itself to the parentView. This is handled by UIViewController.
self.view = anotherView;
Your setCurrentView should be more or so like this,
- (void) replaceSubview:(UIView *)newView {
CGRect frame = mySubview.frame;
[mySubview removeFromSuperview];
self.mySubview = newView;
[self.view addSubview:newView];
newView.frame = frame;
}
As a response to what #beefon said. This works kind of as expected, but background-color is transparent. It doesen't respond either... buttons do not get pressed etc..
- (void)setCurrentView:(UIView *)newView {
/* 1. save current view.frame: CGRect mySubViewFrame = [mySubView frame];
2. remove and put new subview - I have wrote how to do it
3. set new frame for new view: [mySubView setFrame:mySubViewFrame]; */
CGRect currentViewFrame = [currentView frame];
[currentView removeFromSuperview];
[currentView autorelease];
currentView = [newView retain];
[self.view addSubview:currentView];
[currentView setFrame:currentViewFrame];
}
Your instance variable needs to be a property in order to use the dot. syntax, use:
#Property (nonatomic, retain) IBOutlet UIView* subview;
in the header, and use:
#synthesize subview;
in the main file.
In order to set a UIView using the dot. syntax you need to make it a property. This also allows you to set the subview's properties outside the class.