Ha ii every body ,how can we implement a page-curl in tableview,i have a tableview which contains pages of the book and i have implement the touch events in the tableview cell for next chapter and previous chapter,left-swipe for next and right-swipe for previous chapter,when we swipe the tableview it reloads the next chapter and previous chapter content,it really works well but i want it in a page-curl animation,when the user swipe left or right tableview loads content with a page-curl animation.Is that possible to do in a tableview cell?my code for left and right swipe for chapter navigation as follows.
-(void) handleSwipeGesture:(UISwipeGestureRecognizer*)recognizer {
if(![delegate.selectedChapter isEqualToString:[NSString stringWithFormat:#"%d",[DbHandler mNumberOfChaptersInBook:delegate.selectedBook]]]) {
// if the currentChapter is the last then do nothing
delegate.selectedChapter = [NSString stringWithFormat:#"%d",[delegate.selectedChapter intValue] + 1];
[delegate reloadVerses];
[self resetReadViewToVerse:1];
[table removeGestureRecognizer:recognizer];
}
if (recognizer.state==UIGestureRecognizerStateBegan ) {
self.table.scrollEnabled = NO;
}
else if(recognizer.state==UIGestureRecognizerStateEnded) {
self.table.scrollEnabled = YES;
}
return;
}
-(void) handleSwipeGestureleft:(UISwipeGestureRecognizer*)recognizer {
if(![delegate.selectedChapter isEqualToString:#"1"])
{
delegate.selectedChapter = [NSString stringWithFormat:#"%d",[delegate.selectedChapter intValue] - 1];
[delegate reloadVerses];
[self resetReadViewToVerse:1];
[table removeGestureRecognizer:recognizer];
}
if (recognizer.state==UIGestureRecognizerStateBegan ) {
self.table.scrollEnabled = NO;
}
else if(recognizer.state==UIGestureRecognizerStateEnded) {
self.table.scrollEnabled = YES;
}
return;
}
Thanks in advance.
I got the answer.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.4];
[UIView setAnimationDelay:0.0];
[UIView setAnimationBeginsFromCurrentState:YES];
[UIView setAnimationDidStopSelector:#selector(animCompleteHandler:finished:context:)];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[UIView commitAnimations];
just put this code inside the methods.Thanks
Related
I have a subview named courseOptionsView that I want to show and hide with buttons and under certain conditions. When I use a swipe gesture the view works and is positioned correctly, but when I make the exact same call to the function with another button it repositions it, but it repositions it to the original position it was in instead of the coordinates I'm sending. :/ I'm stumped.
*edit
It seems that when I ++ or -- from cHNumber it resets subview. Any ideas?
IBOutlet UIView *courseOptionsView;
- (IBAction)nextHole:(id)sender;
- (IBAction)showCourseOptionsView:(id)sender;
- (IBAction)hideCourseOptionsView:(id)sender;
//show and hide functions
-(void) showCourseOptions{
if(activeRound){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[courseOptionsView setFrame:CGRectMake(50, 44, 200, 455)];
}
}
-(void) hideCourseOptions{
if(activeRound){
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[courseOptionsView setFrame:CGRectMake(-200, 44, 200, 455)];
}
}
// swipe calls
- (IBAction)showCourseOptionsView:(id)sender {
[self showCourseOptions];
}
- (IBAction)hideCourseOptionsView:(id)sender {
[self hideCourseOptions];
}
//button call
- (IBAction)nextHole:(id)sender
{
int totalStrokes = 0;
int totalPlusMinus = 0;
//[courseOptionsView setFrame:CGRectMake(0, 44, 200, 455)];
//[self showCourseOptions];
//save current hole
if(cHStrokes != [[currentRound objectForKey:[NSString stringWithFormat:#"hole%i",cHNumber]] intValue] ||
cHPutts != [[currentRound objectForKey:[NSString stringWithFormat:#"hole%i_putts",cHNumber]] intValue]){
[self saveCurrentHole];
}
// calculate and display +/- and strokes
for (int i = 0; i < ([currentRound count]/2); i++){
totalStrokes += [[currentRound objectForKey:[NSString stringWithFormat:#"hole%i",i+1]] intValue];
totalPlusMinus += [[[selectedScoreCardData objectAtIndex:0] objectForKey:[NSString stringWithFormat:#"hole%i_par",i+1]] intValue];
}
totalPlusMinus = totalStrokes - totalPlusMinus;
self.totalStrokesLabel.text = [NSString stringWithFormat:#"%i", totalStrokes];
self.totalPlusMinusLabel.text = [NSString stringWithFormat:#"%i",totalPlusMinus];
//set to next hole
/*-------------------
| SHOW VIEW HERE
--------------------*/
if(cHNumber == 17){
self.nextHoleButton.enabled = NO;
[self showCourseOptions];
}
if(cHNumber == 1){
self.prevHoleButton.enabled = YES;
}
cHNumber ++;
self.cHNumberLabel.text = [NSString stringWithFormat:#"%i", cHNumber];
[self populateScoreCard];
[strokePickerView reloadAllComponents];
if(([currentRound count]/2) < cHNumber){
[strokePickerView selectRow:cHStrokes - 1 inComponent:0 animated:YES];
[strokePickerView selectRow:0 inComponent:1 animated:YES];
}else{
[strokePickerView selectRow:[[currentRound objectForKey:[NSString stringWithFormat:#"hole%i",cHNumber]] intValue] - 1 inComponent:0 animated:YES];
[strokePickerView selectRow:[[currentRound objectForKey:[NSString stringWithFormat:#"hole%i_putts",cHNumber]] intValue] inComponent:1 animated:YES];
}
}
I think that maybe after you position the view you are calling another function that changes the layout again. A possible candidate is populateScoreCard.
I have a UIViewContoller with a few container(child) UIiewsController. The main UIViewController (mvc) contains:
1.) A UICollectionView that occupies the entire view of mvc (it is above mvc.view but below all other controls).
2.) A UIViewController that displays search options (s1vc)
3.) another similar to #2 (s2vc)
4.) another similar to #2 (s3vc)
I have added gesture recognizers to mvc so that a user can hide/show each of the child view controllers by swiping them off of the screen.
The problem is that when a user swipes any of the svcs off of the screen, they cannot scroll the mvc's collectionView.
Here is how I am hiding/showing the svcs:
-(void)swipeLeftGestureHandler:(UIGestureRecognizer*)gestureRecognizer{
SMLOG(#"Swiped Left");
if([SMUser activeUser] == nil) return;
if([self gestureHorizontalScreenSide:gestureRecognizer] == kHorizontalScreenSideLeft){
[self hideFacets];
}
else{
[self showAccordion];
}
}
-(void)swipeRightGestureHandler:(UIGestureRecognizer*)gestureRecognizer{
SMLOG(#"Swiped Right");
if([SMUser activeUser] == nil) return;
if([self gestureHorizontalScreenSide:gestureRecognizer] == kHorizontalScreenSideLeft){
[self showFacets];
}
else{
[self hideAccordion];
}
}
-(void)hideFacets{
if(self.facetVisible == NO) return;
[UIView animateWithDuration:0.25
animations:^{
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x - newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
self.facetVisible = NO;
}
completion:^(BOOL finished){
self.facetViewController.view.hidden = YES;
self.facetViewController.view.userInteractionEnabled = NO;
}];
}
-(void)showFacets{
if([SMUser activeUser] == nil) return;
if(self.facetVisible == YES) return;
self.facetViewController.view.userInteractionEnabled = YES;
[UIView animateWithDuration:0.25
animations:^{
self.facetViewController.view.hidden = NO;
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x + newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
self.facetVisible = YES;
}
completion:^(BOOL finished){
}];
}
As you can see I'm toggling the svc.view.hidden property and then I also tried toggling th svc.userInteractionEnabled.property but no luck. Still cannot swipe the collection view by swiping where the facets view controller was/is.
Any ideas?
The solution here is to add another outlet (using IB) for the container view in the parentViewController (I called it facetContainerView in this code) and then set it's userInteractionEnabled property.
-(void)hideFacets{
if(self.facetVisible == NO) return;
self.facetVisible = NO;
[UIView animateWithDuration:0.25
animations:^{
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x - newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
}
completion:^(BOOL finished){
self.facetViewController.view.hidden = YES;
self.facetContainerView.userInteractionEnabled = NO;
}];
}
-(void)showFacets{
if(self.facetVisible == YES) return;
self.facetVisible = YES;
self.facetContainerView.userInteractionEnabled = YES;
[UIView animateWithDuration:0.25
animations:^{
self.facetViewController.view.hidden = NO;
CGRect newFrame = self.facetViewController.view.frame;
newFrame.origin = CGPointMake(newFrame.origin.x + newFrame.size.width, newFrame.origin.y);
self.facetViewController.view.frame = newFrame;
}
completion:^(BOOL finished){
}];
}
I was curious as to how this new view outlet was different from self.facetViewController.view, so I inserted this code to compare addresses (they are different indeed). I'm not sure about the heirarchy, but it seems that there is an extra view layer that I was not aware of.
NSLog(#"self.facetViewController.view: %p", self.facetViewController.view);
NSLog(#"self.facetContainerView: %p", self.facetContainerView);
Hopefully this will help someone at some point.
I have some classes for watching pictures in gallery. in those classes after enabling ARC i get message that implicit conversion is forbidden by ARC and I cant run the application.
Those methods are:
- (void) curlToPrevious
{
if (currentImageIndex == 0) return;
if ([self.image2 superview] == NO) {
self.image2.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex-1)];
} else {
self.image1.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex-1)];
}
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kTransitionDuration];
currentImageIndex--;
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.containerView cache:YES];
if ([self.image2 superview] == NO) {
[self.image1 removeFromSuperview];
[self.containerView addSubview:self.image2];
} else {
[self.image2 removeFromSuperview];
[self.containerView addSubview:self.image1];
}
[UIView commitAnimations];
[self updateCurrentImageCounter];
}
- (void) curlToNext
{
if (currentImageIndex == ([self imageCount]-1)) return;
if ([self.image2 superview] == NO) {
self.image2.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex+1)];
} else {
self.image1.image = (UIImage*) [imageViews objectAtIndex:(currentImageIndex+1)];
}
currentImageIndex++;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:kTransitionDuration];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.containerView cache:YES];
if ([self.image2 superview] == NO) {
[self.image1 removeFromSuperview];
[self.containerView addSubview:self.image2];
} else {
[self.image2 removeFromSuperview];
[self.containerView addSubview:self.image1];
}
[UIView commitAnimations];
[self updateCurrentImageCounter];
}
I have
if ([self.image2 superview] == NO) {
In this line on 4 places in code problem.
The text I get is:
implicit conversion of 'int' to 'UIView' is disallowed with ARC
How can I avoid this??? Thanks.
you can replace your code on this if ([self.image2 superview] == nil)
You are comparing an UIView* with an integer (0) - of course you get a warning. Do you want to check whether the superview is nil? Then just do that:
if([self.image2 superview] == nil) { ... }
I have an app that I'd like the swipe gesture to flip to a second view. The app is all set up with buttons that work. The swipe gesture though causes a crash ( “EXC_BAD_ACCESS”.).
The gesture code is:
- (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"%s", __FUNCTION__);
switch (recognizer.direction)
{
case (UISwipeGestureRecognizerDirectionRight):
[self performSelector:#selector(flipper:)];
break;
case (UISwipeGestureRecognizerDirectionLeft):
[self performSelector:#selector(flipper:)];
break;
default:
break;
}
}
and "flipper" looks like this:
- (IBAction)flipper:(id)sender {
FlashCardsAppDelegate *mainDelegate = (FlashCardsAppDelegate *)[[UIApplication sharedApplication] delegate];
[mainDelegate flipToFront];
}
flipToBack (and flipToFront) look like this..
- (void)flipToBack {
NSLog(#"%s", __FUNCTION__);
BackViewController *theBackView = [[BackViewController alloc] initWithNibName:#"BackView" bundle:nil];
[self setBackViewController:theBackView];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:window cache:YES];
[frontViewController.view removeFromSuperview];
[self.window addSubview:[backViewController view]];
[UIView commitAnimations];
[frontViewController release];
frontViewController = nil;
[theBackView release];
// NSLog (#" FINISHED ");
}
Maybe I'm going about this the wrong way... All ideas are welcome...
Why are you even using performSelector: Just because a method is marked as an (IBAction) doesn't make it any different from any other method, and you can send them as messages to a class instance
- (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"%s", __FUNCTION__);
if ((recognizer.direction == UISwipeGestureRecognizerDirectionRight) || (recognizer.direction == UISwipeGestureRecognizerDirectionLeft)) {
[self flipper:nil]
}
}
Actually, since the gesture directions are just bit flags this can be written as:
- (void)handleSwipe:(UISwipeGestureRecognizer *)recognizer {
NSLog(#"%s", __FUNCTION__);
if (recognizer.direction & (UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft)) {
[self flipper:nil]
}
}
Your selector needs to take an argument as implied by the : character in the name, so you should use performSelector:withObject:.
[self performSelector:#selector(flipper:) withObject:nil];
Right I know how to do the pictue book effect but I struggling to remove the view
So page 1, I add the second page view via addSubview (via a swipe). I also increment a counter so I know what page I am on.
So how do I return to page 1? See I thought it would be self.view removeFromSuperview but that crashes when you try to go back to page 2
Code below
- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//NSLog(#"swipe right to left");
UniversalAppAppDelegate *appDelegate = (UniversalAppAppDelegate *)[[UIApplication sharedApplication] delegate];
PictureBookViewController *viewController2 =(PictureBookViewController *) [appDelegate getViewControllerForViewID:#"81"];
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
self.viewController = viewController2;
self.viewController.pageNo = self.pageNo + 1;
[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
[viewController2 release];
} else {
//NSLog(#"swipe left to right");
NSLog([NSString stringWithFormat:#"%d", self.pageNo]);
if (self.pageNo > 0) {
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];
//self.viewController = viewController2;
//self.viewController.pageNo = self.pageNo - 1;
//[self.view addSubview:self.viewController.view];
[self.view removeFromSuperview];
//[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
}
}
}
Update:
Each view has its own view controllers.
You want to remove your viewController's view, not the container's view.
[self.viewController.view removeFromSuperview];
This seems to work and not crash? I am now convinced it right. I just seem to need a way of removing the last added subview. My first view is not the superview
- (void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//NSLog(#"swipe right to left");
UniversalAppAppDelegate *appDelegate = (UniversalAppAppDelegate *)[[UIApplication sharedApplication] delegate];
PictureBookViewController *viewController2 =(PictureBookViewController *) [appDelegate getViewControllerForViewID:#"82"];
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view.superview cache:YES];
self.viewController = viewController2;
self.viewController.pageNo = self.pageNo + 1;
self.viewController.lastViewController = self;
[self.view addSubview:self.viewController.view];
[UIView commitAnimations];
[viewController2 release];
} else {
//NSLog(#"swipe left to right");
NSLog([NSString stringWithFormat:#"%d", self.pageNo]);
if (self.pageNo > 0) {
[UIView beginAnimations:Nil context:nil];
[UIView setAnimationDuration:0.6];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];
self.pageNo --;
self.view = self.viewController.view;
[self.view removeFromSuperview ];
self.view = self.lastViewController.view;
[UIView commitAnimations];
}
}
}