Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by BogdanDude 1 · Nov 04, 2010 at 04:39 PM · objective-c

ObjectiveC: How to show a custom UIView on top of Unity

Hi!

I'd like to show a custom view on top of the Unity UIWindow (the main application window).

Here's the code for showing and hiding the view:

- (void) showCustomView { UnitySetAudioSessionActive(true); UnityPause(true);

     self._customUIViewController = [[UIViewController alloc] autorelease];
     [[self getTopApplicationWindow] addSubview:self._customUIViewController.view];

     if(self._customUIViewController != nil)
     {       
         FAWController *fawView = [[FAWController alloc] initWithAPIKey:@"d0d" delegate:self]; //some custom initialization
         [self._customUIViewController presentModalViewController:fawView animated:YES];
         [fawView release];
     }
 }

 -(void)hideCustomView {

     if(self._customUIViewController != nil)
     {       
         [self._customUIViewController dismissModalViewControllerAnimated:YES];      
     }
     [self._customUIViewController.view removeFromSuperview];

     self._customUIViewController = nil;


     UnityPause(false);
     UnitySetAudioSessionActive(true);
 }
 //helper function
 - (UIWindow*) getTopApplicationWindow
 {
     UIApplication* clientApp = [UIApplication sharedApplication];
     NSArray* windows = [clientApp windows];
     UIWindow* topWindow = nil;

     if (windows && [windows count] > 0)
         topWindow = [[clientApp windows] objectAtIndex:0];

     return topWindow;
 }

The View shows just fine, and it dismisses nicely when I close it, but then Unity doesn't receive any more input (as if something invisible is still being displayed on top).

I'm pretty new to Objective-C, and I'd appreciate any help on this, to dismiss the custom view properly.

Thanks a lot, Bogdan

Comment
Add comment · Show 3
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image brandonc · Nov 30, 2010 at 11:24 PM 0
Share

Did you ever resolve this issue?

avatar image ttiganik · Jun 02, 2011 at 09:14 PM 0
Share

I have the same problem with game center leaderboards

avatar image ChironeV · Jun 10, 2015 at 10:54 PM 0
Share

did anyone ever figure it out? Can I ask how you even got this code to happen? The manual tells me to write stuff in a c# class that doesn't even exist. [DllImport("__Internal")] just gives compile errors.

4 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by saofl · Jul 29, 2016 at 02:47 PM

I realize this is a really old thread, but there are still people watching it so I'll add my .02 cents. The issue you're seeing is because you are trying to present the view of one view controller in another view controller without using view controller containment.

What you need to do is get a reference to the topmost view controller, then add your custom view controller as a child of that controller. This informs the custom view controller that it's view will be managed by another controller.

Below is a code block that gives you an idea of how it works. I have a class I created for Unity code to call for my plugin. This file consists of 2 files iOSPluginClient.h and iOSPluginClient.mm. These files are located in the unity directory Assets/Plugins/iOS. The code sample below is from the .mm file.

