I have a view controller which has a UITableView and a UIPageViewController. The UITableView's height is set to 0 at first. Upon clicking a button, the tableview should slide down(i.e., increase in height) and the PageViewController should be pushed down. I have done it like this...
float yPos = 61;
CGRect fr2 = self.pageController.view.frame;// UIPageViewController
CGRect fr1 = self.categoriesTable.frame; // UITableView
if (self.categoriesTable.frame.size.height == 0.0){
fr1.size.height = 44 * self.categories.count + 20; // categories is a datasource
yPos = yPos + 44 * self.categories.count + 20;
}else{
fr1.size.height = 0.0;
}
fr2.origin.y = yPos;
[UIView animateWithDuration:0.3 animations:^{
self.pageController.view.frame = fr2;
self.categoriesTable.frame = fr1;
}];
Expected Behavior: The tableview and the pageviewcontroller should both slide down at the same time.
Observed Behavior: Only the pageviewcontroller slides down. There is no change in table view's frame. However if you execute this method once again, then the Tableview slides down.
Can anyone help me with this ? Let me know if you need more information/code.
Ok, Looks like I fixed it. I decided to translate the pageviewcontroller back and forth to achieve the same effect. Below is the working code.
float yPos = 0;
CGRect fr2 = self.pageController.view.frame;
CGRect fr1 = self.categoriesTable.frame;
if (self.categoriesTable.frame.size.height == 0.0){
fr1.size.height = 44 * self.categories.count + 20;
yPos = 44 * self.categories.count + 20;
}else{
fr1.size.height = 0.0;
}
fr2.origin.y = yPos;
[UIView animateWithDuration:0.3 animations:^{
self.pageController.view.layer.affineTransform = CGAffineTransformMakeTranslation(0, yPos);
self.categoriesTable.frame = fr1;
}];
Related
I am having an app where I am hiding and showing tabbar on an event, below is the method I am using , when I try to hide it, it works fine . But when I am trying to make it visible it doesn't work.
-(void)setTabBarVisible:(BOOL)visible animated:(BOOL)animated completion:(void (^)(BOOL))completion {
// RootViewController* tabBarController = (RootViewController*)self.navigationController.parentViewController.parentViewController;
UITabBarController *tabBarController = self.tabBarController;
CGFloat duration = (animated)? 0.3 : 0.0;
CGRect frame = tabBarController.tabBar.frame;
CGFloat height = frame.size.height;
CGFloat offsetY = (visible)? -height : height;
CGRect playerFrame = player.view.frame;
CGRect toolBarFrame = self.toolbar.frame;
[UIView animateWithDuration:duration animations:^{
CGRect fr = CGRectOffset(frame, 0, offsetY);
tabBarController.tabBar.frame = fr;
if((!visible && ![self toolBarOnBottom]) || visible) {
self.toolbar.frame = CGRectOffset(toolBarFrame, 0, offsetY);
[self.toolbar layoutIfNeeded];
}
} completion:completion];
}
I when I debug code the second time I call this method to make it visible , the tabbar frame is zero , I think this is the problem. I am testing this on Xcode 9 with iOS 11 SDK. I am not sure if Safe area has anything to do with this.
Any help would be appreciated.
As I wanted to get a working solution , ended up using this , works perfect with autolayout and safe area
Hide UINavBar and UITabBar at the same time with animation
I did my Top View and Bottom View (UIViews) hide while the UITableView is scrolling. Now, I need to check if the user begin drag the UITableview to up again and back the uiviews for the initial position. I have the following code to do the first step: hidden/show while scrolling uitableview
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
if(!self.isScrollingFast) {
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
NSInteger yOffset = scrollView.contentOffset.y;
if (yOffset > 0) {
self.tabBar.frame = CGRectMake(self.tabBar.frame.origin.x, self.originalFrame.origin.y + yOffset, self.tabBar.frame.size.width, self.tabBar.frame.size.height);
self.viewTopo.frame = CGRectMake(self.viewTopo.frame.origin.x, self.originalFrameTopo.origin.y - yOffset, self.viewTopo.frame.size.width, self.viewTopo.frame.size.height);
if(self.originalFrameHidingView.origin.y - yOffset >= 0) {
self.hidingView.frame = CGRectMake(self.hidingView.frame.origin.x, self.originalFrameHidingView.origin.y - yOffset, self.hidingView.frame.size.width, self.hidingView.frame.size.height);
}
else {
self.hidingView.frame = CGRectMake(self.hidingView.frame.origin.x, -10, self.hidingView.frame.size.width, self.hidingView.frame.size.height);
}
[self.tbPertos setFrame:CGRectMake(self.tbPertos.frame.origin.x, self.hidingView.frame.origin.y + self.hidingView.frame.size.height, self.tbPertos.frame.size.width, self.tbPertos.frame.size.height)];
if(self.tbPertos.frame.size.height + self.tbPertos.frame.origin.y + yOffset <= screenHeight)
self.tbPertos.frame = CGRectMake(self.tbPertos.frame.origin.x, self.tbPertos.frame.origin.y, self.tbPertos.frame.size.width, self.tbPertos.frame.size
.height+yOffset);
else {
self.tbPertos.frame = CGRectMake(self.tbPertos.frame.origin.x, self.tbPertos.frame.origin.y, self.tbPertos.frame.size.width, screenHeight - self.tbPertos.frame.origin.y);
}
}
if (yOffset < 1) {
self.tabBar.frame = self.originalFrame;
self.viewTopo.frame = self.originalFrameTopo;
self.hidingView.frame = self.originalFrameHidingView;
self.tbPertos.frame = CGRectMake(self.tbPertos.frame.origin.x, self.hidingView.frame.origin.y + self.hidingView.frame.size.height, self.tbPertos.frame.size.width, screenHeight - self.tbPertos.frame.origin.y);
}
}
}
And there's the code which I'm trying to do the Top and Bottom View reappear when the user begin scroll up. Independently wheres the scroll offset.
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
CGPoint currentOffset = scrollView.contentOffset;
NSTimeInterval currentTime = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval timeDiff = currentTime - self.lastOffsetCapture;
CGFloat distance = currentOffset.y - self.lastOffset.y;
//The multiply by 10, / 1000 isn't really necessary.......
if (distance < 0) {
if(!self.isScrollingFast) {
NSLog(#"voltar posicao normal");
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:1.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
self.tabBar.frame = self.originalFrame;
self.viewTopo.frame = self.originalFrameTopo;
self.hidingView.frame = self.originalFrameHidingView;
self.tbPertos.frame = self.originalFrameTbPertos;
self.isScrollingFast = YES;
[UIView commitAnimations];
}
} else {
self.isScrollingFast = NO;
}
self.lastOffset = currentOffset;
self.lastOffsetCapture = currentTime;
}
Here i implemented code for UIView Hide / Show when tableview scrolling. When tableview scrolling down then UIView is hidden and when scrolling up then UIView show. I hope it's working for you...!
Step 1:- Make one property in .h file
#property (nonatomic) CGFloat previousContentOffset;
Step 2:- Write down this code in scrollViewDidScroll Method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat currentContentOffset = scrollView.contentOffset.y;
if (currentContentOffset > self.previousContentOffset) {
// scrolling towards the bottom
[self.subButtonView setHidden:YES];
} else if (currentContentOffset < self.previousContentOffset) {
// scrolling towards the top
[self.subButtonView setHidden:NO];
}
self.previousContentOffset = currentContentOffset;
}
I'm having a little problem about animations on iOS with Objective-c.
I'm trying to create a card game, and as the game start, the deck distributes the cards on the table, with an animation. The problem is that at the beginning the cards are all in row in the bottom side of the screen, then with the animation they distribute all over the table. But when I tap on anyone of them, they return in their initial position, although the game keeps on working because they flip and unflip over, as well as the score works properly. I'm attaching some snippets of the code and of the view.
Here are links to screenshots:
1)cards as the game starts: prntscr.com/68r8yj
2)cards at the end of initial animation: prntscr.com/68r92u
3)cards as I tap on any of them: prntscr.com/68r2hr
Here's my code snippet
-(void)viewDidAppear:(BOOL)animated {
CGPoint startPoint = {21, 34};
for(int i = 0; i < [self.cardsView count]; i++) {
FrenchPlayingCardView *view = [self.cardsView objectAtIndex:i];
int width = view.bounds.size.width;
int height = view.bounds.size.height;
CGRect newFrame = CGRectMake(startPoint.x, startPoint.y, width, height);
/*[UIView animateWithDuration:1.0
delay:1.0
options:UIViewAnimationOptionTransitionNone
animations:^(){
view.frame = newFrame;;
}
completion:nil];*/
[UIView beginAnimations:#"move" context:nil];
[UIView setAnimationDuration:3.0];
view.frame = newFrame;
[UIView commitAnimations];
NSLog(#"index:%d %f %f", i, view.frame.origin.x, view.frame.origin.y);
startPoint.x += 76;
if(i % 4 == 3) {
startPoint.y += 100;
startPoint.x = 21;
}
}
[super viewDidAppear:animated];
}
call [super viewDidAppear] before your animation and close autolayout. I think autolayout can cause this
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 a 1 row collections view with images
I scroll the images from right to left
I would like to make an animation for each cell coming from the right (ala Google+)
This animation could be based on Alpha or frame location
How to implement that ?
This may not be exactly what you want in your animations but here is what I've done in a UICollectionViewCell subclass. This will fade in the cell while the frame shrinks down to the appropriate size. I call the setPhoto method from within collectionView: cellForItemAtIndexPath:.
#implementation HistoryCollectionViewCell
- (void)setPhoto:(Photo*)photo {
if(_photo != photo) {
_photo = photo;
}
// Set up the animations here
self.photoQueue.alpha = 0.0f;
self.cellContainerView.alpha = 0.0f;
CGRect currentFrame = self.cellContainerView.frame;
CGFloat width = currentFrame.size.width + 20;
CGFloat height = currentFrame.size.height + 20;
CGFloat originX = currentFrame.origin.x - 10;
CGFloat originY = currentFrame.origin.y - 10;
CGRect newFrame = CGRectMake(originX, originY, width, height);
self.cellContainerView.frame = newFrame;
dispatch_queue_t photoQueue = dispatch_queue_create("com.jeremyfox.SnapTo.photoQueue", NULL);
dispatch_async(photoQueue, ^{
__block UIImage* image = nil;
if (_photo) {
image = [Photo getImageAtPath:_photo.thumbnail];
}
dispatch_async(dispatch_get_main_queue(), ^{
if (image) {
self.imageView.image = image;
// Perform the animations here
[UIView animateWithDuration:0.3f animations:^{
self.cellContainerView.alpha = 1.0f;
self.cellContainerView.frame = currentFrame;
}];
}
});
});
}