UIView bottom constraint after rotate - ios

I have UIProgressView that i transformed (rotated) so it would be vertical, my issue is with the bottom constraint which is not appearing correctly since the view is rotated, the bottoms of UIView and UIProgressView and not exactly aligned, i tried also to change the anchor point, couldn't the bottoms to be aligned as well.
- (void)viewDidLoad {
[super viewDidLoad];
[self initFlow];
self._wProgressView = [[UIProgressView alloc] init];
[self._middleRightView addSubview:self._wProgressView];
[self._wProgressView setProgress:0.7];
CGPoint newCenter = self._wProgressView.layer.anchorPoint;
newCenter.x = 0;
newCenter.y = 1;
[self._wProgressView.layer setAnchorPoint:newCenter];
self._wProgressView.transform = CGAffineTransformRotate(self._wProgressView.transform, -0.5 *M_PI);
// [self._wProgressView.centerXAnchor constraintEqualToAnchor:self._wProgressView.superview.centerXAnchor].active = YES;
self._wProgressView.translatesAutoresizingMaskIntoConstraints = NO;
[self._wProgressView.bottomAnchor constraintEqualToAnchor:self._wImageView.bottomAnchor].active = YES;
[self._wProgressView.widthAnchor constraintEqualToAnchor:self._wProgressView.superview.heightAnchor multiplier:0.5].active = YES;
[self._wProgressView.heightAnchor constraintEqualToAnchor:self._wProgressView.superview.widthAnchor constant:0.8].active = YES;
//= self._wProgressView.superview.centerXAnchor;
}

I got it to work this way:
You should give only height, width and Center x and y constraint of UIProgressView to UIView relation
No Need to give bottom constraint of UIProgressView
this work for me I Hope this will help you...!

Related

How to convert frame from UIScrollView to UIView

I want to convert frame from UIScrollView to UIView, but not exaclty.
This is my code:
//Create UIScrollView addSubview self.view
scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
[scrollView setBouncesZoom:YES];
[scrollView setMinimumZoomScale:1];
[scrollView setZoomScale:4];
scrollView.delegate = self;
//create UIView overlay UIScrollView and addSubview self.view
overlayView = [[UIView alloc] initWithFrame:self.view.bounds];
overlayView.backgroundColor = [UIColor blueColor];
overlayView.alpha = 0.5;
[self.view addSubview:overlayView];
//create UIView addSubView overlayView, can move change postion
UIView *moveView = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 100, 100)];
moveView.backgroundColor = [UIColor redColor];
[overlayView addSubView:moveView];
If zoom in, zoom out scrollView, moveView change position by ratio when scrollView zoom in zoom out.
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
[scrollView setZoomScale:scale+0.01 animated:NO];
[scrollView setZoomScale:scale animated:NO];
CGRect visibleRect;
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = CGSizeMake(scrollView.bounds.size.width * scrollView.zoomScale, scrollView.bounds.size.height * scrollView.zoomScale);
visibleRect.origin.x = 0;
visibleRect.origin.y = 0;
overlay.frame = visibleRect;
CGRect moveRect = moveView.frame;
moveRect.origin.x *= scrollView.zoomScale;
moveRect.origin.y *= scrollView.zoomScale;
moveRect.size.width *= scrollView.zoomScale;
moveRect.size.height *= scrollView.zoomScale;
moveView.frame = moveRect;
}
I cannot change postion moveView exactly when scrollView zoom in zoom out. Please help me resolve this issue.
First I'd say, you really need to be using autolayout for all this stuff. Or none of this will work if you rotate the device, or on different devices, etc. Just using frames to position views is just not the done way anymore. It will work to a degree though. Yes autolayout is a learning curve but you just need to know it and use it all the time.
But looking at the code there two issues stand out : at the start of the didEndZooming method, you set the scale twice, Im not sure why -
[scrollView setZoomScale:scale+0.01 animated:NO];
[scrollView setZoomScale:scale animated:NO];
Then also later, you set the origin of the visibleRect property twice in different ways :
visibleRect.origin = scrollView.contentOffset;
visibleRect.size = CGSizeMake(scrollView.bounds.size.width * scrollView.zoomScale, scrollView.bounds.size.height * scrollView.zoomScale);
visibleRect.origin.x = 0;
visibleRect.origin.y = 0;
Setting the x and y values there is the same as setting the origin to the scrollView.contentOffset - so first you set the origin to the content offset position, then to 0,0 - which doesnt make sense. Clearing up those problems might sort things out.

Unwanted bounce of subviews on scrollview

