I have a xCode project generated by Unity3D (which includes a animation) and I've integrated vuforia SDK for displaying an animation (Augmented reality)
The issue that I got by now is to add the navigation between the camera screen and the dashboard of my app.
In int OpenEAGL_UnityCallback(UIWindow** window, int* screenWidth, int* screenHeight, int* openglesVersion) method I'm adding the back button pragmatically like:
if (wrapperObj == nil)
{
wrapperObj = [[WrapperClass alloc] init];
}
[backButton addTarget:wrapperObj action:#selector(goToDashBoard:) forControlEvents:UIControlEventTouchUpInside];
Pass it to a wrapper class
#interface WrapperClass : NSObject
#property (nonatomic, retain) UINavigationController *navigation;
-(void)goToDashBoard:(UIButton*)sender;
#end
void goToPreviousScreen()
{
}
#implementation WrapperClass
#synthesize navigation;
-(void) goToDashBoard:(UIButton*)sender
{
[[self navigation] popViewControllerAnimated:YES];
goToPreviousScreen();
}
#end
Can anyone point me to a solution how to make the navigation up and running?
UPDATE
When trying to pop the view in this way:
AppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.navigationController popToRootViewControllerAnimated:YES];
I get this log:
2012-12-05 16:20:45.502 arapp[5993:907] <HomeViewController: 0x246db00>
StopQCAR
(Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
Could not deactivate dataset.
(Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
Could not destroy dataset.
(Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
Could not deinitialize the tracker.
(Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
Could not deinitialize the tracker.
(Filename: /Applications/buildAgent/work/14194e8ce88cdf47/Runtime/ExportGenerated/iPhonePlayer-armv7/UnityEngineDebug.cpp Line: 43)
ghashtable.c:294: assertion 'hash != NULL' failed
If I understand your question correctly you are trying to modify the Unity built Xcode project by adding files, viewcontrollers, code, etc. to it. It's been my experience that this is not a good idea and you may be much better off building your app in Unity as much as possible. The moderators on Vuforia's forum strongly discourage it also. I built a Unity/Vuforia app this way, mostly to avoid spending the time learning how to do it in Unity with C#. I ended up with a memory leak I couldn't track down and had to bite the bullet and go back to Unity and learn Unity scripting. Of course there are many iOS things you can't do in Unity, and I have no idea what your app does, but there are many plugins that can help you, and I ended learning how to write my own plugins to get some iOS functionality I needed.
However, if you want to navigate between the AR view and other view controllers the way I did it was by making another viewController that was basically an overlay and contained just the button for navigation. Then I initialized it and added it as a subview to the UnityViewController. Then you add the code to go to whatever view you want, like your dashboard.
// Init Vuforia VC, then add its view as subview to "view" AR view, line 524
VuforiaViewController *vuforia = [[VuforiaViewController alloc] init];
// Create a full-screen window
_window = [[UIWindow alloc] initWithFrame:rect];
EAGLView* view = [[EAGLView alloc] initWithFrame:rect];
UnityViewController *controller = [[UnityViewController alloc] init];
sGLViewController = controller;
sGLView = view;
controller.view = view;
_splashView = [ [UIImageView alloc] initWithFrame: [[UIScreen mainScreen] bounds] ];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
_splashView.image = [UIImage imageNamed:SplashViewImage(UIInterfaceOrientationPortrait)];
}
else
{
_splashView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
_splashView.autoresizesSubviews = YES;
}
[view addSubview:_splashView];
[view addSubview:vuforia.view]; // Overlay view added as subview of AR view
As you may know you can comment out startUnity() in the AppController to prevent the AR view from coming up when the app starts, and call it in another VC to get back to the AR view. This approach let me navigate between the AR view and several other VC's, but ultimately the app was unstable and had to be replaced with one built entirely in Unity. Maybe you can find a better way, but you may be better off diving into Unity and plugins, depending on what you want your app to do. Hope this helps.
Related
I use cocos2d combined with AdMob , nomarl my app work great, but after hit the advertising and return the game, it wrong layout, my game is landscape!
Things changes after AdMob is involved. AdMob has a AD type "movie". After clicking the ad, it popups a full screen mode, and play a movie, and then back to the game. The game changes, originally, it is landscape mode, and after back from ad, it seems to be portrait mode, and the game is scaled, everything looks bad. I have tried to update the view controller / CCDirector after back from ad, but it doesn't work.
A workaround found: just rotate the device to the counterpart landscape mode and everything goes well again.
Just wonder if there is any way to prevent telling customers rotate it manually?
Have you encountered this before?
_viewController = [[UIViewController alloc] init];
_viewController.view = [[CCDirector sharedDirector] openGLView];
_admobView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
_admobView.adUnitID = ADMOB_PUBLISHER_ID;
_admobView.delegate = self;
GADRequest *request = [GADRequest request];
request.testing = YES;
[_admobView setRootViewController:_viewController];
[_admobView loadRequest:request];
[_viewController.view addSubview:_admobView];
I had a similar issue before, and the cause was that I created a new UIViewController and set it as rootViewController for AdMob view - just like what you are doing:
_viewController = [[UIViewController alloc] init];
_viewController.view = [[CCDirector sharedDirector] openGLView];
...
[_admobView setRootViewController:_viewController];
This leads to layout problems when returning from some kinds of advertisement. What I am doing now in my app is like:
adMobView.rootViewController = [RootViewController sharedInstance];
[[[CCDirector sharedDirector] openGLView] addSubview:adMobView];
where [RootViewController sharedInstance] is a class method which returns the only instance of RootViewController in the app. For details please refer to my answer to another question: https://stackoverflow.com/a/10222956/1241690
(For cocos2d 2.x, the second line should be:
[[[CCDirector sharedDirector] view] addSubview:adMobView];
)
I have a UIImagePickerController (source type camera) that I use to take pictures. I have it put properly in my .h (added the #property) and .m (#synthesize). Here's what I use to show it:
if (thePicker == nil) {
thePicker = [[UIImagePickerController alloc] init];
thePicker.delegate = self;
thePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
thePicker.allowsEditing = NO;
}
[self presentModalViewController:thePicker animated:YES];
I'm having an odd problem. Every now and again, after closing/opening it a few times, the camera button OR the used button won't work (but the retake and cancel buttons work). I'm not getting any memory warnings and I have a dealloc and didReceiveMemoryWarnings void statement, but they don't get called.
ANyone else having this problem?
I have seen some apps cover it up with their overlay, but you can't remove it. AVCaptureSession really does sound more appropriate for your purposes. I see one example here:
http://www.musicalgeometry.com/?p=1273
Try this it may help u i guess Thanks!!
I have an shipped OpenGL game that I'm adding Game Center support to for a 1.1 rev. The game does not use a UIViewController and is coded as follows in the AppDelegate:
-(void)applicationDidFinishLaunching:(UIApplication *)application
{
window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[window setUserInteractionEnabled:YES];
[window setMultipleTouchEnabled:YES];
glView = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
[window addSubview:glView];
[window makeKeyAndVisible];
[glView performSelectorOnMainThread:#selector(mainGameLoop) withObject:nil waitUntilDone:NO];
}
Everything works great, but when Game Center brings up a window (GKAchievementViewController for example), the window animates on screen fine, but when I touch to scroll it, it doesn't have any of the momentum or bounce-back like normal windows. When I scroll the window past the top and bottom and it doesn't return with bounce back.
The window is fully functional, registers touches, it just behaves ugly.
I assume this is because some information is just not being sent down the pipe correctly because I don't have a UIViewController? I tried creating a UIViewController that sits in-between the UIWindow and the OpenGL UIView, but I get the same behavior.
This is how I'm creating the GKAchievementViewController dialog:
-(void)displayAchievements
{
achievmentsViewController = [[UIViewController alloc] init];
[glView addSubview:achievmentsViewController.view];
GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
if (achievements != nil)
{
achievements.achievementDelegate = self;
[achievmentsViewController presentModalViewController:achievements animated:YES];
}
[achievements release];
}
I don't use any of the UIKit in the game, all buttons, etc are done with straight OpenGL. I am also not using cocos2d or any other framworks.
In my main loop I am doing this:
while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.002, TRUE) == kCFRunLoopRunHandledSource);
Other than that, I am not making any regular calls into the OS.
Does anyone know what is going on? My game is ready to submit other than this problem and it's driving me crazy.
OK, I think I found the answer to this so I'm going to answer my own question in the hopes of saving others a lot of frustration.
The problem is CFRunLoopRunInMode. It doesn't play nice with UIKit. I switched to using CADisplayLink and all is well.
displayLink = [NSClassFromString(#"CADisplayLink") displayLinkWithTarget:self selector:#selector(mainLoopBody)];
[displayLink setFrameInterval:1];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
I've read that CADisplayLink is causing some games problems and there is a lot of debate about using it vs CFRunLoopRunInMode vs NSTimer. I'll use this for a while and see if it causes any problems, but windows scroll right again.
My one concern with CADisplayLink is if the frame rate starts to bog down. Under my old CFRunLoopRunInMode system, if the frames took longer the delta time reflected that. With CADisplayLink, I'm not sure if that is still the case.
Oh the fun of programming.
Ok here is the code that I wrote to display the UIImagePickerController in the camera source. I just declared the myPhotopicker in the header for the property and retain it. Synthesized it in the main code file. Then calling the picker I wrote the code below:
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
if (myPhotopicker==nil) {
myPhotopicker = [[UIImagePickerController alloc] init];
myPhotopicker.delegate = self;
}// create once!
myPhotopicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:myPhotopicker animated:NO];
}
Upon calling it, there are a few things that is weird happening to the app.
Sometimes, when there are many apps running in the background (iPhone4), the app would fail to load the camera and crash the app. Though it will load CameraRoll/PhotoAlbums without problem.
If the camera view is able to load (when there are less apps running in the background), tapping the Cancel button on the camera view results in the app rebooting itself (where the Default.png image is shown quickly, and back to the main page - like when we started the app).
I have been trying to figure out this problem, but not sure what to do... pls help.. Thanks.
here is the complete code of image pickercontrol try too find solu. here.
http://www.icodeblog.com/2009/07/28/getting-images-from-the-iphone-photo-library-or-camera-using-uiimagepickercontroller/
Regards,
Shyam Parmar
Rather than your 'create once' logic try creating and releasing each time.
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
myPhotopicker = [[UIImagePickerController alloc] init];
myPhotopicker.delegate = self;
myPhotopicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:myPhotopicker animated:NO];
[myPhotopicker release];
}
You should also implement the delegate to remove the modal view controller from view when it is dismissed (if you haven't already).
You should also check that the current class conforms to the UINavigationConrollerDelegate protocol.
I tried to create a SplashView which display the Default.png in the background and a UIProgressBar in front. But the splash screen is not being updated...
Inside my view controller I load first the splash view with a parameter how many steps my initialisation has and then I start a second thread via NSTimer and after each initialisation step I tell the SplashView to display the new progress value.
All looks good in theory, but when running this app the progress bar is not being updated (the method of the splash screen receives the values, I can see it in the logs). I also tried to add usleep(10000); in between to give the view updates a bit time and also instead of using the progress bar I drew directly on the view and called [self setNeedsDisplay]; but all didn't work :/
What am I doing wrong?
Thanks for your help!
Tom
Here is some code:
SPLASHSCREEN:
- (id)initWithFrame:(CGRect)frame withStepCount:(int)stepCount {
if (self = [super initWithFrame:frame]) {
// Initialization code
background = [[UIImageView alloc] initWithFrame: [self bounds]];
[background setImage: [UIImage imageWithContentsOfFile: [NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], #"Default.png"]]];
[self addSubview: background];
progressView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
[progressView setFrame:CGRectMake(60.0f, 222.0f, 200.0f, 20.0f)];
[progressView setProgress: 0.0f];
stepValue = 1.0f / (float)stepCount;
[self addSubview:progressView];
}
return self;
}
- (void)tick {
value += stepValue;
[progressView setProgress: value];
}
VIEWCONTROLLER:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
splashView = [[SplashView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 320.0f, 480.0f) withStepCount:9];
[self setView: splashView];
NSTimer* delayTimer;
delayTimer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:#selector(finishInitialization) userInfo:nil repeats:NO];
}
return self;
}
- (void)finishInitialization {
// do some stuff, like allocation, opening a db, creating views, heavy stuff...
[splashView tick]; // this should update the progress bar...
// do some stuff, like allocation, opening a db, creating views, heavy stuff...
[splashView tick]; // this should update the progress bar...
// init done... set the right view and release the SplashView
}
As mentioned in another answer, for some finite amount of time, as your app is being launched, Default.png is displayed and you have no control over it. However, if in your AppDelegate, you create a new view that displays the same Default.png, you can create a seamless transition from the original Default.png to a view that you can add a progress bar to.
Now, presumably, you have created a view or similar and you are updating a progress bar every so often in order to give the user some feedback. The challenge here is that your view is only drawn when it gets called to do a drawRect. If, however, you go from AppDelegate to some initialization code to a viewcontroller's viewDidLoad, without the run loop getting a chance to figure out which views need to have drawRect called on, then your view will never display its status bar.
Therefore in order to accomplish what you want, you have to either make sure that drawRect gets called, such as by pushing off a lot of your initialization code into other threads or timer tasks, or you can force the drawing by calling drawRect yourself, after setting up contexts and such.
If you go with the background tasks, then make sure your initialization code is thread-safe.
Default.png is just a graphic, a static image shown while the application is launching. If you want to show further progress, you'll have to show everything at the applicationDidLaunch phase. Show your modal "Splash Screen" there first (Create a view controller, add its view as a subview of your main window) and dismiss it when you are done whatever additional loading you needed to do.
Also, you need to do update your progress bar in a seperate thread. Updating your GUI in the same thread where a lot of business is going on is (in my opinion, but I could be wrong) a bad idea.
The main thread is, as far as I know, the only one that can safely do GUI things, and its event loop (that is, the main application thread's) is the one that does the actual displaying after you've called -setNeedsDisplay. Spawn a new thread to do your loading, and update the progress on the main thread.