I am using UIViewController for display my view. My view have been created in interface builder.
Right now these are next parameters for view:
width: 568
height: 320
Orientation: Landscape
in ViewController I have next code:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return ((interfaceOrientation == UIInterfaceOrientationLandscapeLeft) || (interfaceOrientation == UIInterfaceOrientationLandscapeRight));
}
in info.plist I have added just two interface orientation right and left.
but when I try to output width of my view in code I get 320 and when I try to output height it write down in console 568 but I expect 320 instead.
I don't know why it works like this. Any suggestions?
even if I add this:
[self.view setFrame:CGRectMake(0, 0, 568, 320)]; in viewDidLoad method. even then I have inccorect height
I need to know width size I use in this method:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
CGFloat width = 0.0f;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
width = 568.0f;
} else {
width = 1024.0f;
}
NSInteger page = scrollView.contentOffset.x / width;
NSLog(#"%d", page);
}
Right now I use hardcode variable of width, but how come. Why I can't use self.view.frame.size.width because the sides swop each other - because.
Maybe you're printing width and height in the viewDidLoad method before the orientation occurs. Try to print it on viewWillAppear or with performSelector:afterDelay:
Another thing that might affect the dimension of the view is how you set the autoresizing mask on the interface builder (the red arrows below the x,y,height,width section on the right panel)
Please add LaunchScreen.storyboard in your project and set it as your Launch Screen under
Targets > General > App Icons and Launch Images > Launch Screen file.
Related
I want display different UIButton/UILabel/UISlider sizes on an iPhone 4/4s screen. In the parent ViewController viewDidAppear: method I was able to set new button frames by calling my viewFormatting function.
- (void) viewFormatting
{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
//iPhone 4
if (result.height == 480)
{
self.myButton.frame = CGRectMake(x, y, width, height);
self.myLabel.frame = CGRectMake(x, y, width, height);
//etc.
}
}
}
But when I try calling the same method viewFormatting inside initWithFrame: on separate UIView class the button/label frames do not resize. I also tried calling the function inside layoutSubviews. I put a NSLog inside viewFormatting so I know it is getting called correctly, but the button/label frames do not change.
Note: In both scenarios I have created the outlets in XIB files.
Any help is greatly appreciated!
Update: Thanks to #nburk I realized that the use AutoLayout was checked on my xib file. After removing that the code above works perfectly.
I'll leave it here for anyone who needs a sample.
Add this method:
-(void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[self viewFormatting];
}
viewDidLayoutSubviews get called automatically.
I've searched a lot about how can I determine the actual view size dynamically in the viewDidLoad method.
Here is my approach which seems to be work on both iOS6 and iOS7 with both Landscape and Portrait mode.
Is there a better solution for that?
Here is my code:
- (CGSize)actualSize {
CGFloat widht;
CGFloat height;
// Determin height and widht
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
if (orientation == UIDeviceOrientationLandscapeRight || orientation == UIDeviceOrientationLandscapeLeft) {
widht = kHeightSelfView;
height = kWidthSelfView;
} else {
widht = kWidthSelfView;
height = kHeightSelfView;
}
// Determin navigationbar height
CGFloat navigationBarHeight = self.navigationController.navigationBarHidden ? .0f : (MIN(self.navigationController.navigationBar.frame.size.height, self.navigationController.navigationBar.frame.size.width));
// Determin navigationbar height
CGFloat statusbarHeight = [DeviceCompatibility isIOS7] ? (MIN(SharedApplication.statusBarFrame.size.width, SharedApplication.statusBarFrame.size.height)) : .0f;
return CGSizeMake(widht, height - navigationBarHeight - statusbarHeight);
}
Typically you should only perform view-based geometry in viewWillAppear. Your view's frame is not yet set in viewDidLoad, but it will be set correctly before viewWillAppear is called.
Instead of picking height & width, you can pick the frame of view like this:
// Adjusts the frame of the child view.
CGRect frame = self.view.frame;
CGRect linkedFrame = scene.view.frame;
linkedFrame.origin.x -= frame.origin.x;
linkedFrame.origin.y -= frame.origin.y;
and then you can make them flexible so that they will resize properly :
// The scene's main view must be made flexible so it will resize properly
// in the container.
scene.view.autoresizingMask = (UIViewAutoresizingFlexibleWidth |
UIViewAutoresizingFlexibleHeight);
Let me know if this is not what you need :)
I created a UICollectionView in the interface builder. I referenced it with
#property (strong, nonatomic) IBOutlet UICollectionView *contactList;
in my .h file and #synthesize contactList; in my .m file.
I tried to implement a slightly different layout in portrait and landscape using the following code:
- (void) adjustViewsForOrientation:(UIInterfaceOrientation) orientation {
if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) {
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)contactList.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(48, 80, 48, 0);
flow.minimumLineSpacing = 80;
} else if (orientation == UIInterfaceOrientationLandscapeLeft || orientation == UIInterfaceOrientationLandscapeRight) {
UICollectionViewFlowLayout *flow = (UICollectionViewFlowLayout*)contactList.collectionViewLayout;
flow.sectionInset = UIEdgeInsetsMake(48, 64, 48, 0);
flow.minimumLineSpacing = 64;
}
}
This works prefectly, but I also want to change the size (in landscape I have a 2*3 grid per page and in portrait it's a 3*2 grid). I tried setting the size like this:
CGRect frame = [contactList frame];
frame.size.width = 960;
[contactList setFrame:frame];
But it won't update. There is no error, but the view just isn't updated. It just stays at the same size as before. What do I have to do to update the view?
In my app I always using this:
[self.contactList performUpdates:^{
CGRect frame = [contactList frame];
frame.size.width = 960;
[contactList setFrame:frame];
[self.contactList.collectionViewLayout invalidateLayout];
} completion:nil];
This should set your frame and update your layout.
When are you modifying the frame of the contactList? At VC initialization time, outlets are nil. Your view controller gets a ViewDidLoad call after the outlets are connected.
I suspect that contactList is still nil when your resizing code is being executed. Move that code's execution into a ViewDidLoad method, and you'll be able to access the real deal.
You can easily test this theory by adding the following to where you resize the frame:
NSLog(#"contactList is: %#",contactList.description);
i think you try to do
[self.yourcontrollerview reloaddata]
when you modify the frame..
Here is the desired outcome. The blue area is the UIView of interest. The UIView is not a UIImageView.
I've tried all sorts of arrangements with auto-resizing masks to no avail
This can only be done programmatically. One option is what #user2223761 suggests with subclassing. If you don't want to subclass UIView, then you need to set the frames on orientation changes and set yourView.center to be the center of the center.
- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration {
if (UIInterfaceOrientationIsLandscape(interfaceOrientation)) {
// Make sure that the frame is centered in the screen
NSInteger paddingLeftSide = (self.view.bounds.size.width - 480) / 2;
self.view.frame = CGRectMake(paddingLeftSide, 0, 480, 320);
} else {
self.view.frame = CGRectMake(0, 0, 320, 320);
}
}
Dealing with different screen sizes can be tricky. In your case it is not :)
since you want to center the view in the screen what ever size it is, all you need to do is set the center of the view to be the center of the screen.
CGRect screenBounds = [[UIScreen mainScreen] bounds];
view.center = CGPointMake(screenBounds.size.width/2,screenBounds.size.height/2);
This code assumes the view's superView's bounds is the same size as the screenBounds..
First: Subclass UIView (create a MYUIView).
Second: override the method
- (void)layoutSubviews {
[super layoutSubviews];
// .. put your code...
}
and perform the frame update manually inside that method by reading the screen size.
auto-resize mask must be set to UIViewAutoresizingNone.
The Auto Resizing for the UIView's. in Xcode shows the value (0,20,768,1024)however user can't change it in Xcode but if try to repint out the width of the view in your code :
NSLog(#"Board view w %f", self.view.size.width);
NSLog(#"Board view h %f", self.view .size.height);
the values that you get for the width with a portrait are 1024 or 1004
I would like to know in the case of 1004 as width what will happen for the remaining 20 pixels ?
many thanks in advance
You probably are not counting the 20px of the top UIStatusBar.
You can also set the frame manually.
-(void)willRotateToInterfaceOrientation: (UIInterfaceOrientation)orientation duration:(NSTimeInterval)duration{
NSLog(#"didRotateFromInterfaceOrientation");
if( orientation == UIInterfaceOrientationPortrait || fromInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown){
[moviePlayer.view setFrame:CGRectMake(0,0,768,1024)];
} else {
[moviePlayer.view setFrame:CGRectMake(0,0,1024,768)];
}
}