In my app there are some UICollectionViewCells displaying some info.
When the user taps a button on one of them, I flip the tapped cells with this piece of code:
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
[UIView animateWithDuration:1.0
delay:0
options:(UIViewAnimationOptionAllowUserInteraction)
animations:^
{
NSLog(#"starting animation");
[UIView transitionFromView:cell.contentView
toView:cell.contentView
duration:.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
completion:^(BOOL finished)
{
NSLog(#"animation end");
}
];
After the cell flips (which is does correctly) the cell is completly white.
Two questions about is:
- why is the cell white after the flip. Shouldn't it display the original info since the fromView is equal to the toView?
- what is the best way to display different content on the back of the cell. I suppose UICollectionViewCell doesn't have something link cell.contentViewBack...
you may have this by now but,
Not sure if this is the 'Best' way to do it, I got this to work by creating a custom UICollectionViewCell, having 2 UIImageViews in the custom cell, and targeting those views in the animation (this only works for you if thats all you want to have in your cells - may help, may not, anywho)
Create new UICollectionViewCell class (mine is called CardCVCell)
In the CardCVCell.h put in you UIImageView outlets
#property (strong, nonatomic) IBOutlet UIImageView *cardImage;
#property (strong, nonatomic) IBOutlet UIImageView *cardBackImage;
I used storyboard - in there I typed in 'CardCVCell' as my custom class on the cell in the Collection View in my scene.
In my View Controller for that scene I have the code you have above, but I use the UIImageViews in the custom cell for the views in the transition (note you have to cast the UICollectionViewCell to your custom class
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
// animate the cell user tapped on
CardCVCell *cell = (CardCVCell *)[collectionView cellForItemAtIndexPath:indexPath];
[UIView transitionFromView:cell.cardBackImage
toView:cell.cardImage
duration:.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:^(BOOL finished)
{
if (finished) {
NSLog(#"animation end");
}
}
];
}
I hope this helps someone if not you, if I can help let me know.
cheers
Related
Hi guys i'm new in this group, i want to create an app that have a tableview cotroller as main controlle and when touch the cell open a tableview in a uiview controller that have a button to add item. How can i do to make a correct flow of data?
In order to do that, several things need to be done.
1.a) In the storyboard, create your tableView Controller and your viewController. Create also a cocoa touch file for both of your controllers.
1.b) Inside the ViewController, add a object 'tableView' and add an outlet for this object.
Then in the 'ViewDidLoad' method of your ViewController, set tableView.delegate = self and tableView.dataSource = self.
Your ViewController has to inherit from 2 protocols (class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource) This will add two functions, to handle the datas displayed in the tableView of your second ViewController.
1.c) Create a generic segue (by control dragging from the tableView Controller to the ViewController) and name it 'YourSegue'
2) In the tableview controller, override the function: override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) and add the following line: performSegue(withIdentifier: "YourSegue", sender: nil) which will open the second ViewController.
3) If, additionally, you wanna send datas from the first TableView Controller to your second ViewController, you should override the method 'prepare(for segue:)' which allows you to instantiate variables of your secondviewController.
Hope this helps.
I have a iPad app, created in XCode 4.6.3, iOS 6.2, ARC and Storyboards.
I create a UIPopover programmatically in SubViewData.m.
#property (strong, nonatomic) UIPopoverController *popover;
// make rectangle to attach popover
CGRect rectangle = CGRectMake( touchPoint.x, touchPoint.y, 110, 1); // 0 height puts arrow on exact touch point
// get addressability to storyboard ViewController
UIViewController *popoverMainView = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"menuView"];
popover = [[UIPopoverController alloc] initWithContentViewController:popoverMainView];
[popover presentPopoverFromRect:rectangle inView:self
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I set notifications in another class (QuickAppointment.m) when a UIButton in the popover has been tapped. I get the notification and issue this code from CalendarViewController.m :
SubViewData *svd = [[SubViewData alloc] init];
[svd.popover dismissPopoverAnimated:YES];
Nothing happens! I don't understand why not... so, what am I doing wrong?
Look at the code you are writing:
SubViewData *svd = [[SubViewData alloc] init];
This creates a completely new and different instance of SubViewData, and not the one that is displaying the popover.
With XCode 4.6 building for iOS 6.1, I'm using a UICollectionView from a storyboard, and I thought that the class implemented scrolling by default. I have made a simple test app with a storyboard that has just a Collection View and one Collection View Cell, and code that implements just collectionView:cellForItemAtIndexPath: and collectionView:numberOfItemsInSection:, calling for enough cells so that scrolling is required to see all the cells.
I thought that with nothing else, I would be able to scroll vertically within the UICollectionView. It shows the visible cells but doesn't scroll. What am I missing here?
Why wouldn't this component allow me to scroll vertically, what am I unable to see?
The implementation code is about as simple as possible:
//
// TestpViewController.h
//
#import <UIKit/UIKit.h>
#interface TestpViewController : UIViewController <UICollectionViewDataSource, UICollectionViewDelegate>
#end
//
// TestpViewController.m
//
#import "TestpViewController.h"
#interface TestpViewController ()
#property (weak, nonatomic) IBOutlet UICollectionView *collectionView;
#end
#implementation TestpViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return 30;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"testCell" forIndexPath:indexPath];
return cell;
}
#end
I just ran into a problem where when I'm adding a new view to my UIViewController there is a small gap on the top. (Appears to be the height of the status bar)
I use pushViewController to show this view, like this:
MapViewController *map = [[[MapViewController alloc] init] autorelease];
[self.navigationController pushViewController:map animated:YES];
In my MapViewController I just create a MKMapView with the same frame as the view controller.
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
_mapView = [[MKMapView alloc] initWithFrame:self.view.frame];
[self.view addSubview:_mapView];
}
But it turns out to be like this:
I'm not sure if I'm still missing something here ...
Try this instead:
_mapView = [[MKMapView alloc] initWithFrame:self.view.bounds];
The frame of a UIView is in the co-ordinate system of the superview.
The bounds of a UIView, on the other hand, is in the co-ordinate system of the view itself.
In this case, the frame of self.view will be taking into account the status bar (as that's how it sits on the screen) - hence the status bar sized offset at the top.
I am loading a UITableView cell from a nib file in a UITableViewController and the background color that I set in Interface Builder is not being displayed. Why not?
You should use tableView:willDisplayCell:forRowAtIndexPath: to set a background color, as Apple recommends in the Table View Programming Guide for iOS:
A table view sends a tableView:willDisplayCell:forRowAtIndexPath: message to its delegate just before it draws a row. If the delegate chooses to implement this method, it can make last-minute changes to the cell object before it is displayed. With this method, the delegate should change only state-based properties that were set earlier by the table view, such as selection and background color, and not content.
This code does an alternating "zebra stripe" effect:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row % 2 == 0) {
UIColor *altCellColor = [UIColor colorWithWhite:0.7 alpha:0.1];
cell.backgroundColor = altCellColor;
}
}