I am working on a Universal Application. I have a View-based application which has one view controller. I am adding a UIImageView as a subview.
My problem is that if I put the ImageView in viewDidLoad, it is getting resized in iPad.
But if I add the ImageView to view controller dynamically on button tap event, the UIImageView is not getting resized as per iPad. Instead, it is showing ImageView with 320 x 480 dimensions.
Note: My View Controller has setAutoresizesSubviews to YES.
My code is as below:
-(void)buttonTap
{
UIImage *img = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle]pathForResource:#"main-bg" ofType:#"png"]];
UIImageView *imgViewMainBG = [[UIImageView alloc]initWithImage:img];
imgViewMainBG.frame = CGRectMake(0,0,320,480);
imgViewMainBG.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:imgViewMainBG];
[imgViewMainBG release];
[img release];
img=nil;
}
AutoresizingMask is for changing the size of all subviews according to the change in size of the superView whenever the superView's size is changed, it won't resize subviews at the time of adding a subView.
But you can find the bounds or frame of self.view and set the frame property of imageView according to that bounds like below
[imgViewMainBG setFrame:CGRectMake(0, 0, self.view.frame.size.width,
self.view.frame.size.height)];
so that imgViewMainBG is fully visible in ipad
Try changing image view's contentMode property to UIViewContentModeScaleToFill.
Related
Consider a UIScrollView with a single subview. The subview is an UIImageView with the following size constraints:
Its height must be equal to the height of the UIScrollView.
Its width must be the width of the image scaled proportionally to the height of the UIImageView.
It is expected that the width of the UIImageView will be bigger than the width of the UIScrollView, hence the need for scrolling.
The image might be set during viewDidLoad (if cached) or asynchronously.
How do you implement the above using autolayout, making as much use as possible of Interface builder?
What I've done so far
Based on this answer I configured my nib like this:
The UIScrollView is pinned to the edges of its superview.
The UIImageView is pinned to the edges of the UIScrollView.
The UIImageView has a placeholder intrinsic size (to avoid the Scrollable Content Size Ambiguity error)
As expected, the result is that the UIImageView is sized to the size of the UIImage, and the UIScrollView scrolls horizontally and vertically (as the image is bigger than the UIScrollView).
Then I tried various things which didn't work:
After loading the image manually set the frame of UIImageView.
Add a constraint for the width of the UIImageView and modify its value after the image has been loaded. This makes the image even bigger (?!).
Set zoomScale after the image is loaded. Has no visible effect.
Without autolayout
The following code does exactly as I want, albeit without autolayout or interface builder.
- (void)viewDidLoad
{
{
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:scrollView];
self.scrollView = scrollView;
}
{
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, self.scrollView.frame.size.width, self.scrollView.frame.size.height)];
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.scrollView addSubview:imageView];
self.scrollView.contentSize = imageView.frame.size;
self.imageView = imageView;
}
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self layoutStripImageView];
}
- (void)layoutStripImageView
{ // Also called when the image finishes loading
UIImage *image = self.imageView.image;
if (! image) return;
const CGSize imageSize = image.size;
const CGFloat vh = self.scrollView.frame.size.height;
const CGFloat scale = vh / imageSize.height;
const CGFloat vw = imageSize.width * scale;
CGSize imageViewSize = CGSizeMake(vw, vh);
self.imageView.frame = CGRectMake(0, 0, imageViewSize.width, imageViewSize.height);
self.scrollView.contentSize = imageViewSize;
}
I'm trying really hard to move to autolayout but it's not being easy.
Under the autolayout regime, ideally the UIScrollView contentSize is solely determined by the constraints and not set explicitly in code.
So in your case:
Create constraints to pin the subview to the UIScrollView. The constraints have to ensure the margin between the subview and the scroll view are 0. I see that you have already tried this.
Create a height and a width constraint for your subview. Otherwise, the intrinsic size of the UIImageView determines its height and width. At design time, this size is only a placeholder to keep Interface Builder happy. At run time, it will be set to the actual image size, but this is not what you want.
During viewDidLayoutSubviews, update the constraints to be actual content size. You can either do this directly by changing the constant property of the height and width constraint, or calling setNeedsUpdateConstraints and overriding updateConstraints to do the same.
This ensures that the system can derive contentSize solely from constraints.
I've done the above and it works reliably on iOS 6 and 7 with a UIScrollView and a custom subview, so it should work for UIImageView too. In particular if you don't pin the subview to the scroll view, zooming will be jittery in iOS 6.
You may also try creating height and width constraints that directly reference a multiple of the height and width of the scroll view, but I haven't tried this other approach.
translatesAutoresizingMaskIntoConstraints is only required when you instantiate the view in the code. If you instantiate it in the IB it's disabled by default
In my opinion the UIImageView should fill the ScrollView. Later I'd try setting the zoom of the scrollview to the value that suits you well so the image can only be panned in one direction
In my case it was a full width UIImageView the had a defined height constraint that causing the problem.
I set another constraint on the UIImageView for the width that matched the width of the UIScrollView as it is in interface builder then added an outlet to the UIViewController:
#property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageViewWidthConstraint;
then on viewDidLayoutSubviews I updated the constraint:
- (void) viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
self.imageViewWidthConstraint.constant = CGRectGetWidth(self.scrollView.frame);
}
This seemed to do the trick.
I have a ViewController with a UIScrollView and 3 subviews.
I've declared the size of the UIScrollView to have the 3 views by horizontal scrolling.
I'm trying to draw a new image on top of each sub view and when the view will be scrolled I would like that the new image will be scrolled with the subview.
Right now, I managed to draw the new image, but it remains static even when I scroll the views.
x = [button frame].origin.x;
y = [button frame].origin.y;
check = [[UIImageView alloc] initWithFrame:CGRectMake(x+100,y+100, 20, 20)];
check.image = [UIImage imageNamed:#"check.png"];
[self.view addSubview:check];
Don't draw it in your scroll view. Draw it in your custom UIImageView subclass. Or add subviews to your image views.
I have a UIImageView aSuper; This view is changing its sizes when i flip it i.e. it is taking sizes of next frame and next frame and so on.
Now this UIImageView contains a subview which is also imageview. I will call it bSubView.
Now i want to resize this bSubView every time its parent's view frame changes.
Code is :- Here invisibleView is subview and viewHolder is parent view. parent view is changing right but problem is with subview.
UIImage *image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageString1]]];
UIImageView *viewHolder=[[UIImageView alloc] initWithFrame:CGRectMake(510, 200, 20, 20)];
invisibleView=[[UIImageView alloc] init];
invisibleView.image=image;
invisibleView.frame=viewHolder.bounds;
viewHolder.autoresizesSubviews=YES;
[ invisibleView setAutoresizingMask:UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight];
invisibleView.contentMode=UIViewContentModeCenter;
viewHolder.image=[UIImage imageNamed:#"EmptyPlanet"];
[viewHolder addSubview:invisibleView];
[self.view addSubview:viewHolder];
Many Thanks in advance.
you can use the inherited method -(void)layoutsubviews
This method is called on the super view when its frame changes. In that method you can configure your subviews
Another option is to use autolayout when configuring the subviews.
I was wondering what was the real meaning of using initWithFrame with this scrollView, because we also set the dimensions of the scrollView after that, and we add the scrollView as a subView of the view.
So why do we need to specify this initWithFrame? I actually don't really understand it when the frame is self.view.frame (I would understand it better if we set a different rectangle, such as 0,0 50,50)
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
scrollView.contentSize = CGSizeMake(847, 1129);
UIImageView *imageView = [[UIImageView alloc] initWithImage: image];
[scrollView addSubview:imageView];
[self.view addSubview:scrollView];
Thanks
self.view in this case is the view containing the scrollview, so the scrollview fills the entire view when set to self.view.frame. Frame and content size are different things - frame of scrollview defines visible part of scrollview, and content size defines the size of scrollable (zoomable) content inside your scrollview.
I am an new user of Objective-c. I have a problem to load imageview to scrollview.
I use interface builder to add a scrollview onto view. and then I try to add an imageview on the scrollview by code.
UIImage *image = [[[UIImage alloc]init]autorelease];
image = [UIIamge imageNamed:#"cover.jpg"];
imageView = [[[UIImageView alloc]init]autorelease];
imageVIew.frame = CGRectMake(50.0, 40.0, 200.0,200.0);
imageView.image = image;
[scorllView addSubview:imageView];
then I add another imageView onto the ScrollView with position at (50.0,1000.0)
and length = 200, width = 200 (the screen of ipad is 786*1004)
the photos can appear on the screen. The second photo is not complete, and I try to scroll the screen, however I can't scroll it.
Thanks.
first, you only need
UIImage * image = [UIImage imageNamed:#"cover.jpg"];
class methods(imageNamed: here) that creates the instance of it other than "alloc" would create a autoreleased object.
[UIImage imageNamed:#"cover.jpg"]
is conceptually identical to
[[UIImage alloc] initWithFileContents:#"cover.jpg"] autorelease] // note, alloc once, release once.
(it may not be identical internally, imageNamed: caches the image initWithFileContents: might not)
In order to scroll the scrollView,
there are many things you need to make sure.
One of it is to make sure your scrollView's contentSize is bigger than your scrollView's frame size.
try setting your scrollView.contentSize = CGSizeMake(someBigValue, someBigValue);
The content inside scrollView scrolls inside the scrollView. So your content should be bigger than scrollView's frame size to scroll.
you have to increase contentinset or UIScrollview to make it scrollable,
You can increase bottom,
scorllView.contentInset = UIEdgeInsetsMake(0, 0, 680, 0);
or increase as you need