I have a scrollview that acts as a banner with 15 image views as subviews (scrolled horizontally). I add the subviews this way:
for (int i = 0; i < featuredImages.count; i++) {
CGRect frame;
frame.origin.x = self.scrollViewFeaturedImages.frame.size.width * i;
frame.origin.y = 0;
frame.size = self.scrollViewFeaturedImages.frame.size;
UIImageView *subview = [[UIImageView alloc] init];
subview.frame = frame;
[self.scrollViewFeaturedImages addSubview:subview];
}
And set the contentSize accordingly:
self.scrollViewFeaturedImages.contentSize = CGSizeMake(self.scrollViewFeaturedImages.frame.size.width * featuredImages.count, self.scrollViewFeaturedImages.frame.size.height);
self.scrollViewFeaturedImages.contentInset = UIEdgeInsetsZero;
However, when the view appears, the first image seems to be a little off.
When I scroll (horizontally) to the next image, the gap disappears, and when I scroll back to the first image, the frame is corrected already.
I've also disabled BOUNCE but I can drag the image vertically.
I've also tried this:
self.automaticallyAdjustsScrollViewInsets = NO;
with no success.
What's going on?
After being puzzled for 2 weeks I finally got this fixed by adding these lines in viewDidAppear.
self.scrollViewFeaturedImages.contentInset = UIEdgeInsetsZero;
self.scrollViewFeaturedImages.scrollIndicatorInsets = UIEdgeInsetsZero;
Did you try to change the UIImageView's property contentMode to UIViewContentModeScaleToFill?

UIScrollview - how to make subview smaller as it scrolls off screen

I'm a beginner with iOS, so i'm just not sure what to research here. I have a UIScrollView with a few square subViews added. How can i make the subviews smaller as they scroll off screen and bigger as they approach the center of the screen?
#import "HorizontalScrollMenuViewController.h"
#import <UIKit/UIKit.h>
#define SUBVIEW_WIDTH_HEIGHT 280
#interface HorizontalScrollMenuViewController : UIViewController
#property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
#end
#implementation HorizontalScrollMenuViewController
-(void)viewDidLoad{
[super viewDidLoad];
NSArray *colors = [NSArray arrayWithObjects:[UIColor greenColor],[UIColor redColor],[UIColor orangeColor],[UIColor blueColor],nil ];
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
CGFloat originX = (screenWidth - SUBVIEW_WIDTH_HEIGHT)/2.0; // get margin to left and right of subview
CGFloat originY = ((screenHeight - SUBVIEW_WIDTH_HEIGHT)/2);
// add subviews of all activities
for (int i = 0; i < colors.count; i++){
CGRect frame = CGRectMake(0,0,SUBVIEW_WIDTH_HEIGHT,SUBVIEW_WIDTH_HEIGHT);
frame.origin.x = self.scrollView.frame.size.width * i + originX;
frame.origin.y = originY;
UIView *subView = [[UIView alloc] initWithFrame:frame];
[UIView setAnimationBeginsFromCurrentState: YES];
subView.layer.cornerRadius = 15;
subView.layer.masksToBounds = YES;
subView.backgroundColor = [colors objectAtIndex:i];
[self.scrollView addSubview:subView];
}
self.scrollView.contentSize = CGSizeMake(self.scrollView.frame.size.width * colors.count, self.scrollView.frame.size.height);
}
#end
Here you can find a fully working example of what you're trying to accomplish. It only has
one subview because it's just to give you an idea of how can you accomplish it. Also, this example was tested on an iPad (iOS7) simulator.
The *.h file
#import <UIKit/UIKit.h>
// Remember to declare ourselves as the scroll view delegate
#interface TSViewController : UIViewController <UIScrollViewDelegate>
#property (nonatomic, strong) UIView *squareView;
#end
The *.m file
#import "TSViewController.h"
#implementation TSViewController
#synthesize squareView = _squareView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Create and configure the scroll view (light gray)
UIScrollView *myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(100, 100, 500, 500)];
CGRect contentSize = myScrollView.frame;
contentSize.size.height = contentSize.size.height + 400;
myScrollView.contentSize = contentSize.size;
myScrollView.userInteractionEnabled = YES;
// give the scroll view a gray color so it's easily identifiable
myScrollView.backgroundColor = [UIColor lightGrayColor];
// remember to set yourself as the delegate of the scroll view
myScrollView.delegate = self;
[self.view addSubview:myScrollView];
// Create and configure the square view (blue)
self.squareView = [[UIView alloc] initWithFrame:CGRectMake(200, 400, 60, 60)];
self.squareView.backgroundColor = [UIColor blueColor];
[myScrollView addSubview:self.squareView];
}
// Here is where all the work happens
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Get the difference between the contentOffset y position and the squareView y position
CGFloat y = self.squareView.frame.origin.y - scrollView.contentOffset.y;
// If the square has gone out of view, return
if (y <= 0) {
return;
}
// Modify the squareView's frame depending on it's current position
CGRect squareViewFrame = self.squareView.frame;
squareViewFrame.size.height = y + 5;
squareViewFrame.size.width = y + 5;
squareViewFrame.origin.x = (scrollView.contentSize.width - squareViewFrame.size.width) / 2.0;
self.squareView.frame = squareViewFrame;
}
#end
And here is a little explanation of what is going on:
A UIScrollView has several properties that allow you to configure it correctly. For example it has a frame (gray) which is inherited from UIView; with this property you specify the visible size of the scroll view. It also has the contentSize (red) which specifies the total size of the scroll view; in the image it's showed as the red area but this is only for illustration purposes as it will not be visible in the program. Imagine the scroll view's frame as the window that let's you see only a part of the bigger content the scroll view has.
When the user starts scrolling a gap appears between the top part of the contentSize and the top part of the frame. This gap is known as the contentOffset
Here is the reference to UIScrollView
Here is the reference to UIScrollViewDelegate
Hope this helps!
Assuming that you have the scrollView inside self.view, you can implement scrollViewDidScroll: in the scroll view delegate to find when it is scrolled.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
for (UIView *view in self.scrollView.subviews) {
CGRect frame = [view convertRect:view.frame toView:self.view]; // Contains the frame of view with respect to self.view
}
}
You can them use the frame to resize subviews as you want.
The answer starts with analyzing the UIScrollView Class Reference and it's delegate. In the delegate documentation see the responding to scrolling and dragging section. You should also review the sample code for each. You can create outlets to your subviews and change the subview properties within a uiview animation. These references will give you a good foundation in understanding where you can build the call to animate the subviews.
Here is a link to animating subviews. Additional examples can be found by Googling "uiview subview animation" (without the quotes). If you run into any major issues read the header files first and post some sample code for additional (more precise) help.
Other reference:
UIKit ScrollViews

