UIScrollView keep buttons in fixed position - ios

I am using UIScrollView for pinch zooming the image the code I am using is like this
CGRect fullScreenRect=[[UIScreen mainScreen] applicationFrame]; //Full Screen
UIScrollView *scroll = [[UIScrollView alloc] initWithFrame:fullScreenRect];
scroll.backgroundColor = [UIColor clearColor];
scroll.delegate = self;
scroll.contentSize = _imageView.frame.size;
[scroll addSubview:_imageView];
scroll.minimumZoomScale = 1.0;
scroll.maximumZoomScale = 5.0;
[scroll setZoomScale:scroll.minimumZoomScale];
self.view = scroll;
[scroll addSubview:_screenShotButton];
[scroll addSubview:_resolutionButton];
-(void)aligementTheControlBasedOnOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
bool ipad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
if (ipad) {
if(UIInterfaceOrientationIsLandscape(toInterfaceOrientation))
{
_imageView.frame = CGRectMake(142, 114, 740, 555);
if ([self.resoultion isEqualToString:#"Default"]) {
_imageView.frame = CGRectMake(142, 114, 740, 555);
}
else if([self.resoultion isEqualToString:#"4:3"])
_imageView.frame = CGRectMake(142, 114, 740, 555);
else if([self.resoultion isEqualToString:#"16:9"])
_imageView.frame = CGRectMake(142, 114, 740, 416);
self.screenShotButton.frame = CGRectMake(794, 667, 55, 55);
self.resolutionButton.frame = CGRectMake(857, 667, 55, 55);
}
else
{
_imageView.frame = CGRectMake(64, 238, 640, 480);
if ([self.resoultion isEqualToString:#"Default"]) {
_imageView.frame = CGRectMake(64, 238, 640, 480);
}
else if([self.resoultion isEqualToString:#"4:3"])
_imageView.frame = CGRectMake(64, 238, 640, 480);
else if([self.resoultion isEqualToString:#"16:9"])
_imageView.frame = CGRectMake(64, 238, 640, 360);
self.screenShotButton.frame = CGRectMake(578, 749, 55, 55);
self.resolutionButton.frame = CGRectMake(649, 749, 55, 55);
}
}
}
Based on the resolution user has chosen I am positioning the buttons.
Everything is working fine for me. The problem I am facing is _screenShotButton and _resolutionButton are also moving when I zoom the image. Instead I want to keep the buttons static in the bottom right side of the screen.
Can anyone help me.

You can do it making moving sub view from UIScrollView to super view of scrollview like:
Place/set your button over scroll view (not inside scroll view) as shown here in this snapshot. And also set button constraints (position) with respect to super view of your scrollview.
Here is ref. snapshot of hierarchy of position of each view over each-other.

Do not add your buttons to the scroll view, but to its parent instead.
This part is wrong:
[scroll addSubview:_screenShotButton];
[scroll addSubview:_resolutionButton];
Assuming scroll has a superview (which in your original question it does not), do this instead:
[scroll.superview addSubview:_screenShotButton];
[scroll.superview addSubview:_resolutionButton];
Alternatively, you can pick the order of scroll vs. screenShotButton by replacing -addSubView: by one of the -insertSubview:: methods.

Related

Table Cell not selectable after rotation

I have a view which should have a different layout in portrait and Landscape mode. I implement a method to redraw my UI elements with Autosizing (no AutoLayout):
-(void)buildViewElements:(UIInterfaceOrientationMask)interfaceOrientation duration:(NSTimeInterval)duration {
if (interfaceOrientation == UIInterfaceOrientationMaskPortrait) {
NSLog(#"Portrait");
[UIView animateWithDuration:duration animations:^{
CGRect newImageFrame = CGRectMake(20, 15, 100, 100);
_personImage.frame = newImageFrame;
CGRect newNameLabelFrame = CGRectMake(128, 20, 172, 21);
_nameLabel.frame = newNameLabelFrame;
CGRect newNameDescFrame = CGRectMake(128, 41, 172, 21);
_nameDescriptionLabel.frame = newNameDescFrame;
CGRect newBorrowedFrame = CGRectMake(128, 64, 75, 21);
_borrowedLabel.frame = newBorrowedFrame;
CGRect newBorrowedValueFrame = CGRectMake(211, 64, 42, 21);
_borrowedValueLabel.frame = newBorrowedValueFrame;
CGRect newLendFrame = CGRectMake(128, 93, 75, 21);
_lendLabel.frame = newLendFrame;
CGRect newLendValueFrame = CGRectMake(211, 93, 42, 21);
_lendValueLabel.frame = newLendValueFrame;
CGRect newcontainerFrame = CGRectMake(0, 130, 320, [CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] - 194);
_tableContainerView.frame = newcontainerFrame;
CGRect newDetailFrame = CGRectMake(20, 0, 280, 29);
_detailSelector.frame = newDetailFrame;
CGRect newTableFrame = CGRectMake(0, 36, 320, newcontainerFrame.size.height - 39);
_tableView.frame = newTableFrame;
}];
}
else if (interfaceOrientation == UIInterfaceOrientationMaskLandscape) {
NSLog(#"Landscape");
[UIView animateWithDuration:duration animations:^{
CGFloat factor = 1.0f;
CGFloat diff = 0.0f;
if ([CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] <= 480) {
// iPhone4 size
factor = 0.8f;
diff = 10.0f;
}
CGRect newImageFrame = CGRectMake(75*factor-diff, 20, 100, 100);
_personImage.frame = newImageFrame;
NSLog(#"Bild Frame %f", newImageFrame.origin.x);
CGRect newNameLabelFrame = CGRectMake(20, 140, 210*factor, 21);
_nameLabel.frame = newNameLabelFrame;
CGRect newNameDescFrame = CGRectMake(20, 161, 210*factor, 21);
_nameDescriptionLabel.frame = newNameDescFrame;
CGRect newBorrowedFrame = CGRectMake(20, 184, 75, 21);
_borrowedLabel.frame = newBorrowedFrame;
CGRect newBorrowedValueFrame = CGRectMake(103, 184, 42, 21);
_borrowedValueLabel.frame = newBorrowedValueFrame;
CGRect newLendFrame = CGRectMake(20, 213, 75, 21);
_lendLabel.frame = newLendFrame;
CGRect newLendValueFrame = CGRectMake(103, 213, 42, 21);
_lendValueLabel.frame = newLendValueFrame;
CGRect newContainerFrame = CGRectMake(250*factor, 0, [CNX_Tools getLargestAttributeOfSize:[[UIScreen mainScreen] bounds].size] - 250*factor, 268);
_tableContainerView.frame = newContainerFrame;
CGRect newDetailFrame = CGRectMake(20, 10, newContainerFrame.size.width - 40 , 29);
_detailSelector.frame = newDetailFrame;
CGRect newTableFrame = CGRectMake(0, 49, newContainerFrame.size.width, 219);
_tableView.frame = newTableFrame;
}];
}
}
This method is called from method:
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
switch (toInterfaceOrientation) {
case UIInterfaceOrientationPortrait:
[self buildViewElements:UIInterfaceOrientationMaskPortrait duration:duration];
break;
case UIInterfaceOrientationPortraitUpsideDown:
[self buildViewElements:UIInterfaceOrientationMaskPortrait duration:duration];
break;
case UIInterfaceOrientationLandscapeLeft:
[self buildViewElements:UIInterfaceOrientationMaskLandscape duration:duration];
break;
case UIInterfaceOrientationLandscapeRight:
[self buildViewElements:UIInterfaceOrientationMaskLandscape duration:duration];
break;
default:
break;
}
}
The method getLargestAttributeOfSize: returns the largest size attribute (height or width).
If I start the view in portrait I can tapp an the table cells and method tableView: didSelectRowAtIndexPath: is called. After a rotation to landscape mode all cells are not selectable and I cannot scroll in the table. But, if I leaf this screen and call ist again (in landscape mode), the same table cells are selectable, the method is called and I can stroll trough the table. If I rotate the device to portrait, I have the same faulty behavior. After a rotation of my device I can not interact with my table and its cells.
Can someone help me please or have an idea what's my issue here?
Thanks!
My guess is that a superview of your UITableView is not adjusted correctly. The input can than never reach your UITableView, but when it is started fresh all is well. Probably the view of your UIViewController.
Try setting clipsToBounds:YES to the superviews to see if your tableView is actually out of the views bounds.

UIScrollview doesn't scroll iOS

I'm creating several scroll views in one view that scroll horizontally. The following code works fine:
-(void)updateSection {
builder = [NSMutableArray array];
float xPosition = 0;
float xposbut = 100;
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 100, self.frame.size.width, self.frame.size.height - 69)];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
scrollView.delegate = self;
[self addSubview:scrollView];
for (int i = 1; i < itemArticleArray.count; i++) {
ItemView *item = [ItemView loadNibs];
item.frame = CGRectMake(xposbut, 10, item.frame.size.width, item.frame.size.height);
xPosition += scrollView.frame.size.width + 2;
xposbut += 500;
UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(xposbut - 50, 4, 2, scrollView.frame.size.height - 8)];
[scrollView addSubview:seperatorView];
xPosition += scrollView.frame.size.width + 4;
[scrollView addSubview: item];
[builder addObject:item];
}
[scrollView setContentSize:CGSizeMake(xposbut, scrollView.frame.size.height)];
[self addSubview:scrollView];
}
However, when I change the 8th line of code to the following:
scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 400, self.frame.size.width, self.frame.size.height - 69)];
It cause the layout to look fine, but the scroll views do then not scroll at all. Any ideas?
you set the contentSize.height to the scrollView.frame.size.height and so the scrollView cant scroll. you have to set the contentSize to the total height of you scrollView, including the not visible area. The frame is only the area on screen.
UIScrollview will scroll when content size is bigger then frame size. In your code you set content size equal to frame size that's why your scrollview is not scrolling.
Set the content size for the scroll view. The content size should be greater than frame.size, then only the scroll view will scroll. And also enable scrolling.
Use the code
scrollView.scrollEnabled=YES;
scrollView.contentSize=CGSizeMake(CGFloat width, CGFloat height);
Height should be greater than scrollView.frame.size.height and add contents inside scrollview beyond the scrolview's frame.
You must give the scroll some space to work so check this out:
Create the scroll in the storyboard
Create an outlet for the scroll
And the in the .m file you must paste these lines
The code:
(void)viewDidLoad {
[super viewDidLoad];
yourScroll.scrollEnabled=YES;
yourScroll.contentSize=CGSizeMake(self.view.frame.size.width, self.view.frame.size.height*2);
}
/*
* yourScroll.contentSize=CGSizeMake(your desired scroll width, your desired scroll height);
* The values must be bigger than the viewController size
*/

Resize UITableViews programmatically

I have 3 tables, but sometimes I have to hide the 3 one. So:
- (void)viewWillAppear:(BOOL)animated
{
if (s == 2)
{
// Adjust frames
self.tableA.frame = CGRectMake(0, 100, 500, 200);
self.tableB.frame = CGRectMake(500, 100, 500, 200);
[self.tableC setHidden:NO];
self.tableC.frame = CGRectMake(0, 200 + 100 +40, 1024, 200);
}
else
{
self.tableA.frame = CGRectMake(0, 100, 500, 600);
self.tableB.frame = CGRectMake(500, 100, 500,600);
[self.tableA sizeToFit];
[self.tableB sizeToFit];
[self.tableC setHidden:YES];
}
The problem is that when s!=2, the tableA and tableB do not resize to take the full height I set. The have 200 as height ...
I created the tables with XIB.
I would like to resize tableA and tableB in such way they have 600 as height, but only when tableC is hidden.
Allowing Autolayout in the IB and deleting sizeToFit worked out.

Adding subviews programmatically positions them weirdly

I have a view in which I want to add multiple subviews, however when I add them, they get positioned in positions where I didn't set the frame. The x coordinate is correct, but the y is quite off.
Using the Interface Builder it went quite smooth, just drag them in and send the correct frame and origin. However I don't appear to be able to set the origin; I get expression is not assignable when I try view.frame.origin = CGPointMake(x, y), and setting the x and y coordinates directly gives me the same error.
Does this happens because subviews cannot overlap programmatically without setting a special attribute (that I'm missing)?
Edit: The views are being set in the initWithStyle method of a UITableViewCell.
Edit 2: Added code within initWithStyle method.
// Initialize images
self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image"]];
self.anImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"anImage"]];
self.anotherImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"anotherImage"]];
// Set imageview locations
self.imageView.frame = CGRectMake(0, 0, 300, 54);
self.anImageView.frame = CGRectMake(20, 53, 16, 52);
self.anotherImageView.frame = CGRectMake(179, 43, 111, 53);
To avoid expression is not assignable, you have to set the entire frame at once, either using
view.frame = CGRectMake(x, y, width, height)
or
CGRect frame = self.view.frame;
frame.origin.x = newX;
self.view.frame = frame;
Most likely you are setting the frames in the viewDidLoad method. The problem here is that you are setting the frame before the viewControllers frame has been resized based on the constraints of the app.
Try moving your frame setting into the method viewWillAppear and see if that fixes your problem.
Edit: Because you are doing this in a cell, and not in a viewController you would do something like the following:
In initWithStyle:reuseIdentifier
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
self.customView = [[UIView alloc] initWithFrame:CGRectZero];
}
return self;
}
Then override layoutSubviews to actually set the views frame
- (void)layoutSubviews
{
[super layoutSubviews];
self.customView.frame = CGRectMake(x, y, width, height);
}
As far as the "expression is not assignable" warning, this is because you cannot just set a views origin without setting the height and width. Use:
view.frame = CGRectMake(x, y, width, height);
If you want to keep the same width and height without having to hard code it do something like
view.frame = CGRectMake(x, y, view.frame.size.width, view.frame.size.height);

Uitextfield and UIImageView are overlapping when orientation change

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.

Resources