Stack UITableView Cells on top of eachother - ios

I am creating an app where I am using a list view as a screen. When I click the item I want the items to "stack on eachother" (think of metal flaps),
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
int i = 0;
for(UITableViewCell *v in [self.tableView subviews])
{
NSLog(#"%d",i);
[UIView animateWithDuration:0.5 animations:^{
if(i == 0)
{
[v setFrame:CGRectMake(0, self.view.frame.size.height - 50 - (indexPath.row + 200)-i, self.view.frame.size.height, 100)];
}
} completion:^(BOOL finished) {
}];
[self.tableView setScrollEnabled:NO];
i++;
}
}
The table view cells do translate, how ever I cannot achieve the "semi overlapping effect", (I am guessing apple makes table view cells linear layouts relative to each other). Is there a way to override this and make them semi over lap at the bottom of the screen?

You can add a subview to the cell's contentView that extends below the bottom of the cell if you want it to overlap the cell below. Be sure to set the contentView's clipsToBounds property to NO (it's YES by default).

Related

Hide NavigationControllerBar when scrolling the tableview

I have implemented a UITableViewController.
The first section is a large image. When the view controller appeared initially, I set the navigationBar to be translucent.
When the tableview is scroll down, the navigationBar.translucent is set to NO and the tableview content frame is moved upwards so that the first section is out of the screen. I implemented the movement in the scrollview delegate :
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
When the tableview is scroll up, the navigation becomes translucent again and the tableview frame is restored.
The problem is, when the scrollview delegate catches the scroll gesture. Once the tableview and navigationBar begins the animation. The scroll action of the tableview stops. Therefore if I want to scroll the tableview to bottom I have to scroll twice, the first time animates the frames and then scroll again, and I think it can be enhanced.
Here is the code.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView == _subTable) {
NSIndexPath * indexPath ;
CGFloat offset = scrollView.contentOffset.y;
if ((offset - currentOffset)>40) {
if (!scrollAnimate) {
self.navigationController.navigationBar.translucent = NO;
[UIView animateWithDuration:0.5 animations:^{
[_mainTable setContentOffset:CGPointMake(0, headHeight) animated:YES];
[_subTable setFrame:CGRectMake(CGRectGetWidth(self.menuTable.frame) , 0, kScreen_Width/3.5*2.5, kScreen_Height-schedualHeight-48)];
[_mainTable setFrame:CGRectMake(0, 0, kScreen_Width, _mainTable.frame.size.height+headHeight)];
[_menuTable setFrame: CGRectMake(0, 0, kScreen_Width/3.5, _mainTable.frame.size.height+headHeight-48)];
}];
if (CGRectGetMaxY(_checkOutBar.frame)!= kScreen_Height-44)
{
[_checkOutBar setFrame:CGRectOffset(_checkOutBar.frame, 0, -44)];
}
scrollAnimate = !scrollAnimate;
frameOffset = !frameOffset;
[_mainTable reloadData];
_checkOutBar.tag = 1000;
}
}
else if((offset - currentOffset)<-40)
{
if (scrollAnimate) {
self.navigationController.navigationBar.translucent = YES;
[UIView animateWithDuration:0.5 animations:^{
[_mainTable setFrame:CGRectMake(0, 0, kScreen_Width, kScreen_Height+self.navigationController.navigationBar.frame.size.height+headHeight)];
[self.mainTable setFrame:CGRectOffset(_mainTable.frame, 0, -(self.navigationController.navigationBar.frame.size.height))];
[_subTable setFrame:CGRectMake(CGRectGetWidth(self.menuTable.frame), 0, kScreen_Width/3.5*2.5, tableHeight)];
[_menuTable setFrame:CGRectMake(0, 0, kScreen_Width/3.5, tableHeight)];
}];
scrollAnimate = !scrollAnimate;
frameOffset = !frameOffset;
[_mainTable reloadData];
if (CGRectGetMaxY(_checkOutBar.frame)!= kScreen_Height) {
[_checkOutBar setFrame:CGRectOffset(_checkOutBar.frame, 0, 44)];
}
_checkOutBar.tag = 2000;
}
}
if ((offset - currentOffset)>0)
{
indexPath = [[_subTable indexPathsForVisibleRows]lastObject];
}
else
{
indexPath = [[_subTable indexPathsForVisibleRows]firstObject];
}
if (indexPath) {
if (indexPath.row == 0) {
selected = indexPath.section;
[_menuTable reloadData];
}
}
currentOffset = offset;
}
}
From Apple documents. set NavigationController. hidesBarsOnSwipe = YES;
hidesBarsOnSwipe
Property
A Boolean value indicating whether the navigation bar hides its bars in response to a swipe gesture.
Declaration:
SWIFT:
var hidesBarsOnSwipe: Bool
OBJECTIVE-C:
#property(nonatomic, readwrite, assign) BOOL hidesBarsOnSwipe
Discussion:
When this property is set to YES, an upward swipe hides the navigation bar and toolbar. A downward swipe shows both bars again. If the toolbar does not have any items, it remains visible even after a swipe. The default value of this property is NO.
Availability:
Available in iOS 8.0 and later.

