Manually rotate and resize UILabel on orientation change - ios

In my previous question I shared my problem with the black background appearing in my app on orientation change: Black background when view rotates on orientation change
I did not manage to solve the problem by following any of the advices I got and I have the feeling that the only way I can avoid the black background is by manually rotating my subviews on orientation change?
One of my subviews is a UILabel which is supposed to cover the entire screen. The rotation is going pretty well using a line of code similar to this one:
myLabel.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(isLandscape ? 90 : 0));
My problem is to make the UILabel adjust to take up the entire screen in landscape mode as well. I have tried to switch height and width of its bounds, but nothing happens.
Any suggestions will be greatly appreciated.
Here are some more code details:
[UIView animateWithDuration:0.5
animations:^{
myLabel.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(isLandscape ? 90 : 0));
}
completion:^(BOOL finished) {
myLabel.bounds = CGRectMake(0, 0, [self screenWidth], [self screenHeight]);
CGFloat fontSize = ((isLandscape ? 0.9649 : 0.9375) * [self screenWidth]) / 2.74;
[myLabel setFont:[UIFont fontWithName:FontName size:fontSize]];
}
];
where
- (CGFloat) screenWidth {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
return isLandscape ? MAX(screenSize.width, screenSize.height) : MIN(screenSize.width, screenSize.height);
}
- (CGFloat) screenHeight {
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
return isLandscape ? MIN(screenSize.width, screenSize.height) : MAX(screenSize.width, screenSize.height);
}

Perhaps you are calling sizeToFit on the label somewhere?
Try instead to set:
myLabel.adjustsFontSizeToFitWidth = YES;
myLabel.minimumFontScale = 0.1;
This will adjust your labels font size to fit the width of label.

I found out that I was able to adjust the label size once I unchecked the auto layout checkbox.

Related

How to make the scrollview scrollable in reduced view area when keyboard appears

