I made a custom UIView doing some animation on it.
I need to calculate it's frame size because it differs in iPhone 6, 6 plus and iPhone 5.
I am using
self.frame, self.layer.presentationlayer.frame
but all of them gives wrong frame, I need the frame of the view after it appears inside the Cell.
in cellForRowAtIndexPath i call this function
[cell.answer1 showStatistics:percent];
in the method first i made
CGRect Frame= self.frame;
dempedLayer=[[UIView alloc] initWithFrame:Frame];
[dempedLayer setBackgroundColor:[UIColor blackColor]];
[dempedLayer setAlpha:0.35];
[self addSubview:dempedLayer];
then i make some animation using CAShapeLayer and CABasicAnimation
CABasicAnimation *rotationAnimation=[CABasicAnimation animationWithKeyPath:#"strokeEnd"]
if you are trying to do animation here is how can achieve it:-
[UIView animateWithDuration:0.5 animations^{
CGRect viewFrame = self.yourView.frame;
viewFrame.size.height += 100;
self.yourView.frame = viewFrame;
}];
if this is not what you are looking for, may be you should check the autoresizing parameters you are setting in the IB/Storyboard.
Related
I created a floating view for my application which always displays on screen.
Now I want to make a half of it go outside my screen when it is interactive for 3-4 seconds. I think I should use a NSTimer to hide out this view, but it is not the problem.
The problem is how should I set origin.x of this view to go outside of the screen? I've tried to set the frame in my initWithSuperView like this:
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenX = screenRect.origin.x;
[self setFrame:CGRectMake(-screenX - size.width, 0, size.width, size.height)];
However, it doesn't work. How should I do it to get my desired result? See image below for more information:
you can use uiview animation similar to this:
dispatch_async(mainQueue, ^{
__weak __typeof(self) weakSelf = self;
[UIView animateWithDuration:3.f animations:^{
// change uiview frame here
weakSelf.frame = hiddenFrame;
} completion:^(BOOL finished) {
// setup completion
[weakSelf.view layoutIfNeeded];
}];
});
also you can setup NSLayoutConstraint to the x constraint of uiview and update it with negative value when you need.
I am trying to reproduce an effect like the iOS 7 app switcher where I can scroll between smaller, transformed views. My current obstacle is getting the contentOffset
In order to do this, I have added a scrollView to my view, and sized it to the bounds of the view. I then create a container view that holds on to all the 'cards' -- it is this container view to which I apply the transform.
Anyway, the issue I am having is with adjusting where a particular card appears after it has the transform applied -- right now, I am unable to adjust the contentOffset during the transform in a manner that is smooth.
Anyway, code would help! Here it is:
NSInteger idx = selectedCardIndex;
if (TransformApplied)
{
[UIView animateWithDuration:0.5 animations:^{
[self.container setTransform:CGAffineTransformIdentity];
[self.container setFrame:CGRectOffset(self.container.frame, (1-ScaleFactor)/2 * NumCards * ScreenWidth, 0)];
[self.scrollView setContentSize:self.container.frame.size];
[self.scrollView setContentOffset:CGPointMake(ScreenWidth * idx, 0) animated:NO];
[self.scrollView setPagingEnabled:YES];
} completion:^(BOOL finished) {
TransformApplied = NO;
}];
}
else
{
[UIView animateWithDuration:0.5 animations:^{
[self.container setTransform:CGAffineTransformMakeScale(ScaleFactor, ScaleFactor)];
[self.container setFrame:CGRectOffset(self.container.frame, (-1)*((1-ScaleFactor)/2) * NumCards * ScreenWidth, 0)];
[self.scrollView setContentSize:CGSizeMake(ScreenWidth * ScaleFactor * NumCards, ScreenHeight * ScaleFactor)];
[self.scrollView setContentOffset:CGPointMake(ScaleFactor * ScreenWidth * idx, 0) animated:NO];
[self.scrollView setPagingEnabled:NO];
} completion:^(BOOL finished) {
TransformApplied = YES;
}];
}
More
I am noticing that everything is smooth when applying the identity transform, but not when applying the smaller transform, I get a weird 'jump' in the frame before the animation.
If i comment out the content offset adjustment in the scale transform (the bottom block) then everything runs smoothly, but the contentOffset is wrong after the scale transform.
Lastly, calling setContentOffset:animated: results in a wonky animation so that is a no-go.
Any help greatly appreciated!!!!
UPDATE
I've looked in to anchor point/ position properties on CALayer, and I've got the animation effects working perfectly with this:
NSInteger idx = selectedCardIndex;
if (TransformApplied)
{
[UIView dd_AnimateWithDuration:0.5 animations:^{
[self.container setTransform:CGAffineTransformIdentity];
[self.scrollView setContentOffset:CGPointMake(ScreenWidth * idx, 0) animated:NO];
[self.scrollView setPagingEnabled:YES];
} completion:^(BOOL finished) {
TransformApplied = NO;
}];
}
else
{
CGPoint anchor = CGPointMake((idx * ScreenWidth + ScreenWidth/2)/CGRectGetWidth(self.container.frame), 0.5f);
[self.container.layer setAnchorPoint:anchor];
CGPoint position = CGPointMake((anchor.x) * self.container.frame.size.width, self.container.layer.position.y);
[self.container.layer setPosition:position];
[UIView dd_AnimateWithDuration:0.5 animations:^{
[self.container setTransform:CGAffineTransformMakeScale(ScaleFactor, ScaleFactor)];
[self.scrollView setPagingEnabled:NO];
} completion:^(BOOL finished) {
TransformApplied = YES;
}];
}
However, now i've got to figure out a way to get rid of all the extra space in the scrollview without allowing the position of the container to change....
I have had a similar issue a long time ago about the position of a view. After a long research, I ended up with the UIView documentation. It says about transform and frame properties of a UIView with a warning:
Warning:
If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
Changing the frame rectangle automatically redisplays the receiver without invoking the drawRect: method. If you want the drawRect: method invoked when the frame rectangle changes, set the contentMode property to UIViewContentModeRedraw.
Changes to this property can be animated. However, if the transform property contains a non-identity transform, the value of the frame property is undefined and should not be modified. In that case, you can reposition the view using the center property and adjust the size using the bounds property instead.
So, the basic idea is that, you shouldn't rely on or change frame when your view's transform contains a non-identity transform.
And the more important idea, always give a chance to the official documentation before looking elsewhere.
I hope this helps.
Using UIView's animateWithDuration:animations:completion:, I'm resizing a UIView and a subview of that UIView which is a subclass of UITableView.
The UIView resizes fine, but the UITableView doesn't. It does move around a little, but the frame does not update properly and reverts to its original state.
Edit: if I move the resizing to the completion block.... it works. What gives?
tweetTable.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[tweetTable endUpdates];
[UIView animateWithDuration:DURATION animations:^{
CGRect leftFrame = leftPane.frame;
leftFrame.size.width = self.view.frame.size.width - MARGIN;
leftPane.frame = leftFrame;
leftPaneButton.frame = leftFrame;
CGRect tweetFrame = tweetTable.frame;
tweetFrame.size.width = leftPane.frame.size.width;
NSLog(#"%f to %f", tweetTable.frame.size.width, leftPane.frame.size.width);
tweetTable.frame = tweetFrame;
tweetTable.backgroundColor = [UIColor redColor];
tweetTable.alpha = 0.5f;
sideInfo.center = CGPointMake(self.view.frame.size.width - MARGIN + (sideInfo.frame.size.width / 2), sideInfo.center.y);
rightPaneButton.center = sideInfo.center;
} completion:^(BOOL finished) {
leftExtended = TRUE;
[tweetTable beginUpdates];
}];
Check in your storyboard if the UIView has Autoresize Subviews checked. That means that it resizes all of its subviews when the view itself gets resized. That would explain why it works in the completion block.
I have a UITextView whose height I am trying to resize as the number of lines increases. Apart form this, I need to resize the UIView in which the UITextView is contained. I am using the following code for this:
-(void) textViewDidChange:(UITextView *)textView{
CGFloat before = textView.frame.size.height;
CGRect frame = textView.frame;
frame.size = textView.contentSize;
CGFloat after = frame.size.height, diff = after - before, final = 0;
if (diff>16) {
final = 8;
}else if(diff<-1){
final = -16;
}else{
final = 0;
}
[self.containerView setFrame: CGRectMake(self.containerView.frame.origin.x,
self.containerView.frame.origin.y-final, self.containerView.frame.size.width,
frame.size.height+13)];
[textView setFrame: frame];
}
I am also trying to change the Y-position of the container as the text is changed. I am using static number values according to font size to avoid complications.
But the problem is that whenever the UITextView enters a new line, it resizes its contentSize to the original size and so the frame of the UITextView is also reduced for a moment, which looks really ugly. Also, the Y-position depends on this contentSize change and it gets all messed up when this automatic resize happens.
I am looking for the same behaviour which apps like whatsapp or viber have. Any idea how I can achieve this?
If I understand correctly, the containerView includes a textfield and must be drawn around it, regardless of the size of the textfield? If that is, try something like this
-(void) textViewDidChange:(UITextView *)textView
{
CGRect frame = textView.frame;
frame.size = textView.contentSize;
//do your magic calculations
[textView setFrame: frame];
[self.containerView setFrame: CGRectMake(self.containerView.frame.origin.x,
self.containerView.frame.origin.y-final, self.containerView.frame.size.width, frame.size.origin.y +frame.size.height+13)];
}
I have an element in a UIView with a constraint that says it should always be 10 pixels from the bottom of the view. I am then attempting to animate this view's height so that it appears to slide down the screen. According to the constraint, the element should always be 10 pixels from the bottom of the view. This holds true when I add the view like so...
printView *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"printView"];
[self addChildViewController:vc];
vc.view.frame = CGRectMake(0, 60, vc.view.frame.size.width, HEIGHT);
vc.view.layer.masksToBounds = FALSE;
[vc.view.layer setShadowOffset:CGSizeMake(0.0, 5.0)];
[vc.view.layer setShadowOpacity:0.8];
vc.view.layer.shadowColor = [[UIColor blackColor] CGColor];
vc.view.layer.shadowRadius = 8;
vc.view.clipsToBounds = TRUE;
[self.view insertSubview:vc.view aboveSubview:docWebView];
I can change HEIGHT to whatever I want and the element is always 10 pixels from the bottom of the view. The problem comes when I try to animate the height
printView *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"printView"];
[self addChildViewController:vc];
vc.view.frame = CGRectMake(0, 60, vc.view.frame.size.width, 0);
vc.view.layer.masksToBounds = FALSE;
[vc.view.layer setShadowOffset:CGSizeMake(0.0, 5.0)];
[vc.view.layer setShadowOpacity:0.8];
vc.view.layer.shadowColor = [[UIColor blackColor] CGColor];
vc.view.layer.shadowRadius = 8;
vc.view.clipsToBounds = TRUE;
[self.view insertSubview:vc.view aboveSubview:docWebView];
[UIView animateWithDuration:5.0 animations:^{
vc.view.frame = CGRectMake(0, 60, vc.view.frame.size.width, 200);
[self.view setNeedsDisplay];
}];
The constraint is no longer honored and instead of the view sliding in with the element always 10 pixels from the bottom, it looks like the element is being uncovered because the element does not move with the view. I hope I am explaining this well enough. To put it another way, I'm going for the effect of a map being pulled down, but instead it looks like the map is already there and a piece of paper that is covering it is being pulled away. Thanks for your help.
When using constraints, you shouldn't be setting frames, you should be adjusting the constraints. When you initially set up your constraints, you should make an IBOutlet to the height constraint, and then animate its constant parameter in the animation block. If you had a height constraint called heightCon, you could do this:
[UIView animateWithDuration:5.0 animations:^{
self.heightCon.constant = 200
[self.view layoutIfNeeded];
}];
I'm not sure about your structure, that self.view might have to be vc.view instead.
After Edit:
This is the way to animate a height constraint, but I'm not sure that's what you want to do to accomplish the look you're after. I'm not really sure what to make of your last paragraph. If you're going for an effect of a map being pulled down, it seems like the bottom constraint needs to be either animated or eliminated.