I finished the development of my app but at this point I face random crashes when I try to save an image in core data.
Here is the console message:
CoreData: error: Serious application error. Exception was caught
during Core Data change processing. This is usually a bug within an
observer of NSManagedObjectContextObjectsDidChangeNotification.
-[_PFExternalReferenceData compare:]: unrecognized selector sent to instance 0x94b69b0 with userInfo (null)
The problem is that it is non deterministic. It happens more or less once out of 5 times.
Would anyone have an idea where I should look for ?
EDIT:
Here is the code of my class that seems to pose a problem. It happens sometimes when I click on the save button, calling -(IBAction)saveResultingImage:
#import "ResultViewController.h"
#interface ResultViewController ()
#property (nonatomic)BOOL resultSaved;
#end
#implementation ResultViewController
#pragma mark - IBActions
- (IBAction)saveResultingImage
{
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
_resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_resultSaved = [self saveOnCoreData];
[self performSegueWithIdentifier:#"BackToStartSegue" sender:self];
}
- (IBAction)discardWithoutSaving
{
[self performSegueWithIdentifier:#"BackToStartSegue" sender:self];
}
- (IBAction)restartDrawing:(id)sender
{
UIImage *backgroundImage = _subImage;
UIImageView *imageView =
[[UIImageView alloc] initWithFrame:CGRectMake(0, 0, backgroundImage.size.width, backgroundImage.size.height)];
imageView.image = backgroundImage;
[self.view addSubview:imageView];
UIImage *maskImage = _maskImage;
CGRect maskViewRect = CGRectMake(0, 0, maskImage.size.width, maskImage.size.height);
ImageMaskView *subView = [[ImageMaskView alloc] initWithFrame:maskViewRect image:maskImage];
[self.view addSubview:subView];
}
- (IBAction)showExplainVC
{
[self performSegueWithIdentifier:#"ShowInfoSegue" sender:self];
}
#pragma mark - Methods
- (BOOL)saveOnCoreData
{
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newMeme =
[NSEntityDescription insertNewObjectForEntityForName:#"Meme" inManagedObjectContext:context];
NSData *toSaveMeme = UIImagePNGRepresentation(_resultImage);
[newMeme setValue:toSaveMeme forKey:#"image"];
NSError *error = nil;
if (![context save:&error]) {
DebugLog(#"Can't save: %# %#", error, [error localizedDescription]);
return NO;
}
return YES;
}
#pragma mark - View Controller LifeCycle
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
{
if ([identifier isEqualToString:#"BackToStartSegue"]) {
return _resultSaved;
}
return _resultSaved;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:NO];
DebugLog(#"Called viewWillAppear");
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
UIBarButtonItem *discardBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"Discard" style:UIBarButtonItemStylePlain target:self action:#selector(discardWithoutSaving)];
UIBarButtonItem *saveBarButtonItem =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:#selector(saveResultingImage)];
UIBarButtonItem *infoBarButton =
[[UIBarButtonItem alloc] initWithTitle:#"How to" style:UIBarButtonItemStylePlain target:self action:#selector(showExplainVC)];
discardBarButtonItem.style = UIBarButtonItemStyleBordered;
self.navigationItem.rightBarButtonItems = #[saveBarButtonItem, discardBarButtonItem, infoBarButton];
self.view.backgroundColor = [UIColor blackColor];
[self restartDrawing:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Core Data Stack
- (NSManagedObjectContext *)managedObjectContext
{
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:#selector(managedObjectContext)]) {
context = [delegate managedObjectContext];
}
return context;
}
#end
Thanks for showing interest :-)
Related
I have 1 tabbarcontroller have Login and Complete Tab. I want to click on Logout button in LoginTab, all data and tableview in COmplete tab is reset. I used this code but it not work:
In CompleteTab.m:
-(void) viewDidLoad
{
temp = [[NSMutableArray alloc] init];
iduploadArray= [[NSMutableArray alloc] init];
FileCompletedArray = [[NSMutableArray alloc] init];
DiffArr= [[NSMutableArray alloc] init];
_tableView = [[UITableView alloc] initWithFrame:self.view.bounds];
tableData = [[NSArray alloc] initWithObjects:FileCompletedArray,nil];
// [_tableView setAllowsSelection:YES];
//tableView.dataSource = self;
// [self.view addSubview:tableView];
// [self parseXMLFile:#"x"];
NSURL *url1 = [NSURL URLWithString:#"server.com"];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL: url1] ;
....
temp = [FileCompletedArray mutableCopy];
_tableView.dataSource = self;
_tableView.delegate=self;
[self.view addSubview:_tableView];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"error: %#", error);//: %#", operation.responseString);
}
];
[httpClient enqueueHTTPRequestOperation:operation];
}
-(void) resetAll
{
[temp removeAllObjects];
[FileCompletedArray removeAllObjects];
[DiffArr removeAllObjects];
[_tableView reloadData];
}
In LoginTab.m:
- (IBAction)LogoutButton:(id)sender {
login = false;
username.hidden = NO;
pass.hidden = NO;
LoginButton.hidden = NO;
LogoutButton.hidden = YES;
//make all the arrays get reset
username.text =#"";
pass.text = #"";
[completeview resetAll];
}
I debug: when I click on Logout button,it called resetAll() function but each variable is 0x000000. So it cannot reset data and reload tableview. Can you help me? Thanks
Since the logout button is in loginTab, it doesnot have any reference to your completeTab. So you need to keep the completeTab reference some where in your app. Best choice is in appDelegate. Then on logout button click, take this instance and reset all data.
Keep your completab view controller instance in AppDelegate like this
#property (nonatomic, retain) UIViewController *completeTab;
self.completeTab = \\Your complete tab viewcontroller instance.
Then on logout button click
[(AppDelegate *)[[UIApplication sharedApplication] delegate].completTab resetAll]
Hope this helps.
Use the selector to call the reset method like this
[completeview performSelector:#selector(resetAll)];
Please create sample project with Tabbased Application.
====== AppDelegate.m ======
#import "LoginTab.h"
#import "CompleteTab.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[[LoginTab alloc] initWithNibName:#"LoginTab" bundle:nil] autorelease];
UIViewController *viewController2 = [[[CompleteTab alloc] initWithNibName:#"CompleteTab" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[viewController1, viewController2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
#end
====== LoginTab.m ======
#implementation LoginTab
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"LoginTab", #"LoginTab");
self.tabBarItem.image = [UIImage imageNamed:#"LoginTab"];
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)LogoutButton:(id)sender {
// Post Notification to CompleteTab Class
[[NSNotificationCenter defaultCenter]
postNotificationName:#"resetAll"
object:self];
}
====== CompleteTab.m ======
#implementation CompleteTab
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"CompleteTab", #"CompleteTab");
self.tabBarItem.image = [UIImage imageNamed:#"CompleteTab"];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(resetAll:)
name:#"resetAll"
object:nil];
return self;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
- (void) resetAll:(NSNotification *) notification
{
NSLog(#"Reset All Called");
}
I am able to call resetAll method of CompeteTab using NSNotification Concept. Please follow this code.
I'd also recommend you check out the free Sensible TableView framework as it has such restting functionality out of box.
As for the method [tableView reloadData] : The table view's delegate or data source calls this method when it wants the table view to completely reload its data. It should not be called in the methods that insert or delete rows, especially within a block implemented with calls to beginUpdates and endUpdates.
I believe you are calling the reloadData in resetAll which is updating the FileCompletedArray which provides the dataSource for the table. Can you call it from somewhere else.
I have two UILabels, info and receiving. Receiving is suppose to tell me that I am actually receiving data. However, when it does indicate that.... my info UILabel is not being updated accordingly. It sometimes works and sometimes does not work..
What is up with that?
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
[super viewDidLoad];
receiving = [[UILabel alloc] initWithFrame: CGRectMake(30,50,255,100)];
info = [[UILabel alloc] initWithFrame: CGRectMake(30,200,255,100)];
info.backgroundColor = [UIColor orangeColor];
receiving.backgroundColor = [UIColor orangeColor];
// [self.view addSubview: toggleSwitch];
receiving.text = #"Not Receiving...";
[self.view addSubview: info];
[self.view addSubview: receiving];
}
return self;
}
- (void) startCommThread:(id)object
{
// NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// initialize RscMgr on this thread
// so it schedules delegate callbacks for this thread
rcsMgr = [[RscMgr alloc] init];
[rcsMgr setDelegate:self];
// run the run loop
[[NSRunLoop currentRunLoop] run];
// [pool release];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Create and start the comm thread. We'll use this thread to manage the rscMgr so
// we don't tie up the UI thread.
if (commThread == nil)
{
commThread = [[NSThread alloc] initWithTarget:self
selector:#selector(startCommThread:)
object:nil];
[commThread start]; // Actually create the thread
}
}
- (void) readBytesAvailable:(UInt32)numBytes {
receiving.text = #"Receiving...";
NSString* str = [rcsMgr getStringFromBytesAvailable];
if ( str ) receiving.text = #"I GOT SOMETHING!";
// if ( numBytes ) receiving.text = numBytes;
else receiving.text = #"Still Receiving...";
info.text = str;
}
Here's my best shot at an answer, with the caveat that I've never used RedPark's cable or SDK. My hunch is that -readBytesAvailable: is called by the RscMgr on the same background thread used to set it up. You can't use UIKit objects on background threads. You need transfer that work back to the main thread/queue something like this:
- (void)readBytesAvailable:(UInt32)numBytes
{
NSString* str = [rcsMgr getStringFromBytesAvailable];
dispatch_async(dispatch_get_main_queue(), ^{
if (str) {
receiving.text = #"I GOT SOMETHING!";
} else {
receiving.text = #"Still Receiving...";
}
info.text = str;
});
}
Also, you should have an autorelease pool on your commThread. Why did you comment it out?
I am using a custom progress view in Uiprogressview, and its being filled with a fixed color within 20 seconds, but I want such that it will be filled with the different color after 10 seconds, so that after 2 seconds it will look like a two colored circle,
here is my code:
#import "CEViewController.h"
#interface CEViewController ()
{
}
#end
#implementation CEViewController
#synthesize progressView;
#synthesize progressSlider;
#synthesize playPauseButton;
#synthesize player;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.player = [[[CEPlayer alloc] init] autorelease];
self.player.delegate = self;
UIColor *tintColor = [UIColor orangeColor];
[[UISlider appearance] setMinimumTrackTintColor:tintColor];
[[CERoundProgressView appearance] setTintColor:tintColor];
self.progressView.trackColor = [UIColor colorWithWhite:0.80 alpha:1.0];
self.progressView.startAngle = (3.0*M_PI)/2.0;
}
- (void)viewDidUnload
{
[self setProgressView:nil];
[self setProgressSlider:nil];
[self setPlayPauseButton:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)dealloc {
[progressView release];
[progressSlider release];
self.player = nil;
[playPauseButton release];
[super dealloc];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)progressSlider:(UISlider *)sender
{
self.player.position = sender.value;
self.progressView.progress = sender.value;
}
- (IBAction)playPauseButton:(UIButton *)sender
{
if(sender.selected) // Shows the Pause symbol
{
sender.selected = NO;
[self.player pause];
}
else // Shows the Play symbol
{
sender.selected = YES;
[self.player play];
}
}
// MARK: CEPlayerDelegate methods
- (void) player:(CEPlayer *)player didReachPosition:(float)position
{
self.progressView.progress = position;
self.progressSlider.value = position;
}
- (void) playerDidStop:(CEPlayer *)player
{
self.playPauseButton.selected = NO;
self.progressView.progress = 0.0;
self.progressSlider.value = 0.0;
}
#end
where should I make change to get my desired output, help please
Try this, replace otherColor with your 2nd half color. You may have to fix some syntax errors, my version of Xcode wont run on this computer so I couldn't check.
#import "CEViewController.h"
#interface CEViewController ()
{
UIColor *progressColor;
BOOL colorChanged;
}
#end
#implementation CEViewController
#synthesize progressView;
#synthesize progressSlider;
#synthesize playPauseButton;
#synthesize player;
#synthesize progressColor;
#synthesize colorChanged;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.player = [[[CEPlayer alloc] init] autorelease];
self.player.delegate = self;
self.progressColor= [UIColor orangeColor];
[[UISlider appearance] setMinimumTrackTintColor:self.progressColor];
[[CERoundProgressView appearance] setTintColor:self.progressColor];
self.progressView.trackColor = [UIColor colorWithWhite:0.80 alpha:1.0];
self.progressView.startAngle = (3.0*M_PI)/2.0;
colorChanged = false;
}
- (void)viewDidUnload
{
[self setProgressView:nil];
[self setProgressSlider:nil];
[self setPlayPauseButton:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (void)dealloc {
[progressView release];
[progressSlider release];
self.player = nil;
[playPauseButton release];
[super dealloc];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)progressSlider:(UISlider *)sender
{
self.player.position = sender.value;
if(sender.value >= 0.5 && colorChanged == false) {
self.progressColor= [UIColor otherColor];
[[UISlider appearance] setMinimumTrackTintColor:self.progressColor];
[[CERoundProgressView appearance] setTintColor:self.progressColor];
colorChanged = true;
}
self.progressView.progress = sender.value;
}
- (IBAction)playPauseButton:(UIButton *)sender
{
if(sender.selected) // Shows the Pause symbol
{
sender.selected = NO;
[self.player pause];
}
else // Shows the Play symbol
{
sender.selected = YES;
[self.player play];
}
}
// MARK: CEPlayerDelegate methods
- (void) player:(CEPlayer *)player didReachPosition:(float)position
{
self.progressView.progress = position;
self.progressSlider.value = position;
}
- (void) playerDidStop:(CEPlayer *)player
{
self.playPauseButton.selected = NO;
self.progressView.progress = 0.0;
self.progressSlider.value = 0.0;
}
#end
I'm finding it difficult to get started in Objective-C.
I'm executing the following code when a button is clicked:
NSLog(#"hi");
MainMenuDriver *mainMenuDriver= [[MainMenuDriver alloc] initWithNibName:nil bundle:nil];
[[self navigationController]pushViewController:mainMenuDriver animated:YES];
I can see "hi" in the console when I hit the button, it's just that the view should change to MainMenuDriver. But nothing happens!
Please help!
As per request for more code:
MainMenuDriver.h:
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface MainMenuDriver : UIViewController <UINavigationControllerDelegate,CLLocationManagerDelegate>{
IBOutlet UIButton *photos;
IBOutlet UIButton *profile;
IBOutlet UISwitch *onOffline;
IBOutlet UILabel *label1;
NSTimer *uploadGPS_timer;
CLLocationManager *lm;
NSString *lat;
NSString *lng;
}
#property(nonatomic,retain) UIButton *photos;
#property(nonatomic,retain) UIButton *profile;
#property(nonatomic,retain) UISwitch *onOffline;
#property(nonatomic,retain) UILabel *label1;
#property (nonatomic,retain) NSTimer *uploadGPS_timer;
#property(nonatomic,retain) NSString *lat,*lng;
-(IBAction)showMessages:(id)sender;
-(IBAction)showFriends:(id)sender;
-(IBAction)showPhotos:(id)sender;
-(IBAction)showProfile:(id)sender;
-(IBAction)switchSwitched:(id)sender;
-(void)uploadGPS_tick:(NSTimer*)timer;
#end
MainMenuDriver.m
#import "MainMenuDriver.h"
#import "ASIFormDataRequest.h"
#import "JoeMaxiViewController.h"
#import "Photos.h"
#import "Profile.h"
#implementation MainMenuDriver
#synthesize messages,profile,photos,friends,label1;
#synthesize onOffline;
#synthesize uploadGPS_timer;
#synthesize lat,lng;
-(IBAction)showPhotos:(id)sender{
[self.navigationItem setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil]];
Photos *x= [[Photos alloc] initWithNibName:nil bundle:nil];
[[self navigationController]pushViewController:x animated:YES];
}
-(IBAction)showProfile:(id)sender{
[self.navigationItem setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil]];
Profile *x= [[Profile alloc] initWithNibName:nil bundle:nil];
[[self navigationController]pushViewController:x animated:YES];
}
-(void)logout:(id)sender{
if([uploadGPS_timer isValid]){
[uploadGPS_timer invalidate];
}
[lm release];
//[uploadGPS_timer release];
[self.navigationController popViewControllerAnimated:NO];
/*NSString *urlStr=[[NSString alloc] initWithFormat:#"http://www.prestocab.com/driver/ajax/logout.php"];
NSURL *url=[NSURL URLWithString:urlStr];
__block ASIFormDataRequest *request=[[ASIFormDataRequest alloc ]initWithURL:url];
[request setDelegate:self];
[request setCompletionBlock:^{
NSString *response=[request responseString];
NSLog(#"%#",response);
}];
[request setFailedBlock:^{
}];
[request startAsynchronous];*/
}
-(IBAction)switchSwitched:(id)sender{
if(onOffline.on){
[label1 setText:#"For Hire"];
[label1 setTextColor:[UIColor colorWithRed:0.0 green:0.8 blue:0.0 alpha:1.0]];
uploadGPS_timer=[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(uploadGPS_tick:) userInfo:nil repeats:YES];
[self uploadGPS_tick:nil];
}else{
[label1 setText:#"Engaged"];
[label1 setTextColor:[UIColor colorWithRed:0.8 green:0.0 blue:0.0 alpha:1.0]];
if([uploadGPS_timer isValid]){
[uploadGPS_timer invalidate];
}
}
}
-(void)uploadGPS_tick:(NSTimer*)timer{
if(!lat || !lng){
//do nothing
}else{
NSString *urlStr=[[NSString alloc] initWithFormat:#"http://www.prestocab.com/driver/ajax/updateCoords.php"];
NSURL *url=[NSURL URLWithString:urlStr];
__block ASIFormDataRequest *request=[[ASIFormDataRequest alloc ]initWithURL:url];
[request setPostValue:lat forKey:#"lat"];
[request setPostValue:lng forKey:#"lng"];
NSLog(#"EOH: %#",lat);
[request setDelegate:self];
[request setCompletionBlock:^{
NSString *response=[request responseString];
NSLog(#"%#",response);
//do nothing
}];
[request setFailedBlock:^{
//NSError *error =[request error];
//do nothing
}];
[request startAsynchronous];
}
}
-(void)locationManager:(CLLocationManager*) manager didUpdateToLocation:(CLLocation *) newLocation fromLocation:(CLLocation*) oldLocation{
lat=[[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.latitude];
lng=[[NSString alloc]initWithFormat:#"%g",newLocation.coordinate.longitude];
NSLog(#"%#,%#",lat,lng);
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
self.navigationItem.title=#"PrestoCab";
UIBarButtonItem *anotherButton = [[UIBarButtonItem alloc] initWithTitle:#"Logout" style:UIBarButtonItemStylePlain target:self action:#selector(logout:)];
self.navigationItem.rightBarButtonItem = anotherButton;
[anotherButton release];
//GPS
lm=[[CLLocationManager alloc] init];
if([CLLocationManager locationServicesEnabled]){
lm.delegate=self;
lm.desiredAccuracy=kCLLocationAccuracyBest;
lm.distanceFilter=30.0f;
[lm startUpdatingLocation];
}
//[self check4messages_tick:nil]; //want to start immediately, not in 10/40 seconds' time
[self uploadGPS_tick:nil];
//check4messages_timer=[NSTimer scheduledTimerWithTimeInterval:40.0 target:self selector:#selector(check4messages_tick:) userInfo:nil repeats:YES];
uploadGPS_timer=[NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:#selector(uploadGPS_tick:) userInfo:nil repeats:YES];
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
if([uploadGPS_timer isValid]){
[uploadGPS_timer invalidate];
}
}
-(void)dealloc{
[super dealloc];
[uploadGPS_timer release];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
Also, here is
MyClassViewController.h:
#import <UIKit/UIKit.h>
#interface MyClassViewController : UINavigationController{
IBOutlet UIButton *passenger;
IBOutlet UIButton *driver;
}
#property (nonatomic,retain) UIButton *passenger;
#property (nonatomic,retain) UIButton *driver;
-(IBAction) passengerClicked:(id)sender;
-(IBAction) driverClicked:(id)sender;
#end
and MyClassViewController.m:
#import "MyClassViewController.h"
#import "MainMenuDriver.h"
#implementation MyClassViewController
#synthesize passenger;
#synthesize driver;
-(IBAction)passengerClicked:(id)sender{
NSLog(#"passenger");
}
-(IBAction)driverClicked:(id)sender{
NSLog(#"driver");
MainMenuDriver *mainMenuDriver= [[MainMenuDriver alloc] initWithNibName:nil bundle:nil];
[[self navigationController]pushViewController:mainMenuDriver animated:YES];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
I can see a couple of things:
Your nib file's name is different from the name of your class. If you put nil, the UIViewController will try to load a nib file with the UIViewController's name. Your UIViewController can be MainMenuDriver but your nib file name can be MainMenuDriverNibFileName.nib
[self navigationController] is nil.
For this, do the following:
NSLog(#"hi");
if([self navigationController]){
MainMenuDriver *mainMenuDriver= [[MainMenuDriver alloc] initWithNibName:nil bundle:nil];
[[self navigationController]pushViewController:mainMenuDriver animated:YES];
}
else{
NSLog(#"Houston we have a problem");
}
Update 1:
So, its nil, what you can do is the following:
Quick and Dirty:
[self presentViewController:mainMenuDriver animated:YES];
Instead of UIViewController switch to a UINavigationController.
I have looked at a few guides for CAKeyFrameAnimation and I am failing to see how to trigger them. The only thing I can think of is that I have to use it as a return, but that doesn't make much sense to me.
-H File-
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ImageSequenceViewController : UIViewController
<UIGestureRecognizerDelegate>{
UISwipeGestureRecognizer *swipeLeftRecognizer;
NSMutableArray *myImages;
IBOutlet UIImageView *imageView;
IBOutlet UIImageView *bView;
IBOutlet UISegmentedControl *segmentedControl;
}
#property (nonatomic, retain) UISwipeGestureRecognizer *swipeLeftRecognizer;
#property (nonatomic, retain) UIImageView *imageView;
#property (nonatomic, retain) IBOutlet UISegmentedControl *segmentedControl;
-(IBAction)takeLeftSwipeRecognitionEnabledFrom:(UISegmentedControl *)aSegmentedControl;
-(IBAction)ButtonPressed1: (id)sender;
#end
-M File-
#import "ImageSequenceViewController.h"
#implementation ImageSequenceViewController
#synthesize swipeLeftRecognizer;
#synthesize imageView;
#synthesize segmentedControl;
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
//CUSTOM CODE
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
-(void)loadLeft {
//aView = [[UIImageView alloc] initWithFrame:self.view.frame];
CALayer *layer = [CALayer layer];
[layer setFrame:CGRectMake(0.0,
0.0,
[[self view] frame].size.height,
[[self view] frame].size.width)];
myImages = [[NSMutableArray alloc] init];
for(NSUInteger count=0; count<100; count++){
NSString *fileName;
if (count < 10)
{
fileName = [NSString stringWithFormat:#"trailerRotation_000%d", count];
}
else if (10 <= count < 100)
{
fileName = [NSString stringWithFormat:#"trailerRotation_00%d", count];
}
else
{
fileName = [NSString stringWithFormat:#"trailerRotation_0%d", count];
}
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:#"jpg"];
//UIImage *image = [[UIImage alloc] initWithContentsOfFile:fileName];
//[myImages addObject:image];
[myImages addObject:[UIImage imageWithContentsOfFile:path]];
}
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"Contents"];
[anim setDuration:0.10];
[anim setCalculationMode:kCAAnimationDiscrete];
[anim setRepeatCount:1];
[anim setValues:myImages];
[self.view.layer addSublayer:layer];
[layer addAnimation:anim forKey:#"images"];
//aView.animationImages = myImages;
//aView.animationDuration = 10.00;
//aView.animationRepeatCount = 1;
}
-(void)loadRight {
bView = [[UIImageView alloc] initWithFrame:self.view.frame];
myImages = [[NSMutableArray alloc] init];
for(NSUInteger count=99; count>0; count--){
NSString *countString;
if (count < 10)
{
countString = #"000";
countString = [countString stringByAppendingFormat:#"%d", count];
}
else if (10 <= count < 100)
{
countString = #"00";
countString = [countString stringByAppendingFormat:#"%d", count];
}
else if (100 <= count < 1000)
{
countString = #"00";
countString = [countString stringByAppendingFormat:#"%d", count];
}
NSLog(#"%d", count);
NSString *fileName = #"trailerRotation_";
fileName = [fileName stringByAppendingFormat:countString];
fileName = [fileName stringByAppendingFormat:#".jpg"];
[myImages addObject:[UIImage imageNamed:fileName]];
}
bView.animationImages = myImages;
bView.animationDuration = 10.00;
bView.animationRepeatCount = 1;
}
- (void)viewDidLoad {
[super viewDidLoad];
imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
[imageView setImage:[UIImage imageNamed:#"trailerRotation_0000.jpg"]];
//[self.view addSubview:imageView];
[self loadLeft];
[self loadRight];
UIGestureRecognizer *recognizer;
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];
recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(handleSwipeFrom:)];
self.swipeLeftRecognizer = (UISwipeGestureRecognizer *) recognizer;
swipeLeftRecognizer.direction = UISwipeGestureRecognizerDirectionLeft;
if ([segmentedControl selectedSegmentIndex] == 0) {
[self.view addGestureRecognizer:swipeLeftRecognizer];
}
self.swipeLeftRecognizer = (UISwipeGestureRecognizer *) recognizer;
[recognizer release];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
self.segmentedControl = nil;
self.swipeLeftRecognizer = nil;
self.imageView = nil;
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[self becomeFirstResponder];
}
-(void)startItLeft {
NSLog(#"Left");
//[aView startAnimating];
//[self.view addSubview:aView];
//[aView release];
[bView release];
}
-(void)startItRight {
NSLog(#"Right");
[bView startAnimating];
[self.view addSubview:bView];
//[aView release];
[bView release];
}
//- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
//- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
//- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event {
//}
-(IBAction)ButtonPressed1:(id)sender
{
NSLog(#"Button");
//[aView stopAnimating];
[bView stopAnimating];
//[self loadLeft];
[self loadRight];
}
-(IBAction)takeLeftSwipeRecognitionEnabledFrom:(UISegmentedControl *) aSegmentControl {
if ([aSegmentControl selectedSegmentIndex] == 0) {
[self.view addGestureRecognizer:swipeLeftRecognizer];
}
else {
[self.view removeGestureRecognizer:swipeLeftRecognizer];
}
}
-(void)handleSwipeFrom:(UISwipeGestureRecognizer *) recognizer {
//CGPoint location = [recognizer locationInView:self.view];
//[self showImageWithText:#"swipe" atPoint:location];
if (recognizer.direction == UISwipeGestureRecognizerDirectionLeft) {
//[self startItLeft];
}
else {
[self startItRight];
}
}
//CUSTOM CODE
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)dealloc {
[super dealloc];
}
#end
I'm rather new to iOS development so any advice is helpful.
Thanks.
Try:
[myImages addObject:(id)[UIImage imageWithContentsOfFile:path].CGImage];
Since the CAKeyFrameAnimation expects CGImageRef objects.
It looks like you're trying to load up 100 images and cycle them all within the space of 0.1 second. Not only is that pretty ridiculous (that's 1000fps right there, and CoreAnimation is capped at 60fps), but it's likely to take longer than 0.1 seconds for CoreAnimation to copy all the images before it even starts, which means that it will have finished before it started (and therefore no animation will occur).
I'll admit it was a PEBKAC error.
Thanks all for your help.