I have embedded all my views in a UIScrollView from xib. The scrollview contents cover all screen below status bar. Now when the textfield is tapped, I am able to move the scrollview little up. But I want it to be completely scrollable till the bottom most view is also visible above the keyboard. Also when the scrollview is scrolled till top , it should come to normal original positions. Hence, Overall I want a completely scrollable functionality like mentioned above for my scrollview.
I am done with following tricks but with no luck:
Trick 1: Change the height of the scrollview so that the content is more than scrollview height and hence the view is scrollable:
-(void)keyboardWillAppear:(NSNotification *)sender
{
CGFloat y_offset=0;
if([UIScreen mainScreen].bounds.size.height == 480){
y_offset = 80;
} else {
y_offset = 70;
}
NSDictionary* userInfo = [sender userInfo];
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
keyboardHeight = keyboardEndFrame.size.height;
[UIView animateWithDuration:0.5f animations:^{
[self.view setFrame:CGRectMake(0, - y_offset, self.view.frame.size.width, self.view.frame.size.height)];
}];
[self.loginScrollView setFrame:CGRectMake(self.loginScrollView.frame.origin.x, self.loginScrollView.frame.origin.y, self.loginScrollView.frame.size.width, [UIScreen mainScreen].bounds.size.height - keyboardHeight)];
}
-(void)keyboardWillDisappear:(NSNotification *)sender
{
[UIView animateWithDuration:0.5f animations:^{
[self.view setFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
}];
[self.loginScrollView setFrame:CGRectMake(self.loginScrollView.frame.origin.x, self.loginScrollView.frame.origin.y, self.loginScrollView.frame.size.width, [UIScreen mainScreen].bounds.size.height)];
}
Trick 2: As per other suggestions, I changed the contentInset of the UIScrollView.
In keyboardWillAppear method I added following code:
CGSize kbSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height+100, 0.0);
self.loginScrollView.contentInset = contentInsets;
self.loginScrollView.scrollIndicatorInsets = contentInsets;
and in keyboardWillDisappear method I set the contentInset back to zero values.
Hence, let me know if there needs to be any other way to sort this out or any other possible changes I need to make in scrollview frame. Moreover , if I turn on the bouncesVertically functionality it is able to bounce even when complete subviews are visible onscreen which I don't want. So basically I want it to freeze when keyboard is not there and scrollable till viewable area when it is up. Hence, give me any other suggestions? Thanks in advance.
From a conceptual point of view when "scrollView Size == scrollView ContentSize", it does not scroll. To make it scrollable we need to increase the contentSize. In your problem you need to adjust the contentSize of scrollView along with frame. This can be done in your first approach.
As for the second approach, changing the edge insets will create a sort of padding for the content drawable area. This can make the bottom content visible, but it won't affect the contentSize, hence view will not be scrollable.
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField:textField up:YES];
}
-(void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField:textField up:NO];
}
-(void)animateTextField:(UITextField*)textField up:(BOOL)up
{
const int movementDistance = -60; // change this size if you need
const float movementDuration = 0.3f; // change this size if you need
int movement = (up ? movementDistance : -movementDistance);
[UIView beginAnimations: #"animateTextField" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
it is useful for me
I can really recommend this library:
https://github.com/michaeltyson/TPKeyboardAvoiding
It's very very easy to use, and works for ScrollView, TableView and CollectionView!

How to I resize an ImageView in the ViewDidLoad?

I have an imageView that is resized in two different parts of my code. This works great in my textFieldDoneEditing. However, when I use the same code in my viewDidLoad, I get a different sized view. Is there a difference with doing this in the that method?
Here's the code:
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGRect frame = CGRectMake(0,0, screenWidth, screenWidth);
PuzzleImage.frame = frame;
Thank you
If your ViewController is landscape mode, viewDidLoad always gets main screen's bounds in portrait mode.
So, solution is setFrame in viewWillAppear to get right bounds.

Incorrect size of a textview frame (self.textview.frame.size.height)

I want to change the height of a textview depending on its content. I created the method to resize its view. The first time I call this view controller it resize properly (height = 253) but not the other times (height = 296).
I tried resizing it from viewDidAppear, viewWillAppear and viewDidLoad. The first time viewDidAppear and viewDidLoad are called. Second and following times all methods (viewDidAppear, viewWillAppear and viewDidLoad) are called. I don't know the reason and I don't know why this weird behavior, any clue?
-(void) setHeight
{
NSLog(#"Set height");
CGRect frame = descriptionTextView.frame;
frame.size.height = descriptionTextView.contentSize.height;
descriptionTextView.frame = frame;
NSLog(#"height: %f", descriptionTextView.frame.size.height);
if([[UIScreen mainScreen] bounds].size.height == 568) //iPhone 4inch
{
totalHeight = 380+frame.size.height;
[self.mainScrollView setContentSize:CGSizeMake(320,totalHeight)];
}
else{
totalHeight = 250+frame.size.height;
[self.mainScrollView setContentSize:CGSizeMake(320,totalHeight)];
}
}
I use autolayout in my project but not for this view since I dont know how to properly resize a textview inside a scrollview (which also includes 2 more views with labels, images and buttons) based on the textview content with autolayout. Is it better to use autolayout than this function? Perhaps you can help me with the constraints...
You are changing only the scroll size according to your calculation but you are missing to change the size of text view itself. After setting scroll view content size update the size of the text view and all should be fine (contentSize and frame). This may look like:
[descriptionTextView setContentSize:CGSizeMake(CGRectGetWidth(descriptionTextView.frame),totalHeight)];
CGRect frame = descriptionTextView.frame;
frame.size.height = totalHeight;
[descriptionTextView setFrame:frame];
By the way: in the if-statement you can only calculate totalHeight and set it afterwards.
Additionally you do not need this line:
frame.size.height = descriptionTextView.contentSize.height;
Try this:
CGSize constraintSize;
constraintSize.height = MAXFLOAT;
constraintSize.width = yourTextView.frame.size.width;
NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:#"yourFontName" size:yourFontSize], NSFontAttributeName,
nil];
CGRect frame = [yourTextView.text boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributesDictionary
context:nil];
// Use this frame for your textview

How to drawrect paintcode content centre horizontal on landscape iOS on retina iPad?

I'm getting in a bit of a muddle trying to draw some paintcode graphics code in the middle of the screen horizontally.
I'm really not sure if scale or landscape orientation affects this.
I've created a UIView subclass and addSubview in viewDidLoad like so...
MenuTitleView *fancyView = [[MenuTitleView alloc] initWithFrame:self.view.bounds];
[[self view] addSubview:fancyView];
Rather than the size PaintCode gave me...
CGRect textRect = CGRectMake(0, 0, 418, 129);
I'm trying to determine the screen / view width and the size of the canvas width.
I've tried various things without success.
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGFloat w = screenRect.size.width;
CGFloat width = 500;
CGFloat height = 200;
CGFloat x = (w - width) * 0.5f;
CGFloat y = 20;
CGRect textRect = CGRectMake(x, y, width, height);
Scale is not an issue, because Quartz and UIKit now work in 'points' rather than in pixels, so that's already accounted for. However orientation is not, [UIScreen mainScreen] will return the same rect either for applicationFrame or bounds etc, it's oblivious to orientation.
I like to put a solution in a category on UIView or UIViewController, because you'll reuse it plenty. something like this...
-(CGRect )workingCanvas{
CGRect screenRect = [UIScreen mainScreen].bounds;
BOOL landscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
CGRect result = CGRectZero;
CGFloat lesserDimension = (screenRect.size.width < screenRect.size.height) ? screenRect.size.width : screenRect.size.height;
CGFloat greaterDimension = (screenRect.size.width > screenRect.size.height) ? screenRect.size.width : screenRect.size.height;
result.size.width = (landscape) ? greaterDimension : lesserDimension;
result.size.height = (landscape) ? lesserDimension : greaterDimension;
if ([[UIApplication sharedApplication]isStatusBarVisible]){
result.size.height -= [[UIApplication sharedApplication]statusBarFrame].size.height;
}
return result;
}
if you want to position your view just in the middle of the screen try this
CGRect screenRect = [[UIScreen mainScreen] applicationFrame];
CGFloat width = 500;
CGFloat height = 200;
CGFloat x = CGRectGetMidX(screenRect);
CGFloat y = 20;
CGRect textRect = CGRectMake(x, y, width, height);
already tested is working
Good Luck!!

Rotate UIImageView inside UIScrollView issue

I have to implement the rotate works like the photo app. Having the UIImageView inside a UIScrollView. and when device rotate, I want the image to rotate to landscape like Photo's. If the image is landscape-one, then it will fill the whole UIScrollView's width with the rotation animation. When the following code
[UIView animateWithDuration:0.36
animations:^(void){
[_imageView setTransform:CGAffineTransformMakeRotation(M_PI*90/180)];
_imageView.frame = CGRectMake(0, 0, 480, 320); //set the frame after the rotate
self.contentSize = CGSizeMake(480, 320); //set the content-size of the scrollview
}
completion:^(BOOL complete){
}];
But this does not work. rotate happens, but the position of the _imageView is not correct, or the image did not fill the width. Even I change the order frame and content-size before transform, still not correct.
What will be the correct approach to have this?
The WWDC 2010 Video: Designing Apps with Scrolls Views shows you exactly how to do this.
The correct answer, in my opinion, is to not animate the rotation yourself at all.
If you work according to the latest iOS 6 guidelines, then you just rearrange your views in the ViewController its layoutSubviews() method.
The source code that #CoDEFRo refers to is similar to the following, but here I've put it into the UIScrollView's delegate method scrollViewDidScroll:.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGSize boundsSize = scrollView.bounds.size;
CGRect frameToCenter = self.imageView.frame;
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
self.imageView.frame = frameToCenter;
}

Resources