Scroll horizontally with UIScrollView don't seems to work with Autolayout

I'm trying to create a Horizontal Scroll using UIScrollView and a UIImageView. The image View has a width of 1280px (4 pages) and the scrollView 320px. When I use this code WITHOUT autolayout mode, the scroll works properly:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.scrollView.scrollEnabled = YES;
self.scrollView.showsVerticalScrollIndicator = NO;
self.scrollView.showsHorizontalScrollIndicator = NO;
CGRect imageFrame = self.helpImageView.frame;
NSLog(#"imageFrame w: %f",self.helpImageView.frame.size.width); //prints 1280.000000
[self.scrollView setContentSize:imageFrame.size];
NSLog(#"contentSize w: %f",self.scrollView.contentSize.width); //prints 1280.0000
NSLog(#"scrollFrame w: %f",self.scrollView.frame.size.width); //prints 320.00
}
But, if I want to use Autolayout, this code returns the same result but the UIScrollView does not scroll. Why??? I'm using these constraits:
Bottom space to: ScrollView Equals:32.0
Leading space to: ScrollView
Trailing space to: ScrollView
Top Space To: SCrollView Equals:-20.0
Bottom Space To: View Equals:-12.0
Leading space to: View
Top Space To: View Equals:427.0
Trailing space to: View
I also created horizontal scroll view, then initial values are as follows.
CustomScrollView.m :
self.showsHorizontalScrollIndicator = NO;
self.showsVerticalScrollIndicator = NO;
self.scrollsToTop = NO;
self.delegate = (id)self;
self.contentSize = CGSizeMake(320.0 * PAGE_COUNT, 420.0);
self.pagingEnabled = YES;
self.bounces = NO;
for (int i = 0; i < PAGE_COUNT; i++) {
// NSString *str = [NSString stringWithFormat:#"%#%d%#", #"foo", i, #".png"];
UIImageView * imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:str]];
// imgView.frame = CGRectMake(320.0f * i + 10, 0, 300, 300 * 1.33);
[self addSubview:imgView];
}
In this project, PAGE_COUNT=4 and 4 images are foo0.png ~ foo3.png.

add sub view in center - iPad

I want to add a sub view in current view, this sub view is 300x300. When I add subview using
[self.view addSubview:md.view];
the md.view will appear at position (0,0) is there any way to add subview in center?
Thanks
You can set view's center property:
md.view.center = self.view.center;
Or you can explicetly set frame for md.view so that it will be centered as you want.
Use
CGRect bounds = self.view.bounds;
md.view.center = CGPointMake(bounds.size.width / 2, bounds.size.height / 2);
before or after that -addSubview: line.
You can specify exactly where you want the sub view to be placed within the parent view by doing so in the viewDidLoad method as follows:
- (void)viewDidLoad {
[super viewDidLoad];
SubView1Controller *subView1Controller=[[[SubView1Controller alloc] initWithNibName:#"SubView1" bundle:nil] autorelease];
CGRect r = [subView1Controller.view frame];
r.origin.x = 50;
r.origin.y = 50;
[subView1Controller.view setFrame:r];
[self.view insertSubview:subView1Controller.view atIndex:0];
}

Resources