Not able to get the right size in auto-layout using systemLayoutSizeFittingSize - ios7

I have a button which is designed in a UIView with 600, 600 size (any, any). The button is located at (40,40) and is of size (520, 80). The button is displayed in iPhone 4.0 retina display (320 x 568).
In viewWillAppear, I am getting the width of the button using the following code:
NSLog(#"%f", self.fullgameButton.frame.size.width); // returns 520.
In viewWillAppear, I am getting the size using systemLayoutSizeFittingSize:
CGSize size = [self.fullgameButton systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; // returns 403.
In viewDidAppear, I am getting the size of the button:
NSLog(#"%f", self.fullgameButton.frame.size.width); // returns 240.
When I get the size using systemLayoutSizeFittingSize, I am expect the button to return a width of 240. But, it is giving me an unusual value of 403. Any reason why I am getting such a value?

Related

iOS6 contentInset in UIWebview behaves differently from iOS7

I attempt to add spaces in Webview so the content fits the webview nicely like implementing UIViewContentModeScaleAspectFit. The webview's superview is fixed with 320 * 200, and the webview's content size varies but are small enough to fit in the size. Everything works fine except when using iOS 6.
float verticalInset = (self.frame.size.height - fitSize.height) / 2;
float horizontalInset = (self.frame.size.width - fitSize.width) / 2;
wv.scrollView.contentInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset);
wv.center = self.center;
fitSize is correctly calculated, because if i just set webview's frame to the size, the content fits perfectly. However, that won't fill up its superview when zoomed in.
It seems like when I change the contentInset in iOS 6 it doesn't resize its content to fit the result frame (frame - inset); but iOS 7 does resize it. Is there any solution to fix this difference?

iPhone 5 views not resizing to correct width

I do not use auto layout and I set all my views to autoresize their subviews.
My subviews will not get the correct width and I do the following hack:
- (void)awakeFromNib {
if([CEDeviceUtils isPhone5])
{
NSUInteger width = [CEViewUtils windowSize].width;
if(width != 568) width = 568;
[CEViewUtils sizeView:self atWidth:width];
}
}
isPhone5, windowSize and sizeView are just some utility methods that I use and their implementation is not important for my question.
I do not like having to use this hack and I must be missing something. Any clues on how to fix this issue?
Thanks!
The 4" Retina display has a 320 x 568 effective resolution, with the 568 pt being the height. I'm assuming you're using a landscape orientation by the fact that you're checking if the width property is 568, but are you sure your [CEViewUtils windowSize].width isn't returning the 320 pt width of the device in the default portrait orientation? You should probably just be looking at the height property regardless of the current state of device rotation.
Also, it can't hurt to check that your isPhone5 method is actually returning the correct value; throw an NSLog() or breakpoint in your code to make sure control reaches where you expect it to. (Same goes for the awakeFromNib method -- make sure it's getting called when you expect it to be. You may need to move this code into the viewWillAppear or viewDidAppear methods, which are called after the view metrics have been established, so you can override them.)

Problems scaling a UIImage to fit a UIButton

I have a set of buttons and different sized images. I want to scale each image in order that it fits the button in the correct aspect ratio. Once I've scaled the image, I set the button's image property to the scaled version.
UIImage *scaledImage = [image scaledForButton:pickerButton];
[pickerButton setImage:scaledImage forState:UIControlStateNormal];
my scaledForButton method is defined in a class extension for UIImage. It looks like this:
- (UIImage *)scaledForButton:(UIButton *)button
{
// Check which dimension (width or height) to pay respect to and
// calculate the scale factor
CGFloat imageRatio = self.size.width / self.size.height;
CGFloat buttonRatio = button.frame.size.width / button.frame.size.height;
CGFloat scaleFactor = (imageRatio > buttonRatio ? self.size.width/button.frame.size.width : self.size.height/button.frame.size.height);
// Create image using scale factor
UIImage *scaledimage = [UIImage imageWithCGImage:[self CGImage]
scale:scaleFactor
orientation:UIImageOrientationUp];
return scaledimage;
}
When I run this on an iPad2 it works fine and the images are scaled correctly. However if I run it on a retina display (both in the simulator and on a device) the image does not scale correctly and is squished into the button.
Any ideas why this would happen on retina only? I've been scratching my head for a couple of days but can't figure it out. They're both running the same iOS and I've checked the scale and ratio outputs, which are always the same, regardless of device. Many thanks.
Found the answer here: UIButton doesn't listen to content mode setting?
If you're setting the .contentMode, it seems you have to set the imageView property of the UIButton, not just the UIButton, then it worked properly.
The problem on iPad 3 was as Herman suggested - the CGImage was still a lot larger than the UIButton, so even though it was scaled down, it still had to be resized to fit the button.

SetFrame works on iPhone, but not on iPad. Auto resize mask to blame?

I'm trying to resize a UITextView when the keyboard shows. On iPhone it works beautifully. When the the system dispatches a keyboard notification, the text view resizes. When it's done editing, I resize it to fill in the initial space. (Yes, I'm assuming the keyboard is gone when the editing stops. I should change that. However, I don't think that's my issue.)
When I resize the textview on the iPad, the frame resizes correctly, but the app seems to reset the Y value of the frame to zero. Here's my code:
- (void) keyboardDidShowWithNotification:(NSNotification *)aNotification{
//
// If the content view being edited
// then show shrink it to fit above the keyboard.
//
if ([self.contentTextView isFirstResponder]) {
//
// Grab the keyboard size "meta data"
//
NSDictionary *info = [aNotification userInfo];
CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
//
// Calculate the amount of the view that the keyboard hides.
//
// Here we do some confusing math voodoo.
//
// Get the bottom of the screen, subtract that
// from the keyboard height, then take the
// difference and set that as the bottom inset
// of the content text view.
//
float screenHeightMinusBottom = self.contentTextView.frame.size.height + self.contentTextView.frame.origin.y;
float heightOfBottom = self.view.frame.size.height - screenHeightMinusBottom;
float insetAmount = kbSize.height - heightOfBottom;
//
// Don't stretch the text to reach the keyboard if it's shorter.
//
if (insetAmount < 0) {
return;
}
self.keyboardOverlapPortrait = insetAmount;
float initialOriginX = self.contentTextView.frame.origin.x;
float initialOriginY = self.contentTextView.frame.origin.y;
[self.contentTextView setFrame:CGRectMake(initialOriginX, initialOriginY, self.contentTextView.frame.size.width, self.contentTextView.frame.size.height-insetAmount)];
}
Why would this work on iPhone, and not work on iPad? Also, can my autoresize masks be making an unexpected change?
Like said #bandejapaisa, I found that the orientation was a problem, at least during my tests.
The first thing, is about the use of kbSize.height being misleading, because in Landscape orientation it represents the width of the keyboard. So, as your code is in a UIViewController you can use it this way:
float insetAmount = (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)?kbSize.height:kbSize.width) - heightOfBottom;
The self.interfaceOrientation gives the orientation of the Interface (can be different from the Device orientation) and the macro UIInterfaceOrientationIsPortrait returns YES if the given orientation is Portrait (top or bottom). So as the keyboard height is in the kbSize.height when the interface is Portrait, and in the kbSize.width when the interface is Landscape, we simply need to test the orientation to get the good value.
But that's not enough, cause I've discovered the same problem with the self.view.frame.size.height value. So I used the same workaround:
float heightOfBottom = (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)?self.view.frame.size.height:self.view.frame.size.width) - screenHeightMinusBottom;
Hope this helps...

UILabel text overrun in custom tableCell

I have a weird problem in a custom UITableCell subClass.This custom cell has a pair of UILables that are multi-line and can contain varying amounts of text (up to 2000 characters). The custom tableCell has a layout method where I am calculating their frame's height using the code below, taking the device orientation into account:
if (isPortrait) {
presentationTextLabelSize = [presentationTextStr sizeWithFont:[UIFont systemFontOfSize:12.0f] constrainedToSize:CGSizeMake(portraitDescriptionWidth, 2000.0f) lineBreakMode:UILineBreakModeWordWrap];
presentationTextLabelRect = CGRectMake(60.0f, 25.0f, portraitDescriptionWidth, presentationTextLabelSize.height);
} else {
presentationTextLabelSize = [presentationTextStr sizeWithFont:[UIFont systemFontOfSize:12.0f] constrainedToSize:CGSizeMake(landscapeDescriptionWidth, 2000.0f) lineBreakMode:UILineBreakModeWordWrap];
presentationTextLabelRect = CGRectMake(60.0f, 25.0f, landscapeDescriptionWidth, presentationTextLabelSize.height);
}
self.presentationTextLabel.frame = presentationTextLabelRect;
I have the label's autoResizeMask set as follows:
self.presentationTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin;
I use the same calculation in the UITableViewController to set the row height.
Everything works perfectly, the label is sized to the correct height for it's width, and the cell autoResizes on device rotation, except that when the device is rotated to landscape the label's text sometimes extends out of the label's frame to the right, clear past the edge of the tableView. If I scroll the cell out of view and back again it's back to normal. I am logging the cell's width to the console, and it is correct, yet the text extends far past that width.
Any ideas what's joing on?
Thanks
The problem is, the tableView is not reloaded when the device is rotated to landscape. So, there is mismatch in updating the texts. Use [tableView reloadData]; at the place, where you find the device is changed to landscape mode.