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.
Related
After I had set an image to an UIButton called bigIcon, I put it inside animateWithDuration with the change of its frame, then I ran the code, the button size changed instantly (has no animation), but it move from origin to destination slowly (has animation), how can I solve this problem? I found out that if I did set an image to the button this problem will disappear.
here is the code:
- (void)bigImage:(MCGodCell *)godCell withImage:(UIImage *)image {
self.bigIcon = [UIButton new];
self.bigIcon.adjustsImageWhenHighlighted = NO;
[self.bigIcon setBackgroundImage:image forState:UIControlStateNormal];
CGFloat iconX = self.tableView.frame.size.width / 2.0;
CGFloat iconY = self.tableView.frame.size.height / 2.0;
self.bigIcon.frame = CGRectMake(iconX, iconY, 1, 1);
[self.tableView addSubview:self.bigIcon];
CGFloat iconW = self.tableView.frame.size.width;
CGFloat iconH = iconW;
iconY = (self.view.frame.size.height - iconH) / 2.0;
[UIView animateWithDuration:0.3 animations:^{
self.bigIcon.frame = CGRectMake(0, iconY, iconW, iconH);
}];
}
You're not seeing the frame change because you're trying to animate it immediately after adding it to the view hierarchy.
UIKit needs to add the button as a subview, and then run the animation on the next UI update pass.
Wrap your animation block inside a dispatch_async block like this:
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.3 animations:^{
self.bigIcon.frame = CGRectMake(0, iconY, iconW, iconH);
}];
});
I have a view controller with a view that doesn't fill the screen and has transparency around the edges. In said view I have a tableview, some buttons and a text field.
I have all of the controls attached to the bottom of the view with constraints and the tableview attached to the top.
Everything resizes fine when the device is put in landscape/portrait mode, but when I manually resize it when the keyboard appears, the bottom of the view just moves up and covers the lowest elements.
Resizing/animation code:
- (void)keyboardDidShow:(NSNotification *)notification {
//Stuff to get keyboard frames
void (^animations)() = ^() {
CGRect mainViewFrame = self.mainView.frame;
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = tableViewFrame.size.height - 50;
mainViewFrame.size.height = mainViewFrame.size.height - 50;
CGFloat paddingOffset = self.view.frame.size.height - self.mainView.frame.origin.y - self.mainView.frame.size.height;
mainViewFrame.origin.y = (mainViewFrame.origin.y - keyboardEndFrame.size.height + paddingOffset - 8);
self.mainView.frame = mainViewFrame;
[self.tableView setNeedsLayout];
[self.mainView setNeedsLayout];
};
[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:^(BOOL finished){
if (finished) {
NSLog(#"Finished animating");
self.acceptBottomConstraint.constant = 5;
self.cancelBottomConstraint.constant = 5;
}
}];
}
This is my UI in the Storyboard:
This is what it looks like after resizing:
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.
I have a UITableView embedded in a UIView. When a cell is selected, the TableView slides left using UIView Animation so that details underneath can be displayed. When I slide the tableview back to its original frame, the table view can be scrolled over the top of the other elements in the Warpper View. Before the animation, you could only scroll the tableview cells up and down within the boundaries of the tableview. Why is this happening?
- (void)slideTableView:(BOOL)reset
{
//Current pos
CGRect newTableViewFrame = self.tableView.frame;
//Determine direction based on current pos
int newX;
if (reset || newTableViewFrame.origin.x < 0) {
newX = newTableViewFrame.origin.x=0;
}
else {
newX = newTableViewFrame.origin.x - 280;
}
newTableViewFrame.origin.x =newX;
CGFloat animationDuration = 0.2;
CGFloat animationDelay = 0.0;
[UIView animateWithDuration:animationDuration delay:animationDelay options:UIViewAnimationOptionCurveEaseInOut
animations:^{
self.tableView.frame=newTableViewFrame;
}
completion:^(BOOL finished){
}];
}
I had added a shadow to the view earlier and used:
self.clipsToBounds = NO;
self.layer.masksToBounds = NO;
Simply setting back fixes the above:
self.clipsToBounds = YES;
self.layer.masksToBounds = YES;
I have created a UIView with a UIToolbar both programmatically and with IB. I try to resize the UIView but the tool bar resizes first and make it obvious that there are 2 views. Can anyone tell me how to resize both view simultaneously so that it give the appearance that the UIView and toolbar are one? I have set all the appropriate masks. The code below is called on the UIView from the UIView class.
Thanks!!!
[UIView animateWithDuration: .3 animations:^ {
CGRect frame = self.frame;
frame.origin.x = 0;
frame.origin.y = 20;
frame.size.height = 900;
frame.size.width = 768;
self.frame = frame;
}];
Animate both at the same time:
[UIView animateWithDuration: .3 animations:^ {
toolbar.frame = CGRectMake(0.0, 20.0, 900.0, 768.0);
self.frame = CGRectMake(0.0, 20.0, 900.0, 768.0);
}];
Or use some NSLayoutConstraint to achieve equal frames.