Uitextfield and UIImageView are overlapping when orientation change - ios

I want to display a warning bubble when user enters an invalid email. I can successfully show the bubble but while bubble is present if orientation changes bubble overlaps with uitextfield
View start as Landscape:
Orientation becomes Portrait:
Other way around:
View start as Portrait:
Orientation becomes Landscape (bubble goes further away)
My CODE:
//image for warnings
//get screen size
CGRect screenRect = [[UIScreen mainScreen] bounds];
float bubleOriginx;
//detect device orientation
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
if(orientation == UIInterfaceOrientationLandscapeLeft || orientation== UIInterfaceOrientationLandscapeRight)
{
bubleOriginx=screenRect.size.width*0.95;
}else
{
bubleOriginx=screenRect.size.width*0.72;
}
UIImage *bubble = [[UIImage imageNamed:#"create event button.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(15, 21, 15, 21)];
self.emailImage = [[UIImageView alloc] initWithImage:bubble];
self.emailImage.frame = CGRectMake(bubleOriginx, self.email.frame.origin.y+28, 0, 0);
UILabel *xlabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
xlabel.font = [UIFont fontWithName:#"Helvetica" size:15.0];
xlabel.text = string;
xlabel.numberOfLines = 0;
CGSize labelSize = [xlabel.text sizeWithFont:xlabel.font
constrainedToSize:xlabel.frame.size
lineBreakMode:xlabel.lineBreakMode];
xlabel.frame = CGRectMake(
xlabel.frame.origin.x, xlabel.frame.origin.y,
xlabel.frame.size.width, labelSize.height);
[xlabel setBackgroundColor:[UIColor clearColor]];
[self.emailImage addSubview:xlabel];
self.emailImage.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
[self.view addSubview:self.emailImage];
[UIView animateWithDuration:0.85
animations:^(void) {
self.emailImage.frame = CGRectMake(bubleOriginx, self.email.frame.origin.y+28, 220, -60);
xlabel.frame = CGRectMake(10, 0, 210, 60);
} completion:^(BOOL finished) {
}];
How can I stable that UIImageview so it wont overlap? Lets say it will always stay +30 points away from the end point of uitextfield or at least wont overlap.
Thanks,
Mord

This is because of the autoResizingMask
self.emailImage.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin;
Keep UIViewAutoresizingFlexibleRightMargin; (Wont behave the way you expect though)
But setting origin.x on orientation change will solve it.
CGRect tempFrame = self.emailImage.frame;
tempFrame.origin.x = textField.frame.origin.x+textField.frame.size.width+30;
self.emailImage.frame = tempFrame;
for all orientations. Assuming textField is the reference to the UITextField you have shown in the image.

Related

iOS: Make image width slightly smaller than screen width

I'm having an issue where my image is too big. I need it to be slightly less than what the screen width is.
Here's my controller:
- (void)viewDidLoad {
[super viewDidLoad];
self.imageName = #"goldencoaster";
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"table"]]];
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", self.imageName]];
CGRect bounds;
bounds.origin = CGPointZero;
bounds.size = [[UIScreen mainScreen] bounds].size;
self.coasterImage.bounds = bounds;
self.coasterImage.image = image;
}
However, this returns this when I run the simulator:
How would I get the image to show up slightly smaller than the screen width?
====================================================================
UPDATE
So I took out auto layout as suggested, and updated my controller to look like this:
- (void)viewDidLoad {
[super viewDidLoad];
self.imageName = #"goldencoaster";
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"table"]]];
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", self.imageName]];
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect bounds;
bounds.origin.x = screen.origin.x + 10;
bounds.origin.y = screen.origin.y + 10;
bounds.size.width = screen.size.width - 100;
self.coasterImage.frame = bounds;
self.coasterImage.image = image;
}
However, now my image doesn't show up at all?? Only the background (image with name "table") shows up, but not the goldencoaster.
Try this
- (void)viewDidLoad {
[super viewDidLoad];
self.imageName = #"goldencoaster";
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"table"]]];
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", self.imageName]];
CGRect bounds;
bounds.origin = CGPointZero;
bounds.size = [[UIScreen mainScreen] bounds].size;
self.coasterImage.bounds = bounds;
self.coasterImage.image = image;
self.coasterImage.frame = CGRectMake(20, 0, self.view.frame.size.width-40, self.view.frame.size.height);
self.coasterImage.center = self.coasterImage.superview.center;
}
Swift 3.1
override func viewDidLoad() {
super.viewDidLoad()
imageName = "goldencoaster"
view.backgroundColor = UIColor(patternImage: UIImage(named: "table")!)
let image = UIImage(named: imageName)
var bounds = CGRect()
bounds.origin = CGPoint.zero
bounds.size = (UIScreen.main.bounds).size
coasterImage.bounds = bounds
coasterImage.image = image
coasterImage.frame = CGRect(x: CGFloat(20), y: 0, width: self.view.frame.size.width - CGFloat(40), height: self.view.frame.size.height)
coasterImage.center = (coasterImage.superview?.center)!
}
you can do it with contentMode like
self.coasterImage.contentMode = UIViewContentModeScaleAspectFit;
here are the different contentMode check it from here
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
Two words: Auto Layout
You want your UI to adapt to different devices, and orientations.
Auto Layout and size classes are designed to handle those needs.
Update:
You're checking screen size and setting bounds. That suggests you're trying to size the view instead of letting Auto Layout constrain it. Auto Layout takes the place of setting frame or bounds. You don't want to mix the two.
If you weren't using autolayout, you will need to edit the image frame. For example if you want to reduce the size in 10 pixels:
- (void)viewDidLoad {
[super viewDidLoad];
self.imageName = #"goldencoaster";
[self.view setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:#"table"]]];
UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", self.imageName]];
CGRect screen = [[UIScreen mainScreen] bounds];
CGRect bounds = CGRectMake(screen.origin.x+10,
screen.origin.y+10,
screen.size.width-20,
screen.size.height-20);
self.coasterImage.center = self.coasterImage.superview.center;
self.coasterImage.frame = bounds;
self.coasterImage.image = image;
}

UIImagePickerController Camera view size issue

I'm building an app using the UIImagePickerController and a custom Overlay. What is does is comparing two images (before image and after image). I am using a custom overlay with the before image when taking the after photo(please see the image attached).
iPhone 5 - ios7
iPhone 4 - iOS7 (When taking the image)
iPhone 4 - iOS 7 (After taking the photo)
See the size difference between iPhone 4 and iPhone 5 camera view.
Application works fine with iPhone 5 screen size(Both ios 6 and ios7). But iPhone 4/4s screen size, it works fine ONLY with iOS6. The issue is with iphone 4/4s(ios7 ONLY), Camera view takes full screen.
That means, you can notice
iPhone 5 camera view size ~ 320*427 (iOS 6 and iOS 7)
iPhone 4 camera view size ~ 320*427 (iOS 6)
BUT
iPhone 4 camera view size ~ 320*480 (iOS 7).
After the image is taken, it fitted to the actual size of 320*427. Because of this issue, I cannot align before image with camera view on iPhone 4 iOS7 (because its screeches to 320*480).
Does anyone faces this strange issue. I tried almost everything, but NO luck. Any ideas please???
This is my piece code for loading the camera view with custom before photo overlay.
- (void)loadCameraWithImage
{
if (!isLoadedOnce)
{
isLoadedOnce = YES;
UIImagePickerController *cameraView = [[UIImagePickerController alloc] init];
cameraView.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraView.wantsFullScreenLayout = NO;
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)]) {
[self setEdgesForExtendedLayout:UIRectEdgeNone];
}
// crop before image
UIImage *imgTmpCropped = [self imageByCropping:imgBefore toRect:CGRectMake(0, 0, imgBefore.size.width/2, imgBefore.size.height)];
UIImage *overleyImage = [[UIImage alloc] initWithCGImage: imgTmpCropped.CGImage
scale: [UIScreen mainScreen].scale
orientation: UIImageOrientationDownMirrored];
UIImageView *crosshairView;
UIImageView *beforeView;
CGFloat screenHieght = [UIScreen mainScreen].bounds.size.height;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
//overleyImage = [UIImage imageNamed:#"overlay_ipad.png"];
crosshairView = [[UIImageView alloc] initWithImage:overleyImage];
crosshairView.frame = CGRectMake(0, 0, 768, 1024);
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
beforeView.frame = CGRectMake(0, 0, 384, 1024);
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleAspectFill;
}
else {
//overleyImage = [UIImage imageNamed:#"overleyImageAfter.png"];
crosshairView = [[UIImageView alloc] init];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
if(screenHieght>500){
crosshairView.frame = CGRectMake(0, 60, 320, 480);
beforeView.frame = CGRectMake(0, 70, 160, 427);
}
else{
if([[[UIDevice currentDevice] systemVersion] floatValue] <7.0){
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 427);
}
else{
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 480);
}
}
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleToFill;
}
//[crosshairView addSubview:beforeView];
//set our custom overlay view
cameraView.cameraOverlayView = beforeView;
cameraView.delegate = (id)self;
cameraView.showsCameraControls = YES;
cameraView.navigationBarHidden = YES;
cameraView.toolbarHidden = YES;
[cameraView setHidesBottomBarWhenPushed:YES];
[self.view.window.rootViewController presentViewController:cameraView animated:YES completion:nil];
isLoadedOnce = NO;
}
}
TL;DR
Camera's preview has the same aspect ratio in every device (4:3), screens don't. Asume the preview will have that specific aspect ratio and that it will be placed in a specific position on the screen. Draw your overlay inside that area.
Longer:
We faced the same issue. (Our use case is taking pictures of credit cards with an overlay with the same size as a card). The main problem is that the camera preview's proportions are always the same (4:3) in every device but different phones have different screen proportions (iPhone 4s vs iPhone 5, for example) so the preview's need to be fitted differently and that makes putting an overlay and cropping that very difficult.
Our solution was (the code is somewhat messy and hacky, sorry):
// Adjust camera preview to be a little bit more centered instead of adjusted to the top
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float cameraAspectRatio = 4.0 / 3.0;
float imageHeight = screenSize.width * cameraAspectRatio;
float verticalAdjustment;
if (screenSize.height - imageHeight <= 54.0f) {
verticalAdjustment = 0;
} else {
verticalAdjustment = (screenSize.height - imageHeight) / 2.0f;
verticalAdjustment /= 2.0f; // A little bit upper than centered
}
CGAffineTransform transform = self.cameraController.cameraViewTransform;
transform.ty += verticalAdjustment;
self.cameraController.cameraViewTransform = transform;
CGRect previewFrame = CGRectMake(0, verticalAdjustment, screenSize.width, imageHeight);
CardPhotoView *overlayView = [[CardPhotoView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height) widthPercentageOfCamera:self.widthPercentageOfCamera previewFrame:previewFrame];
self.overlayView = overlayView;
self.overlayView.delegate = self;
self.overlayView.useViewport = YES;
[self.overlayView setCameraReady:NO];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(cameraIsReady:) name:AVCaptureSessionDidStartRunningNotification object:nil];
self.cameraController.showsCameraControls = NO;
self.cameraController.navigationBarHidden = YES;
self.cameraController.toolbarHidden = YES;
self.cameraController.cameraOverlayView = self.overlayView;
[self presentViewController:self.cameraController animated:NO completion:nil];
Explanation:
self.cameraController is a UIImagePickerController. CardPhotoView is a view subclass that draws the overlay, it takes the preview frame to know exactly where the preview will be positioned (some devices will have black bars on top and bottom, some won't). It also takes a width percentage to add a little padding to the cropping window.
Also, we have hidden all default camera controls and we have implemented some buttons that will do the work for us. Those buttons are added in the CardPhotoView class and they are drawn taking into account where the preview frame is.

iOS: adding images to a UIButton, then putting button in a scrollview, but only seeing one image?

I'm working on an iPad app and part of the UI is a scrollview that has buttons for its contents. I'm working on adding images to these buttons, but when I do so, I only ever get the image in one spot, when I should be seeing it on all the buttons. This is what I'm doing:
float scrollCurrTop = 0;
CGRect currProcedureButtonFrame = CGRectMake(0,
scrollCurrTop,
self.fProceduresView.frame.size.width,
self.fLabelAndButtonHeight);
PatientIDButton* currProcedureButton = [PatientIDButton buttonWithType:UIButtonTypeCustom];
[currProcedureButton setFrame:currProcedureButtonFrame];
[currProcedureButton.layer setBorderColor: [self.fPanelViewBorderColor CGColor]];
[currProcedureButton.layer setBorderWidth: self.fBorderWidth];
currProcedureButton.titleLabel.font = self.fLabelFont;
NSString* displayName = [grabbing name];
if (displayName == nil)
{
displayName = currPlanName;
}
[currProcedureButton setTitle:displayName
forState:UIControlStateNormal];
[currProcedureButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
currProcedureButton.contentHorizontalAlignment = UIControlContentHorizontalAlignmentCenter;
currProcedureButton.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
// is the plan approved?
if ([self isPlanApproved:currPlanName])
{
// add the checkmark to this plan button
CGRect currPlanButtonFrame = currProcedureButton.frame;
float originX = currPlanButtonFrame.size.width - (currPlanButtonFrame.size.width/3.0f);
float originY = currPlanButtonFrame.origin.y;
float width = currPlanButtonFrame.size.width - originX;
float height = currPlanButtonFrame.size.height;
CGRect currPlanApprovalImageFrame = CGRectMake(originX, originY, width, height);
UIImageView* currPlanApprovalImage = [[UIImageView alloc] initWithFrame:currPlanApprovalImageFrame];
[currPlanApprovalImage setBackgroundColor:[UIColor colorWithRed:(63.0f/255.0f)
green:(179.0f/255.0f)
blue:(79.0f/255.0f)
alpha:1.0f]];
[currPlanApprovalImage setImage:self.fCheckMarkIcon];
[currProcedureButton addSubview:currPlanApprovalImage];
}
[self.fProceduresView addSubview:currProcedureButton];
scrollCurrTop += self.fLabelAndButtonHeight;
Where 'fProceduresView' is the scrollview that houses the buttons. What am I doing wrong?
It seems that you're misunderstanding the logic behing setting the frame of the imageview's those you're trying to add
CGRect currPlanButtonFrame = currProcedureButton.frame;
float originX = currPlanButtonFrame.size.width - (currPlanButtonFrame.size.width/3.0f);
float originY = currPlanButtonFrame.origin.y;
float width = currPlanButtonFrame.size.width - originX;
float height = currPlanButtonFrame.size.height;
CGRect currPlanApprovalImageFrame = CGRectMake(originX, originY, width, height);
UIImageView* currPlanApprovalImage = [[UIImageView alloc] initWithFrame:currPlanApprovalImageFrame];
You don't need to set originY to currPlanButtonFrame.origin.y;
All subviews have relative coordinates to their's superviews.
So in your case originY should be 0
For example:
// Image is visible
Button frame [0, 0, 100, 100]
image in button [0, 0, 100, 100]
// Button is visible, but image is not because it will be clipped by bounds of the button.
Button frame [100, 100, 100, 100]
image in button [100, 100, 100, 100]
Also you will be able to "see" your images, if you set
currProcedureButton.clipsToBounds = NO

Round corner full bottom screen for portrait & landscape mode?

I want to add rounded corners image on my UIView, so I made ​​two of my images 12x12px rounded corners.
I want to know how best to add my view taking into account that he must align automatically in portrait and landscape mode in the bottom of the total screen!
This is what I did now, but that does not work:
CGSize result = [[UIScreen mainScreen] bounds].size;
self.brcLeft = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, result.height-12.0, 12.0, 12.0)];
self.brcLeft.image = [UIImage imageNamed:#"brc-left"];
[self.view addSubview:brcLeft];
self.brcRight = [[UIImageView alloc] initWithFrame:CGRectMake(result.width-12.0, result.height-12, 12.0, 12.0)];
self.brcRight.image = [UIImage imageNamed:#"brc-right"];
[self.view addSubview:brcRight];
For setting your views to both orientation at the bottom of the screen do this:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
CGRect screenFrame = [[UIScreen mainScreen] bounds];
[self.brcLeft setFrame:CGRectMake(0.0, screenFrame.size.height - self.brcLeft.frame.size.height , 12.0, 12.0)];
[self.brcRight setFrame:CGRectMake(result.width-12.0, screenFrame.size.height - self.brcRight.frame.size.height , 12.0, 12.0)];
return YES;
}
and for rounded Corners:
#import <QuartzCore/QuartzCore.h>
write this in your viewDidLoad
self.brcLeft.layer.cornerRadius = 2;
self.brcLeft.layer.masksToBounds = YES;
self.brcRight.layer.cornerRadius = 2;
self.brcRight.layer.masksToBounds = YES;

How to get CGRect of UIImageView after CGAffineTransformRotate?

In my game I'm rotating UIImageview to 30-degrees and I need to get transformed CGRect of rotated UIImageview, please some one help me with sample code.
UIImageView *mainImgB = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, width, hight)];
[mainImgB setBackgroundColor:[UIColor greenColor]];
mainImgB.layer.anchorPoint = CGPointMake(0, 0);
mainImgB.center = CGPointMake(View.frame.size.width/2, View.frame.size.height/2);
mainImgB.transform = CGAffineTransformRotate(mainImgB.transform,30 * M_PI/180);
Thanks
Use CGRectApplyAffineTransform :
CGRect newRect = CGRectApplyAffineTransform(yourViewOnWhichTransformGetsApplied.frame, yourTransformHere);

Resources