How to center a view loaded from nib file? - ios

I have a view defined in a nib file. (named FooView.xib)
The view is of a fixed size (smaller than screen size).
I would like to load it in a view controller (named FooViewController.[hm]) and I want the view to show up in the center of the screen in whatever devices (a universal app).
Since the name of the xib and viewcontroller class have such correspondence, the view in the xib is loaded automatically.
Then I write code in the -(void)viewDidLoad method to center my view, which can be referenced by self.view. I write something like this.
CGRect screenBounds = [[UIScreen mainScreen]bounds];
self.view.center = CGPointMake(screenBounds.size.width/2, screenBounds.size.height/2);
And it does not work. Neither will it work when I modify self.view.frame = ....
I checked the values of self.view.center or self.view.frame. They did change but I didn't see any changes in the simulator.

In the xib file make sure you have disabled auto-layout.
in viewController.m: (*Edit: place this in viewDidAppear not in viewDidLoad)
[self.view addSubview:myView];
myView.center = self.view.center;

Related

how to show an overlapping view iOS

I have a view with some UI components and a button on it, upon touch of a button I want to show a half view with some textfields on it overlapping the initial view, the initial view should be visible partly , the overlapping view will cover only half screen from bottom. Is this possible ?
I don't have any code as I am unable to figure out what it needs to be done, as we show any view it covers the entire screen.
Thanks
there are several ways you can do this, here are two:
1) add a popover controller that gets displayed on your button press:
here's some apple documentation on popovers: https://developer.apple.com/Library/ios/documentation/WindowsViews/Conceptual/ViewControllerCatalog/Chapters/Popovers.html
2) add the new view as a subview to your UIViewController
PROGRAMICALLY:
in the viewDidLoad function you can do the following to initialize the halfScreenView
GLfloat topOffset = self.view.frame.size.height/2;
UIView halfScreenView = [[UIView alloc] initWithFrame: CGRectMake(0, topOffset , [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height - topOffset)
[self.view addSubview:halfScreenView];
-more logic might be needed if you support Landscape orientation, you can always re-assign the location of the view with halfScreenView.frame.origin and halfScreenView.frame.size
-initially you can have this view be hidden
halfScreenView.hidden = YES;
-when you click the button it will show the overlaying view:
halfScreenView.hidden = NO;
USING STORYBOARD:
you can also set up your overlaying view in the storyboard if you have one
-drag a UIView into your UIViewController and set it up where you want it to be located
-initialize the view to be hidden by checking the hidden box in the attribute inspector
-add the view as a property to your view
-manage when to show this view with self.halfScreenView.hidden
-this technique allows you to customize what is inside the new view within the storyboard which is nice
FOR BOTH:
-be careful with layers, you don't want your view to show up behind the one you already present. In the storyboard the last thing inserted goes on top. With in the code you can always access/change the views z position with halfScreenView.layer.zPosition (higher z values are on top)
First create a new class subclassing UIViewController called SecondView (or whatever you want), then design the UI the way you want (in its .xib file)
Then go to your main view controller's file and make an IBAction for that button.
In that method, write:
SecondView* second = [[SecondView alloc] initWithFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height/2, height, width);
[self.view addSubview:second.view];
This will add it to the bottom half of the screen. Put your own parameters for its height and width. When you want to dismiss the view, you can do this inside your SecondView class
[self.view removeFromSuperview];
You can deal with the textFields from within the SecondView class and have them communicate with your other view by doing the following in SecondView.h
#property IBOutlet UITextField* textField;
Hope this helps!
Yes, assuming you are using Interface Builder, go ahead and build the overlapping view and hook up all of the IBOutlets and IBActions. Say this view is called myView. Set myView.hidden = YES and myView.enabled = NO. This hides and disables myView so that it isn't even there from the user's perspective. In the appropriate button's IBAction, change the hidden and enabled properties to YES. That will make the view visible and active again.

Screen bounds extends visible area

I'm trying to make a square (50 x 50) UIView in the lower right hand of my main view, but I'm confused about why it's not entirely visible. In this instance, only the tip of it is visible from the bottom. Am I confusing some concept?
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
UIView *transparentFloater = [[UIView alloc] initWithFrame:CGRectMake(width - 50.f, height - 50.0f, 50.0f, 50.0f)];
[self.view addSubview:transparentFloater];
Try to add the autoresizing mask:
transparentFloater.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
If I am not wrong, You have created your ViewController with xib and in the attributes of view, you have forgot to mention that you are using a "navigation bar" as "top bar".
Reason
So in ViewDidLoad, view in .xib with a height X is returned. But as you might have loaded the viewController using UINavigationController, after loading the height of view is decreased by 44pixels.
Suggestions :
1) Whenever you know that you are going to have navigation bar on top please mention it in .xib file as well.
For doing so click on the view in xib and select the option called topbar in attributes Inspector of utilities area
2) Call the following api
NSLog(#"In ViewDidAppear %#",NSStringFromCGRect(self.view.bounds));
in
viewDidLoad
viewDidAppear
to track whats happening with the bounds of view
You does not need to do anything just put
transparentFloater.backgroundColor = [UIColor redColor];
because your view (custom) is invisible (because your main view color and custom view color are same (white) ) may be. I tried your code in my demo project. it worked perfectly for me.

Getting subViews' frames in Storyboard

I just want (for now) to get the dimensions of a subview on the view controller's instantiation.
[This is a reduction to as simple a case I can find of a previous question. I am trying to figure out why subViews of scenes in Storyboards are not behaving the way I expect, which is to say: like XIBs do - I just want to get dimensions of my subviews before anything is actually drawn to the screen]
To condense the problem down to a new, clean project, I do this:
create a new, single view project with "using Storyboard" checked
add a single UIView to the default existing MainStoryboard_iPad.storyboard (and change its background to green to make it more easily seen - beyond shrinking the dimensions some, this is the only change I make from the default UIView I drag onto the scene)
option-click the ViewController.h file in the navigator to bring it up in its own frame underneath the Storyboard frame and insert a pair of braces underneath the #interface directive
control-click-and-drag from the UIView in the Storyboard to ViewController.h and tell it to name the outlet firstViewFirstSubView
So we now have for ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{
IBOutlet UIView *firstViewFirstSubView;
}
#end
Then, I add this method to the ViewController.m:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(#"View Controller will appear. firstViewFirstSubView: %# ", firstViewFirstSubView);
NSLog(#"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width,
firstViewFirstSubView.frame.size.height,
firstViewFirstSubView.frame.origin.x,
firstViewFirstSubView.frame.origin.y);
}
At this point, I expect to be able to get the dimensions of the UIView subview. I get all 0s, though:
2012-11-15 15:21:00.743 StoryboardViewBounds[11132:c07] View Controller will appear. firstViewFirstSubView: <UIView: 0x9379730; frame = (0 0; 0 0); autoresize = TM+BM; layer = <CALayer: 0x9378e40>>
2012-11-15 15:21:00.744 StoryboardViewBounds[11132:c07] subView's dimmensions: 0.000000 by 0.000000 at 0.000000, 0.000000
What am I doing wrong? It seems like this should be very straightforward, so I think I must be missing something simple, whether throwing the right switch in the Storyboard editor or implementing a method that Storyboard needs.
Those dimensions are calculated and set when the call to layoutSubviews is made, which occurs after viewWillAppear. After layoutSubviews is called on the UIVIew you can get the dimensions.
Look at implementing this method in your view controller: viewDidLayoutSubviews. At this point you should be able to get dimensions of your subviews. Note that this call is available starting in iOS 5.0 but since you reference storyboards I assume you are working at or above that anyway.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
NSLog(#"View Controller did layout subviews. firstViewFirstSubView: %# ", firstViewFirstSubView);
NSLog(#"subView's dimmensions: %f by %f at %f, %f", firstViewFirstSubView.frame.size.width,
firstViewFirstSubView.frame.size.height,
firstViewFirstSubView.frame.origin.x,
firstViewFirstSubView.frame.origin.y);
}
There is a Related issue that I am compelled to address, which hopefully will save someone else a day of debugging:
I am finding out that in Storyboard:
segue-push does not cause subViews to be laid out at -viewDidLayoutSubviews (they are instead laid out at some other time just before -viewDidAppear).
Whereas...
segue-modal and [navController.storyboard presentViewController:] does cause subViews to be laid out at -viewDidLayoutSubviews.
The solution is to put [self.mySubView layoutSubviews] within the viewController's -viewDidLayoutSubviews method in order to manually load the subViews within mySubView.
My case was that I had a custom gradient button that was not properly initializing it's visual appearance.
The button was contained within a scrollView that contained a CustomView which contained the custom gradient button.
So, basically... a button within a view within a scrollView.
The app starts out with a UINavigationController having some other ViewController1 loaded.
ViewController1 contains a button which, when pressed, launches a storyboard segue-push to ViewController2.
(this was arranged in storyboard by control-dragging from the button in ViewController1 to ViewController2).
ViewController2 contains the scrollview/customView/customButton.
In ViewController2's -viewDidLayoutSubviews, I initialize the customButton which is a custom Gradient Button having it's own .h/.m files.
GradientButton.m has an initLayers method which configures it graphically and requires the bounds/frame property of the button to be initialized.
However...
in ViewController2's -viewDidLayoutSubviews, self.customButton had a frame of 0,0,0,0.
A few notes:
Yes, I am calling [super viewDidLayoutSubviews] at the beginning of -viewDidLayoutSubviews.
The only view that has been laid out at -viewDidLayoutSubviews is self.view (ViewController2's initial view, as connected in Storyboard's connections panel. in my case - self.view is a scrollView).
To resolve:
in ViewController2, I created an outlet self.bottomView for the view that contained self.customButton.
in ViewController2's -viewDidLayoutSubviews, I call [self.bottomView layoutSubviews]
This will then cause customButton's frame/bounds to be properly set.
Next, I call [self.customButton initLayers] which now properly initializes my custom gradient button.
A few notes about ViewController2's -viewDidLayoutSubviews: calling [self.view layoutSubviews] causes bottomView's frame to be initialized, but NOT customButton's frame.
In terms of a view hierarchy, -layoutSubviews applies only to the subViews of self.view and not to any subViews of those subViews.
This only appears to be the case with storyboard segue-push.
The storyboard segue-modal and the programmatic [navController presentViewController] both seem to correctly initialize all levels of the view hierarchy (all "subViews of subViews") by the time -viewDidLayoutSubviews is called.

Change UIView to UIScrollView

I built in my storyboard this "myView" view controller scene:
I have a simple view containing an ImageView and a UILabel (that I reference in code through IBOutlets).
What I want is transform this view to a scrollview and I was wondering if I could just adjust things in the storyboard for this purpose.
I also tried to change the view to scrollview programmatically adding to the viewController's "ViewDidLoad" method the following:
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame];
scrollView=[[UIScrollView alloc] initWithFrame:fullScreenRect];
scrollView.contentSize=CGSizeMake(320,600);
self.view=scrollView;
But I'm not able to see my imageView and my label if I do So..Why?
I also tried (in storyboard) to assign the view (inside the "custom class" panel) the UIScrollView class but that's not working.
OK I found the solution, I changed the view type (identity inspector), but the view property of a UIViewController isn't a UIScrollView. So I get round this with casting the view to a UIScrollView:
[(UIScrollView *)self.view setContentSize:CGSizeMake(320, 1000)];
Add View to controller->Identity Inspector->Class-Change to UIScrollView
Resize your view
(self.urview as! UIScrollView).contentSize = CGSizeMake(self.view.frame.width, self.view.frame.height)

UITableView width when inside a popover

See below - the tableView cells are getting cut off. Why doesn't this work? The width of the popover is 240.
(In a subclass of UITableViewController)
- (void)viewDidLoad {
[super viewDidLoad];
self.tableView.frame = CGRectMake(0,0,200,200);
}
You have to specify the content size of the ui controller you are displaying. You can do it in 2 ways:
access the ui controller from your popover controller and set it size:
UIViewController* yourViewController = yourPopOverController.contentViewController;
yourViewController.contentSizeInViewController = CGSizeMake(300, 600);
check the checkbox "Use Explicit Size" for popover in the inspector of the viewController in storyboard
As you see the content ui controller is the one responsible of setting the size of your popover.
Have you tried specifying the popover's content size?
i.e.
self.popoverController.popoverContentSize = CGSizeMake(400, 500);
I've found that while popover's are "suppose" to adjust to the appropriate size based on the content view controller, this doesn't always work as well as it should.

Resources