animating UITableViewHeader to grow/shrink

Im very new to iOS and am trying to figure out how I can animate the tableView header to appear like its sliding down from the top of the view, stay there for 3 seconds, then slide back up and disappear.
I havent done any animation of any kind before so I could really use some help. I dont know where to start. Ive looked at other answers on here but cant seem to figure out how to do it.
ive got my table view appearing just fine with this code in my viewDidLoad of my UITableViewController class
self.headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320,15)];
self.headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, 15)];
self.headerLabel.textAlignment = NSTextAlignmentCenter;
self.headerLabel.text = #"some text";
[self.headerView addSubview:self.headerLabel];
self.tableView.tableHeaderView = self.headerView;
self.tableView.tableHeaderView.frame = CGRectMake(0, 0, 320, 15);
I assume I need to animate the height of my frame.
edit: I found this code which seems like it should work, however it crashes my app when the animation runs
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView animateWithDuration:3.0f
delay:0.0f
options: UIViewAnimationOptionBeginFromCurrentState
animations:^{
self.headerView.frame = CGRectMake(0.0f, 0.0f, 320.f, 0.0f);
}
completion:^(BOOL finished) {
[self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}];
}
I don't know if you can animate a table view's header view like you want to. With a complex UI object like a Table view Apple tends to treat the views that make up the object as private, and bad things tend to happen when you try to manipulate the view hierarch.
If you're not using auto-layout and you want to animate another view that is part of YOUR view hierarchy then your code might be as simple as something like this:
CGPoint center = myView.center;
CGFloat myViewBottom = myView.frame.origin.y + myView.frame.origin.size.height;
//Move the view above the top of it's superview before starting the animation.
center.y -= myViewBottom;
//Animate the view down into position
[UIView animateWithDuration: .2
animations:
^{
myView.center += myViewBottom;
};
completion:
^{
//As the completion block for the first animation, trigger another
//animation to animate the view away again. This time delay
//for 3 second before the 2nd animation.
[UIView animateWithDuration: .2
delay: 3.0
options: 0
animations:
^{
myView.center -= myViewBottom;
};
completion: nil
}
];
Try to use beginUpdates and endUpdates, here is an example:
in your header
#property NSInteger newOffset;
implementation:
- (void) colapseHeader
{
_newOffset = 50;
[self.tableView beginUpdates];
[self.tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50 + _newOffset;
}
- (void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
_newOffset = 100;
[self.tableView beginUpdates];
[self.tableView endUpdates];
[self performSelector:#selector(colapseHeader) withObject:nil afterDelay:3];
}

View doesn't appear as expected

Theoretically the following code should animate the table view cell of the screen to the right and bring in a dark "view" in it's place.
CGPoint location = [gesture locationInView:tableView];
NSIndexPath *swipedIndexPath = [tableView indexPathForRowAtPoint:location];
UITableViewCell *swipedCell = [tableView cellForRowAtIndexPath:swipedIndexPath];
//code to create view
UIView *sideView;
sideView.backgroundColor = [UIColor lightGrayColor];
//set the side view frame to the same as the cell
sideView.frame = swipedCell.frame;
//add it to the tableview
[tableView addSubview:sideView];
[UIView animateWithDuration:1
animations:^{
sideView.frame = CGRectMake(0, swipedCell.frame.origin.y, swipedCell.frame.size.width, swipedCell.frame.size.height);
// While simultaneously moving the cell's frame offscreen
// The net effect is that the side swipe view is pushing the cell offscreen
swipedCell.frame = CGRectMake(swipedCell.frame.size.width, swipedCell.frame.origin.y, swipedCell.frame.size.width, swipedCell.frame.size.height); //move cell off
}];
However, only the cell moves off the screen. No gray view comes in it's place.
Is there a step I am missing? What is wrong with this code?
Video of example here
The big error is that you're not initializing sideView to anything.
Try UIView* sideview = [[UIView alloc] initWithFrame:swipedCell.frame];
It doesn't sound like a good idea to add a view in place of a cell just like that. You'd have to deal with scrolling, table view editing, and other stuff that the UITableView takes care of for you. So instead, try adding the sideView as a subview of swipedCell.contentView and then doing this animation instead:
[UIView animateWithDuration:1 animations:^{
sideView.frame = CGRectMake(0, swipedCell.frame.origin.y, swipedCell.frame.size.width, swipedCell.frame.size.height);
//This moves all the subviews except for the sideView off the screen
for (UIView *subview in swipedCell.contentView.subviews)
if (![subview isEqual:sideView])
subview.frame = CGRectOffset(subview.frame, swipedCell.frame.size.width, 0.0);
}];
Hope this helps!

UITableView reorder button covering the entire cell

I've been trying to use this tutorial to make the reorder button cover the entire cell. It works great until the cell disappears from the view. Once you go back to the cell, the reorder button has shifted over quite a bit.
In this picture, the red represents the reorder button.
Here's the code used in the tutorial.
- (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Grip customization code goes in here...
for(UIView* view in cell.subviews)
{
if([[[view class] description] isEqualToString:#"UITableViewCellReorderControl"])
{
UIView* resizedGripView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
[resizedGripView addSubview:view];
[cell addSubview:resizedGripView];
[resizedGripView release];
CGSize sizeDifference = CGSizeMake(resizedGripView.frame.size.width - view.frame.size.width, resizedGripView.frame.size.height - view.frame.size.height);
CGSize transformRatio = CGSizeMake(resizedGripView.frame.size.width / view.frame.size.width, resizedGripView.frame.size.height / view.frame.size.height);
// Original transform
CGAffineTransform transform = CGAffineTransformIdentity;
// Scale custom view so grip will fill entire cell
transform = CGAffineTransformScale(transform, transformRatio.width, transformRatio.height);
// Move custom view so the grip's top left aligns with the cell's top left
transform = CGAffineTransformTranslate(transform, -sizeDifference.width / 2.0, -sizeDifference.height / 2.0);
[resizedGripView setTransform:transform];
for(UIImageView* cellGrip in view.subviews)
{
if([cellGrip isKindOfClass:[UIImageView class]])
[cellGrip setImage:nil];
}
}
}
}
How do I keep the reorder control from moving to the left? I've tried to translate the transform again, but that just makes it so the reorder control is completely off the screen. What's wrong with the code that makes it move to the left and how do I fix it?
I figured out how to do it! I had to add a property to the viewController that stored the initial frame of the resizedGripView. It turns out that every time the method was being called (every time the cell appeared again), the reorder button was being moved from it's current position, so I had to store it's initial position.
UIView* resizedGripView = [[UIView alloc] init];
if (!initialFrame.size.height)
[resizedGripView setFrame: CGRectMake(0, 0, CGRectGetMaxX(view.frame), CGRectGetMaxY(view.frame))];
else
[resizedGripView setFrame: initialFrame];
if (!initialFrame.size.height)
[self setInitialFrame: resizedGripView.frame];

Animation of UILabel's frame (and other views' frames) in UITableViewCell

Please help. Trying to get animation of frame position working inside a UITableViewCell, specifically I'm trying to move the default UILabel (cell.textLabel). However, no matter what technique I use, I can't get any view inside the cell to move. The animation of colour and alpha works as outlined by the code below.
Cheers in advance for help.
Andy
Here is the code I am using:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0 && indexPath.row == 0) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect textLabelFrame = cell.textLabel.frame;
textLabelFrame.origin.x = -textLabelFrame.size.width;
[UIView animateWithDuration:0.5
delay:0.0
options:UIViewAnimationCurveEaseOut
animations:^{
cell.textLabel.frame = textLabelFrame; // THIS DOESN'T WORK - HELP!
cell.imageView.frame = CGRectOffset(cell.imageView.frame,0,0); // EVEN TRYING TO MOVE IMAGEVIEW DOESN'T WORK
cell.textLabel.alpha = 0; // This animates
cell.imageView.backgroundColor = [UIColor redColor]; // This animates
}
completion:^(BOOL finished){
NSLog(#"Done!");
}];
}
}
I don't think it's possible to reposition the default label or image view in a standard cell. If you want to do that, you should add your own subviews to the cell's contentView, and do your animations with those.

Resources