I have tried several different solutions to this problem with no success.
I have a UIImageView (created on the Storyboard) that has multiple Gesture Recognizers on it. I have trying to resize this UIImageView based on screen size to take advantage of the 4 inch display.
It appears that since the Imageview was built using the storyboard, I can't change it programmatically???
My current code looks like this:
//determine screen size, set scoring button width based on device size.
CGFloat lCurrentHeight = self.view.bounds.size.height;
if (lCurrentHeight == 568.0) {
CGRect _redHeadImageFrame = _redHeadImage.frame;
_redHeadImageFrame.size.width = 220;
[_redHeadImage setFrame:_redHeadImageFrame];
}
Any ideas??? Thanks.
If you are using autolayout you have to change withConstraint of the image, because manual changing of the frame will not work in this case.
EDIT
You can create IBOutlet for the width constraint as you do it for other controls - just select constraint in IB and move it with right button to your header file. Than in code change constraint:
[self.imageWidthConstraint setConstant:100.0];
yes you need to use like this,
CGFloat lCurrentHeight = [[UIScreen mainScreen] bounds].size.height; //it will give 568
CGFloat lCurrentHeight = self.view.bounds.size.height;//it will give 548,in your case that condition failed.
There's no difference in resizing UIViews created by code or by the storyboard. It's exactly the same: setting the frame of the view, as you are doing.
What might be happening:
Your if condition it's never true. Have you checked with a breakpoint if the code inside it is even called? Maybe there's some error in the float direct comparation. See this.
Also, see this for a better understanding on how to check if it's 4 inch display.
If the setFrame: code is actually called, check if you are using auto-layout in your view. Maybe there's a constraint in the UIImageView. In this case, you should play with this constraint, in order to resize the view correctly..
Related
I'm switching to autolayout and I'd like to position views relatively to height of device. How should I setup constraints to satisfy such condition.
I have nice layout for iPhone 5 but for iPhone 6Plus I'd like to move "red" to position of "gray":
All my current constrains:
One idea might be to place the username, password and login items on a uiView with a clearBackground and then create a constraint for that view and its superview and create an outlet to it. You could then detect which phone you are using in code and modify the constraints programatically in willLayoutSubviews.
if ((int)[[UIScreen mainScreen] bounds].size.height == 736)
{
// This is iPhone 6+ screen
myConstraint.constant = 150;
} else if ((int)[[UIScreen mainScreen] bounds].size.height == 568) {
// This is iPhone 5s screen
frameRateLabelHeightConstraint.constant = 100;
}
There will be a better way to do this in Autolayout no doubt but I do find it a bit confusing so I have used this method in the past.
Here is a sample project uploaded # One Drive. Here are the sample outputs on various versions of iPhone Simulators...
As I see you want to put your form to the center of view. So I think the best solution will be to put your form elements on another transparent view and add to this view centerX aligment constraint and centerY aligment constraint.
you can check another way here
I have an xib which its content is like this:
The orange view is view_b which is an UIView containing a UITextField, while the UITableView is tblv_a. And view_content is UIView that containing the two views.
What I want to accomplish is to resize the view_content's and its subviews' sizes whenever the keyboard is showing, i.e. while the user is editing in the UITextField. And I tried to do this with the following codes in keyboardDidShow::
NSDictionary* info = [notification userInfo];
CGRect kbRect = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGRect convertContentRect = [self.view convertRect:CGRectFromString(str_contentViewRect) toView:self.view];
CGRect coverRect = CGRectIntersection(kbRect, convertContentRect);
self.view_content.frame = CGRectMake(CGRectFromString(str_contentViewRect).origin.x, CGRectFromString(str_contentViewRect).origin.y, CGRectFromString(str_contentViewRect).size.width, CGRectFromString(str_contentViewRect).size.height - coverRect.size.height);
self.tblv_a.height = self.view_content.height - self.view_b.height;
self.view_b.y = self.tblv_a.y_height;
However, when I try the result with simulator, it didn't work as expected, instead, it gives the following result:
After trying to figure out what's wrong, I tried to disable autolayout in interface builder, then it works as expected, which is:
I didn't set any constraints on the views, and I checked about the frames of the views and they seem correct. So I guess autolayout is the source of the problem, but I have no idea why this is happening, can anyone help?
And if I want to enable autolayout to deal with different screen sizes, how should I solve this?
Thanks!
(view_content's background color is light gray, while tblv_a is clear color)
If auto layout is on, then the system will add default constraints if you don't add your own. When constraints are in place, you shouldn't set any frames. If you need to move or resize a view, you need to do it by changing the constraints.
In Xcode 5 I have created a universal app, with a UIScrollView containing an UIImageView (here fullscreen):
Since I've set all UI properties in the Interface Builder (the image to be displayed, the UIImageView dimensions of 1000 x 1000 pixels and the UIImageView Mode set to "Scale To Fill"), the actual source code in the ViewController.m is very short:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
/*
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
_imageView.frame = CGRectMake(_imageView.frame.origin.x,
_imageView.frame.origin.y,
800, 800);
}
*/
_scrollView.contentSize = _imageView.bounds.size;
NSLog(#"%s: _scrollView %# %#",
__PRETTY_FUNCTION__,
NSStringFromCGPoint(_scrollView.frame.origin),
NSStringFromCGSize(_scrollView.frame.size));
NSLog(#"%s: _imageView %# %#",
__PRETTY_FUNCTION__,
NSStringFromCGPoint(_imageView.frame.origin),
NSStringFromCGSize(_imageView.frame.size));
}
This works surprisingly (for me as iOS newbie) well in iPhone and iPad - and the app can even be rotated.
However the image displayed for iPhone is a bit too large and needs to be scaled down for more comfortable playing:
I was hoping, that since the UIImageView Mode is "Scale To Fill", I would just need to change its frame (or bounds? I've tried both) - as in the commented code shown above.
But this doesn't work - the scrolling breaks (can't scroll to the image bottom anymore).
Any advice please?
(I also hope to add a pinch and double tap gesture recognisers later - and scale the UIImageView in them as well).
UPDATE:
I've tried following Andrei's suggestion (thanks!) by adding the following code to the viewDidLayoutSubviews, but the image hasn't scaled down:
if (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPad) {
_scrollView.maximumZoomScale = 1.2;
_scrollView.minimumZoomScale = .8;
_scrollView.zoomScale = .8;
}
UIScrollView can handle the zooming for you, together with pinch gestures.
You just need to set the proper values in "minimumZoomScale" and "maximumZoomScale" properties, and it will let the user pinch between those limits.
You also need to implement the
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView
method from UIScrollViewDelegate. It should just return the imageView.
You can also set the zoom level using the "zoomScale" property.
For double tapping you need to add your own double tap gesture recognizer to the scrollview and increase the zoom level when a double tap occurs.
Updated with delegate method and double tap gesture.
You must definitely read about AutoLayout. You cannot go changing frames and bounds if AutoLayout is turned on. You can of course turn it off for the whole Storyboard.
The solution to your problem are constraints. With them you define how your views are related, for example: how your UIScrollView is related to it's parent view and how UIImageView is related to your UIScrollView.
Read more about constraints on links below:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/AutolayoutPG/Introduction/Introduction.html
http://www.raywenderlich.com/50317/beginning-auto-layout-tutorial-in-ios-7-part-1
While UIScrollView can handle zooming with pinching for you, you must implement correct delegate method: viewForZoomingInScrollView:. And of course you must set correct property values for minimumZoomScale and maximumZoomScale.
More information on the following links:
https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/UIScrollView_pg/ZoomZoom/ZoomZoom.html
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
Both sites have enough information and examples for you to be able to do this. First experiment with the code available on those sites and then post another more specific question, if you encounter a problem.
I'm trying to aligning a container UIView to the bottom of the screen in such a way it always is at the bottom of any device whatever the resolution or height is but I can't figure out how to do this via the storyboard.
Any insight is appreciated. Thanks a lot!!!
You have to make a vertical constraint between your view and its container view with a constant of your desired space between the views.
One way via IB is to CTRL-Drag from your view to the container view and select bottom space to bottom layout guide.
Make sure to check the constant after creating the layout constraint to have the correct value since ib will use the current distance for the two views.
Use autolayout (official documentation), or you can do this:
// Assuming you want to move a UIView *foo
CGFloat screenHeight = [[[[UIScreen mainScreen] bounds] size] height];
CGRect newFrame = foo.frame;
newFrame.origin.y = screenHeight - foo.frame.size.height;
foo.frame = newFrame;
With autolayout:
In this picture, in the top most part of the pop up dialog, the drop down menus with the numbers will let you choose what to set the constraint relative too. Try this.
Sorry for the bother but I'm trying to lazy load several imageViews and then resize it proportionately to the content in a UITableView. I'm also trying (Unwisely perhaps?) to use Autolayout basically for the first time. And I'm not understanding why the constraints aren't working in this case. Here's the code that I'm using to resize the UIImageView after I've loaded the proper image into it.
// Scale the image view and return it.
- (UIImageView *) scaleImageViewForScreenWidth:(UIImageView *)imageView {
UIImage *imgFromView = [imageView image];
CGRect newFrame = CGRectMake(0, 0, imgFromView.size.width, imgFromView.size.height);
float imgFactor = newFrame.size.height / newFrame.size.width;
newFrame.size.width = [[UIScreen mainScreen] bounds].size.width;
newFrame.size.height = newFrame.size.width * imgFactor;
[imageView setFrame:newFrame];
return imageView;
}
As far as constraints are concerned. I'm trying to attach a Label and UIImageView with a shadow to the bottom of the main imageview. Here are the constraints that I'm applying to a bottom shadow in the imageview. The bottom shadow constraints are:
Height Equals: 83
Align Bottom to: Background Image View
LeadingSpace to: Table View Cell
I'm not getting what I want though. Any ideas? I feel like I'm fighting autolayout.
As requested! Here's some guidelines for using Autolayout that should help a lot.
The first thing is that the ideal approach is for you to set things up in Interface Builder so that no further programming is required. So, if - for example - the bounds of your view change, then your view will adjust itself automatically as required.
If that doesn't do the business, then you may have to update the constraints programmatically. Now, the golden rules as I mentioned is that you update the constraints. Resist the temptation to update the underlying UIView frame!
So, you'll do something like:
_myWidthConstraint.constant = 300.f;
The next thing to note is that you should do this in a specific place, and that is in your UIView subclass method updateConstraints:
- (void)updateConstraints
{
[super updateConstraints];
_myWidthConstraint.constant = 300.f;
}
How do you trigger that? By invoking:
[self setNeedsUpdateConstraints];
Hope this helps! For further info check Ole Begemann's excellent article 10 Things You Need To Know About Cocoa Autolayout.
Don't forget the WWDC videos. These are essential!
Also, now there's a book iOS Auto Layout Demystified . Although I've bought it, I haven't had a chance to read it yet. It does look pretty good though.
I was also facing the same issue. the image inside the imageview was too big for the imageview and the contentMode was set to AspectFill.
I solved this by unchecking 'Autoresize Subviews".