iPhone Swipe Gesture crash - iphone

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];

Related

How can we implement pagecurl animation in tableview?

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

in iOS5 my methods for switching pictures in gallery are bad

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) { ... }

Hide iAds on iPhone when there is no network connection

I am trying to include iAds in my app. It works fine when there is network connection but the iAds doesn't hide when the network is not available..please find the code below and help me..thanks for your time..
I included this code in viewDidLoad
static NSString * const kADBannerViewClass = #"ADBannerView";
if (NSClassFromString(kADBannerViewClass) != nil) {
if (self.adView == nil) {
self.adView = [[[ADBannerView alloc] init] autorelease];
self.adView.delegate = self;
self.adView.frame = CGRectMake(0,355,320,60);
self.adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
}
}
[self.view addSubview:self.adView];
Delegate methods:
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!self.bannerIsVisible) {
[UIView beginAnimations:nil context:NULL];
banner.frame = CGRectOffset(banner.frame, 0,10);
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (self.bannerIsVisible) {
[UIView beginAnimations:nil context:NULL];
banner.frame = CGRectOffset(banner.frame, 0, -10);
[UIView commitAnimations];
self.bannerIsVisible = NO;
NSLog(#"%#",error);
}
}
If I understand your code correctly, you are initially showing the banner. That is not correct. It is better to initially move the banner off-screen and then only move it on-screen when you receive bannerViewDidLoadAd: and back off-screen when you receive bannerView:didFailToReceiveAdWithError:.
This also has the advantage that your banner view does not initially show up empty. Which can happen if there is a slow network connection.
You can do like this
Hide banner during viewdidload and write this in .m file.
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error{
NSLog(#"Error loading iAd");
}
-(void)bannerViewDidLoadAd:(ADBannerView *)banner{
NSLog(#"Ad loaded");
self.banner.hidden = NO;
}
-(void)bannerViewWillLoadAd:(ADBannerView *)banner{
NSLog(#"Ad will load");
self.banner.hidden = NO;
}
-(void)bannerViewActionDidFinish:(ADBannerView *)banner{
NSLog(#"Ad did finish");
self.banner.hidden = NO;
}

how to animate image on shake effect?

I have implemented game application.In which i want to animate some area of images on shake effect.How it possible please give me advice.
Edit:
My excatly query is that:
In my game application there is one image.Now i am selected some area frame of image.now i am shaking iphone then only selected area of frame image must be animate.
Here is a skeleton ... then you can get more detail at the suggested docs. This is real simple-minded but has a randomization and you can instantiate with your own image. I created an image container as a UIViewController and in my main (either your AppDelegate or the RootViewController) you create the instance in viewDidLoad. The methods that have to be overloaded in your AppDelegate, (the code is at the end of the post) so it receives shakes, are:
viewWillAppear
viewDidAppear
viewWillDisappear
viewDidDisappear
canBecomeFirstResponder
becomeFirstResponder
nextResponder
You become a responder in viewWillAppear and you have to enable the device notifications (verified that there is a documented bug) so the motion methods get invoked.
motionBegan:withEvent
motionEnded:withEvent
I like to put an NSLog(#"%s", FUNCTION); statement in all my first-time written methods, that way I can quickly determine if something is missing to get my events, properly initialized, etc. Its just my style.
AnimatedImage.h isA ViewController
#interface AnimatedImage : UIViewController {
UIImageView *image;
UILabel *label;
float cx;
float cy;
float duration;
float repeat;
}
#property (nonatomic, retain) UIImageView *image;
#property (nonatomic, retain) UILabel *label;
-(id) initWithImageName: (NSString*) imageName;
-(IBAction) shake;
AnimatedImage.m
#include <stdlib.h>
#define random() (arc4random() % ((unsigned)RAND_MAX + 1))
#import "AnimatedImage.h"
#implementation AnimatedImage
#synthesize image;
#synthesize label;
-(id) initWithImageName: (NSString*) imageName {
NSLog(#"%s", __FUNCTION__);
image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageName]];
return self;
}
-(IBAction) shake {
cx = 0.90 + (random() % 10) / 100; // cx = 0.95;
cy = 0.90 + (random() % 10) / 100; // cy = 0.95;
duration = ( 5.0 + random() % 10) / 1000.0;
repeat = (65.0 + random() % 20);
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, cx, cy);
[UIView beginAnimations: #"identifier" context: #"shake"];
[UIView setAnimationDelegate:image.superclass];
[UIView setAnimationDuration: duration]; // 0.008];
[UIView setAnimationRepeatCount: repeat]; // 85.0];
[UIView setAnimationRepeatAutoreverses: YES];
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
[UIView commitAnimations];
}
-(IBAction) bounce {
image.transform = CGAffineTransformTranslate(image.transform, -20, -6);
[UIView beginAnimations: #"identifier" context: #"bounce"];
[UIView setAnimationDelegate:image.superclass];
[UIView setAnimationDuration: duration];
[UIView setAnimationRepeatCount: repeat];
[UIView setAnimationRepeatAutoreverses: YES];
image.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0);
[UIView commitAnimations];
}
#end
This "root or main" delegate is a UIViewController. I have left of detail to show its simplicity, but still left my 'trace' code that I find essential for first-time debugging. Also, as an aside, I believe you have to overload motionBegan, even if you only need the motionEnded event. I recall that my app did not work and then I added the motionBegan and it started to call motionEnded. It kinda' makes sense that it would be that way, but I don't have any documentation to back it up. A simple experiment after you get it working can confirm or deny my comment.
- (void)viewDidLoad {
[super viewDidLoad];
[super becomeFirstResponder];
.
.
.
NSLog(#"%s", __FUNCTION__);
NSLog(#"%s: I %s first responder! (%#)", __FUNCTION__, [self isFirstResponder] ? "am" : "am not", self);
.
.<created image in this ViewController's NIB using IB>
.
someImage = (UIImageView *) [self.view viewWithTag:TAG_SOMEIMAGE];
aniImage = [[AnimatedImage alloc] init];
aniImage.image = someImage;
}
-(void) viewWillAppear: (BOOL) animated{
NSLog(#"%s", __FUNCTION__);
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver: self
selector: #selector(receivedRotate:)
name: UIDeviceOrientationDidChangeNotification
object: nil];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
NSLog(#"%s", __FUNCTION__);
[super becomeFirstResponder];
assert( [self canPerformAction:#selector(motionEnded:withEvent:) withSender:self] );
}
- (void)viewWillDisappear:(BOOL)animated {
NSLog(#"%s", __FUNCTION__);
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver: self];
[[UIDevice currentDevice] endGeneratingDeviceOrientationNotifications];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
NSLog(#"%s", __FUNCTION__);
[super resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder {
NSLog(#"%s", __FUNCTION__);
return YES;
}
- (BOOL)becomeFirstResponder {
NSLog(#"%s", __FUNCTION__);
return YES;
}
- (UIResponder *)nextResponder {
NSLog(#"%s", __FUNCTION__);
return [self.view superview];
}
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(#"%s", __FUNCTION__);
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
NSLog(#"%s", __FUNCTION__);
if( [self isFirstResponder] ) {
[aniImage shake];
}
}
This code does work -- but if I snipped out too much detail, just ask and I will make certain to add enough to help you along. This was a really rewarding task for me and I am excited to share it with someone looking for some help in the same experience.
Have a look at LocateMe example code, one of the first samples in the SDK and use and change the bounce back to centre code.

TTThumbView/TTPhotoView no autorotation

In my app I try to use the TTphotoView, so in a ViewController I push the TTphotoView with my navigationController like this:
if(self.photoViewController == nil {
PhotoViewController *viewController = [[PhotoViewController alloc] init];
self.photoViewController = viewController;
viewController.hidesBottomBarWhenPushed = YES;
[viewController release];
}
[self.navigationController pushViewController:self.photoViewController animated:YES];
[self.navigationController  dismissModalViewControllerAnimated:YES]
the problem is when the user rotate the device on the PhotoViewController nothing happen.
EDIT : I can't believe people didn't have the same problem. If someone use the photoView in his application with his own navigation and not the TTNavigation can he tell me how did he push the ViewController?
I had the same problem.
I don't know why but TTScrollView deviceOrientationDidChange method in three20 code is commented out! If you uncomment it, it will work.
See the code here: http://github.com/facebook/three20/blob/master/src/TTScrollView.m
Have you overridden your application's:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
and returned YES for the landscape orientations?
My comment for willcodejavaforfood, as I told you I can force by doing something like for example that but too many problem inside, and the PhotoViewController of three20 must do it by himself so I don't want that:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedRotate:) name:UIDeviceOrientationDidChangeNotification object:nil];
}
-(void) receivedRotate: (NSNotification *) notification {
NSLog(#"ORIENTATION CHANGE");
UIDeviceOrientation interfaceOrientation = [[UIDevice currentDevice] orientation];
if(interfaceOrientation == UIDeviceOrientationLandscapeRight) {
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration: 0.5f];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.view.transform = CGAffineTransformIdentity;
self.view.transform = CGAffineTransformMakeRotation(-M_PI/2);
self.view.bounds = CGRectMake(0.0, 0.0, 480.0, 320.0);
self.view.center = CGPointMake(240.0f, 160.0f);
[UIView commitAnimations];
}
}