Here's the code:

 #import "iOSPluginClient.h"
 #import <UIKit/UIKit.h>
 
 #import "DemoViewController.h"
 
 @interface iOSPluginClient()
 
 // tracker variable for when we add a contained view controller
 @property (nonatomic, strong) UIViewController *presentedController;
 
 @end
 
 @implementation iOSPluginClient
 
 
 +(instancetype) singleton
 {
     static id _sharedInstance = nil;
     static dispatch_once_t oncePredicate;
     dispatch_once(&oncePredicate, ^
                   {
                       _sharedInstance = [self new];
                   });
     return _sharedInstance;
 }
 
 
 -(void) showDemoView
 {
     // if you displayed as a contained controller and removed it then self.presentedController will be nil
     if (self.presentedController == nil)
     {
         // either load as contained controller or as presented controller
         // change this to see both ways of displaying your content then remove
         // when you know what you want to use
         BOOL loadAsContained = true;
         
         // this view controller is defined in a storyboard, get a reference to the containing storyboard
         UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
         
         // instantiate the view controller from the storyboard
         DemoViewController *demo = [storyboard instantiateViewControllerWithIdentifier:@"DemoVC"];
         
         if (loadAsContained)
         {
             // add this view controller as a contained controller (child) of the presented view controller
             [self addContainedController:demo];
         }
         else
         {
             // if you don't want to display as a child, and instead want to present the view controller
             // on top of the currently presented controller then use this method instead of the previous one
             [[self getTopViewController] presentViewController:demo animated:YES completion:nil];
         }
     }
     else
     {
         [self removeContainedController:self.presentedController];
     }
 }
 
 // condensed version
 - (UIWindow*) getTopApplicationWindow
 {
     // grabs the top most window
     NSArray* windows = [[UIApplication sharedApplication] windows];
     return ([windows count] > 0) ? windows[0] : nil;
 }
 
 
 - (UIViewController*) getTopViewController
 {
     // get the top most window
     UIWindow *window = [self getTopApplicationWindow];
     
     // get the root view controller for the top most window
     UIViewController *vc = window.rootViewController;
     
     // check if this view controller has any presented view controllers, if so grab the top most one.
     while (vc.presentedViewController != nil)
     {
         // drill to topmost view controller
         vc = vc.presentedViewController;
     }
     
     return vc;
 }
 
 
 -(void) addContainedController:(UIViewController*)controller
 {
     // get a reference to the current presented view controller
     UIViewController *parent = [self getTopViewController];
     
     // notify of containment
     [controller willMoveToParentViewController:parent];
     
     // add content as child
     [parent addChildViewController:controller];
     
     // set frame of child content (for demo inset by 100px padding on all sides)
     controller.view.frame = CGRectMake(100.0, 100.0, parent.view.bounds.size.width - 200.0, parent.view.bounds.size.height - 200.0);
     
     // get fancy, lets animate in
     controller.view.alpha = 0.0;
     
     // add as subview
     [parent.view addSubview:controller.view];
     
     // animation duration
     CGFloat duration = 0.3;
     
     // animate the alpha in and bring top views to top
     [UIView animateWithDuration:duration
                      animations:^
      {
          controller.view.alpha = 1.0;
      }
                      completion:nil
      ];
     
     // set our tracker variable
     self.presentedController = controller;
 }
 
 -(void) removeContainedController:(UIViewController*)controller
 {
     // if fade out our view here just because
     [UIView animateWithDuration:0.3
                      animations:^
      {
          controller.view.alpha = 0;
      }
                      completion:^(BOOL finished)
      {
          
          // inform the child it is being removed by passing nil here
          [controller willMoveToParentViewController:nil];
          
          // remove the view
          [controller.view removeFromSuperview];
          
          // remove view controller from container
          [controller removeFromParentViewController];
          
          // nil out tracker
          self.presentedController = nil;
      }];
 }
 
 }
 
 
 @end
 
 
 /*******************************************************
  */
 #pragma mark -    C String Helpers
 /*
  ********************************************************/
 
 
 // Converts C style string to NSString
 NSString* CreateNSString (const char* string)
 {
     if (string)
         return [NSString stringWithUTF8String: string];
     else
         return [NSString stringWithUTF8String: ""];
 }
 
 
 NSArray* ExplodeNSStringFromCString (const char* string)
 {
     if (string)
         return [[NSString stringWithUTF8String: string] componentsSeparatedByString:@","];
     else
         return [NSArray new];
 }
 
 // Helper method to create C string copy
 char* MakeStringCopy (const char* string)
 {
     if (string == NULL)
         return NULL;
     
     char* res = (char*)malloc(strlen(string) + 1);
     strcpy(res, string);
     return res;
 }
 
 
 
 extern "C"
 {
 // function definition, called from c# or javascript unity code
 void displayDemo()
     {
         // calls the method to display our view controller over the unity controller
         [[iOSPluginClient singleton] showDemoView];
     }
       
 }  // end of extern C block
 
 
 

The c# code I have to call my objective c code is in a file called TestPlugin.cs. The code from that file looks as follows:

 using UnityEngine;
 // We need this one for importing our IOS functions
 using System.Runtime.InteropServices;
 
 public class TestPlugin : MonoBehaviour
 {
     // Use this #if so that if you run this code on a different platform, you won't get errors.
     #if UNITY_IPHONE
 
     // For the most part, your imports match the function defined in the iOS code    
     [DllImport ("__Internal")]
     private static extern string showDemoView();
 
     #endif
 
     // Now make c# methods that can provide the iOS functionality
     static void ShowMyCustomView()
     {
         // We check for UNITY_IPHONE again so we don't try this if it isn't iOS platform.
     #if UNITY_IPHONE
         // Now we check that it's actually an iOS device/simulator, not the Unity Player. You only get plugins on the actual device or iOS Simulator.
         if (Application.platform == RuntimePlatform.IPhonePlayer)
         {
                 // this calls our native method defined above
             showDemoView();
         }
     #endif
     }
 
 void Update ()
     {
                 // for demo purposes, tap the screen to present the view controller
         if (Input.GetMouseButtonDown(0)) 
         {
                         // call unity function that triggers call to native iOS code
             ShowMyCustomView();
         } 
     }
 
 
 
 
 
 }

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Mollrow · May 24, 2019 at 06:18 PM 1
Share

Change

[DllImport ("__Internal")] private static extern string showDemoView();

to

[DllImport ("__Internal")] private static extern void showDemoView();

Took about a full day of debugging to notice this lol

avatar image
0

Answer by AlKir · Dec 15, 2010 at 10:28 PM

I had the similar task, and this post was very useful for me http://forum.unity3d.com/threads/56755-Unity-plugin-to-handle-loading-native-Cocoa-UI-s-with-ease

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by kannan_nile · Sep 01, 2011 at 01:18 PM

on the -(void)hideCustomView function set dismissModalViewControllerAnimated property to NO instead of YES, it works fine. Unity receives input fine.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by adfx01zoe · Jun 17, 2012 at 03:14 PM

I also have the same issue. I've tried setting the dismiss modal view : no but it doesn't work. Anyone has a solution ?

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

6 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How would I add OS X menu bar functions to a Unity app? 3 Answers

UnitySendMessage and NSString allocation 1 Answer

xcode view change from antialiased to aliased 0 Answers

How to open the Camera for Unity iPhone? 3 Answers

Does iOS UnitySendMessage queue up whilst loading scenes? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges