I have a UIView,
UIView *topBarView
I am deciding the size i.e. the width and height of topBarView as
CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height*.05);
Now I am setting the frame of topBarView as
topBarView.frame = (CGRect){0, 0,topBarSize};
Im my view controller I have set this condition for rotation
- (BOOL)shouldAutorotate
{
return YES;
}
-(UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskPortrait;
}
When my view controller opens in portrait mode it is all good and as expected the topBarView is placed at the top
But when my view opens in Landscape Left mode the topBarView instead of being on top in Landscape is on the left of the screen i.e same frame as it was in case of portrait
How can I fix this?
As you have set frame your view's origin is (0,0) so it will definitely set in top - left corner in any orientation.
If you want to manage width and height according to orientation then you should use autolayout.
You should set top,leading,trailing and fixed height constraint to that view. so, it will will manage height,width and position with orientation.
Update:(as asked in comment)
Write below code in viewdidload and comment yours
UIView *topBarView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height * 0.5)];
topBarView.backgroundColor = [UIColor orangeColor];
[self.view addSubview: topBarView];
Hope this will help :)
Related
I am developing in Objective-C. I am using the following code for scrollView, and it works fine in Portrait orientation.
- (void)viewDidLayoutSubviews
{
UIScrollView *scrollView = self.scrollview;
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
}
But the view does not slide down when I change to landscape orientation.
Am i missing something?
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
In this, 320 used for Width.. When you are trying for landscape orientation. Then please increase size for width..
Please check it with more than 320 (Minimum Screeen Width).
3.5 inch - 480 & 4 inch - 568
[scrollView setContentSize:CGSizeMake(SCREEN_WIDTH + YOUR_EXTRA_SIZE,3100.0)];
Hopefully, it will help you.
Thanks.
- (void)viewWillAppear:(BOOL)animated
{
UIScrollView *scrollView = self.scrollview;
[scrollView setContentSize:CGSizeMake(320.0,3100.0)];
}
Scrollview always loaded in portrait mode in viewDidLoad/loadView method, so what ever adjustment you like to made you have to do those changes in viewWillAppear/viewDidAppear methods.
When Device get rotate didRotateFromInterfaceOrientation method get called, so I would suggest to change the ScrollView Contant size this way
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
self.scrollView.contentSize = self.contentView.bounds.size;
}
Note : Make sure your have UIScrollView and UIView in your layout
UIScrollView is scrollView and
UIView is contentView
How can I vertically center an image inside a scrollView?
I'm using storyboards in Xcode 5. The main view is embedded inside a navigation controller, and "Adjust scroll view insets" option is enabled in main Storyboard. This main view has a scrollView which size is equal to the main view size.
The imageView is inside the scrollView and it's the same size as the scrollView. Content mode is set to AspectFit.
So, hierarchy is as follows:
- UINavigationController
- UIView
- UIScrollView
- UIImageView
The image may be landscape or portrait, and can be any size (it's loaded at runtime). This is why imageView is the same size as the scrollView.
How can I vertically center the image inside the scrollView?
EDIT:
As commented before, I have set imageView's contentMode to AspectFit because the image may be too big, so I need it resized. The problem I have is that the image is not center of the scrollView.
You can check screenshot at link and download source code at link.
It will be good to use auto layout as mentioned by #Douglas. However, if you prefer the traditional way, you can also make it work.
I'll first give you the answer and then explain it to you. You should first delete the image view from the storyboard ( I'll explain it later), and then add the viewWillAppear method.
- (void)viewDidLoad
{
[super viewDidLoad];
// 1. Add the image view programatically
UIImageView * imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:#"portrait.jpg"]];
[_scrollView addSubview:imageView];
_imageView = imageView;
}
- (void)viewWillAppear:(BOOL)animated
{
// 2. calculate the size of the image view
CGFloat scrollViewWidth = CGRectGetWidth(_scrollView.frame);
CGFloat scrollViewHeight = CGRectGetHeight(_scrollView.frame);
CGFloat imageViewWidth = CGRectGetWidth(_imageView.frame);
CGFloat imageViewHeight = CGRectGetHeight(_imageView.frame);
CGFloat widthRatio = scrollViewWidth / imageViewWidth;
CGFloat heightRation = scrollViewHeight / imageViewHeight;
CGFloat ratio = MIN(widthRatio, heightRation);
CGRect newImageFrame = CGRectMake(0, 0, imageViewWidth * ratio, imageViewHeight * ratio);
_imageView.frame = newImageFrame;
// 3. find the position of the imageView.
CGFloat scrollViewCenterX = CGRectGetMidX(_scrollView.bounds);
CGFloat scrollViewCenterY = CGRectGetMidY(_scrollView.bounds) + _scrollView.contentInset.top / 2 ;
_imageView.center = CGPointMake(scrollViewCenterX, scrollViewCenterY);
}
Here is the explanation:
You should not put the imageView in the storyboard, otherwise the frame of the imageView will be fixed by the storyboard, and will not change with the size of the image. Even if you choose UIViewContentModeScaleAspectFill, the frame of the imageView is still not changed. It just add some white space around the image.
Now the imageView has the same size as your image. If you want it to be fully displayed, you need to calculate the frame yourself.
Pay attention to the _scrollView.contentInset.top / 2, this is why you need to put the codes in viewWillAppear instead of viewDidLoad. The _scrollView.contentInset.top is the height of the navigation bar and is calculated automatically for you before willViewAppear.
You put your image view in a scrollView, I guess you want to zoom in and out. If this is true, add self.imageView = imageView; and the bottom of viewDidLoad. Set the delegate of _scrollView to self and add the following method:
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return _imageView;
}
I made a comment, but then took a look at your project. You are almost there. I ran through the following steps and have gotten the result you are looking for.
First, make sure you have auto layout turned ON!!!
In your storyboard click on your scroll view. You had a scroll view that was the same size as the view. You are going to put on some constraints. Down at the bottom of the story board you will see some icons.
The fourth one over looks sort of like an I-beam on its side, it is the pin button. After selecting the scroll view, click on this and it will bring up a pop up menu.
For the scroll view click on all the bars around the middle block so you pin the scroll view to the sides of the main view.
You will notice they are all red now.
Then go and click on the imageview. Once again you had it set to the size of the view. Using the pin button again, you are going to pin just the Width at 320 and the Height at 568. When you are done you are then going to use the next button over.
This is the align button. Click on that after you have selected your image view. You are going to click on Horizontal Center in Container, and Vertical Center in Container.
Next you will need to add one method to your ViewController.m file.
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[_scrollView setContentSize:CGSizeMake(self.view.frame.size.width, self.view.frame.size.height)];
}
Start up the simulator and let her rip! You will get one warning though. It says the content size is ambiguous for the scroll view. But that's OK, because you will set it on viewDidLayoutSubviews.
Hope that helps, or helps someone out. Autolayout and scroll views are a bit tough!!
EDIT#1
if you want to then make the image view scalable, by pinch zooming you can do the following.
Make sure you made the .h file follow the UIScrollViewDelagate.
#interface ViewController : UIViewController <UIScrollViewDelegate>
This will allow the scroll view to be able to access the delegate methods of the scroll view. The method you are looking for is called..
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}
Then in the viewDidLoad method of your .m file do the following.
_scrollView.minimumZoomScale = 0.5;
_scrollView.maximumZoomScale = 4.0;
_scrollView.delegate = self;
The underscore and the variable name is the same as self.variable. Either will work.
That should do it. Let me know if it works or if you have any other questions. ENJOY!
These are the ones u can use, the 3 modes of ImageView content display.You can do this by dynamically setting them or u can set them in storyboard too, click on the ImageView and go to properties tab-bar and choose from there, run them and select which output u want.
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.contentMode = UIViewContentModeScaleToFill;
imageView.contentMode = UIViewContentModeScaleAspectFill;
Hope this helps
If you want to center image in an imageview use
imageView.contentMode=UIViewContentModeCenter;
image retains it's size in this this content mode. Alternatively you can use other content modes as per your requirement.
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit, // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill, // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw, // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter, // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
I want to have an UIView with width=480 and height=640, centered in the middle of my master view.
I want this to happen both in landscape orientation and portrait orientation, but now if I design it for portrait orientation, when I'm turning the device to landscape, my UIView has width=640 and height=480.
Any solutions for my UIView to keep it's sizes in both orientation types?
you can implement viewDidLayoutSubviews (in UIViewController) or layoutSubviews (in UIView) to reposition the view.
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.myCustomView.bounds = CGRectMake(0, 0, 480, 640); // update size
self.myCustomView.center = self.view.center; // update center
}
I faced a strange problem, the scrollview does not scroll down, only scroll up. I have scrollview in my app, please look at my coding
.....
self.scrollView = [[UIScrollView alloc] initWithFrame: CGRectMake(0, 0, 320,427)];
[self.view addSubViews: self.scrollView];
UIView *blueView = [[UIView alloc] initWithFrame: CGRectMake(0, 47, 320, 320)];
blueView.backgroundColor = [UIColor blueColor];
[self.scrollView addSubViews: blueView];
self.scrollView.contentSize = CGSize(320, 640);
....
My problem is no matter what value I changed contentSize, my ScrollView only scroll up, not scroll down. I want user can move blueView to the top or bottom of iPhone screen from the original position.
do you have this problem?
The Problem
It looks like your issue is with how you're orienting blueView within scrollView. You're setting the frame of blueView to the CGRect (0, 47, 320, 320). When you set the frame like this, one of the things you're implicitly saying is:
The top edge of blueView is 47 points below the top edge of scrollView.
That's a perfectly valid thing to say, but it's what's causing the problem you describe. scrollView won't scroll down because it is designed to start, by default, with the rect (0, 0, 320, 480) in view. The contentSize property only indicates the size of the content within the UIScrollView, not its positioning. When you set it, you're basically telling scrollView:
Starting from your content origin, the content is 320 points wide and 640 points tall.
Thus, scrollView won't scroll up because, as far as it knows, there's no content above the coordinate (0, 0).
The Solution
There are three steps you'll need to take to get the functionality you want.
Set the contentSize to be just big enough to allow blueView to scroll all the way up and down.
Put blueView in the vertical center of scrollView.
Scroll the scrollView so that it is initially centered on blueView.
Set the contentSize to be just big enough to allow blueView to scroll all the way up and down.
We'll want to calculate the correct value of the contentSize property. It is of the type CGSize, so we need two parts: width and height. width is easy – since you don't seem to want horizontal scrolling, just make it the width of the screen, 320. Height is a little more tricky. If you want blueView to just touch the top and bottom of the screen when scrolled up or down, you need to do some math. The correct total height will be double the height of the screen, minus the height of blueView. So:
scrollView.contentSize = CGSizeMake(320, 480 * 2.0 - blueView.frame.size.height);
Put blueView in the vertical center of scrollView.
That's easy; just set the center property of blueView:
blueView.center = CGPointMake(160, scrollView.contentSize.height / 2.0);
Scroll the scrollView so that it is initially centered on blueView.
If you check the Apple UIScrollView documentation, you'll see an instance method - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated. This is exactly what you need to scroll scrollView programmatically. The rect you want is the one centered on blueView, with the size of the iPhone screen. So:
CGRect targetRect = CGRectMake(0, scrollView.contentSize.height / 2.0 - 240,
320, 480);
[scrollView scrollRectToVisible:targetRect animated:NO];
Make sure you do this scrolling in viewWillAppear, so it's ready right when the user sees the view.
That should be it. Let me know if you have any questions!
The content size of the scrollView should be the size of the view it is holding. This is how the code should be, try something like this.
self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(X, Y, W, H1)];
UIView * blueView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, W, H2)];
self.scrollView .contentSize = blueView.frame.size;
[self.scrollView addSubview:blueView];
[self.view addSubView: self.scrollView];
Thanks to Riley. Here, the H1 is the height of the UIScrollVIew and H2 is the height of the blueView and (H1 < H2).
I have a custom view with some drawing in drawRect added as subview in a UIView.On tapping on the subview I change the height of the base view.This is done by -
CGRect rect = self.bounds;
rect.size.height = 400.0;
self.bounds = rect;
This also repositions the custom view (sets it to the top of the base view) which I don't want , the subview should remain fixed at the bottom of the UIView.
Y position for the custom view is set to the height of the base view -
y = self.bounds.size.height - 40.0;
This works when the custom control is added for the first time, but does not work when the base view changes height.
I have set self.autoresizesSubviews = NO; for the base view.
If I remove the custom view from the base view and add it again after the height changes nothing is shown , just a blank base view.
Any ideas to fix the position of the custom view to the bottom of the base view.
Try to use
self.bounds = CGRectMake(0, 0, 320, 400);
It will make the bounds from top left corner to point on the right side of the screen that is 400 pixels below the initial point.
You can also try using method
-(void)layoutSubviews
I don't remember the correct syntax, but I'm pretty sure it was like that.
hope it helps
What about firing setNeedsDisplay method on that view.