Hi @reuk I’ve actually implemented a minor change (see below) to the JUCE codebase, which puts the UIScheme implementation under JUCE control, which is I guess where we’d all like it ![]()
My motivation for doing the work below, was just in case that resolved my issue - but it didn’t. That means that I’m pretty certain that the issue in question, somehow, is in my own code. I just can’t figure it out. It is just a real stinker - but that is my problem!
Note: app initialisation is moved to UISceneDelegate:willConnectToSession:connectionOptions
On a side note, when the app rotates, this is called:
- (void)windowScene:(UIWindowScene *_Nonnull)windowScene didUpdateCoordinateSpace:(id<UICoordinateSpace>_Nonnull)previousCoordinateSpace interfaceOrientation:(UIInterfaceOrientation)previousInterfaceOrientation traitCollection:(UITraitCollection *_Nonnull)previousTraitCollection
Add to the top of juce_Windowing_ios.mm …:
@interface MyUIScene : UIWindowScene
@end
@implementation MyUIScene
- (instancetype)initWithSession:(UISceneSession *)session connectionOptions:(UISceneConnectionOptions *)connectionOptions {
self = [super initWithSession:session connectionOptions:connectionOptions];
if (self) {
}
return self;
}
@end
@interface MyUISceneDelegate : NSObject<UIWindowSceneDelegate>
@end
@implementation MyUISceneDelegate
- (instancetype)init {
self = [super init];
if (self) {
}
return self;
}
// UISceneDelegate
- (void)scene:(UIScene *_Nonnull)scene willConnectToSession:(UISceneSession *_Nonnull)session options:(UISceneConnectionOptions *_Nonnull)connectionOptions {
if (JUCEApplicationBase::getInstance() == nullptr) {
if (auto* app = JUCEApplicationBase::createInstance())
{
if (! app->initialiseApp())
exit (app->shutdownApp());
}
else
{
jassertfalse; // you must supply an application object for an iOS app!
}
}
}
- (void)sceneDidDisconnect:(UIScene *_Nonnull)scene {
}
- (void)sceneDidBecomeActive:(UIScene *_Nonnull)scene {
}
- (void)sceneWillResignActive:(UIScene *_Nonnull)scene {
}
- (void)sceneWillEnterForeground:(UIScene *_Nonnull)scene {
}
- (void)sceneDidEnterBackground:(UIScene *_Nonnull)scene {
}
- (void)scene:(UIScene *_Nonnull)scene openURLContexts:(NSSet<UIOpenURLContext *> *_Nonnull)URLContexts {
}
- (nullable NSUserActivity *)stateRestorationActivityForScene:(UIScene *_Nonnull)scene {
return nil;
}
- (void)scene:(UIScene *_Nonnull)scene restoreInteractionStateWithUserActivity:(NSUserActivity *_Nonnull)stateRestorationActivity {
}
- (void)scene:(UIScene *_Nonnull)scene willContinueUserActivityWithType:(NSString *_Nonnull)userActivityType {
}
- (void)scene:(UIScene *_Nonnull)scene continueUserActivity:(NSUserActivity *_Nonnull)userActivity {
}
- (void)scene:(UIScene *_Nonnull)scene didFailToContinueUserActivityWithType:(NSString *_Nonnull)userActivityType error:(NSError *_Nonnull)error {
}
- (void)scene:(UIScene *_Nonnull)scene didUpdateUserActivity:(NSUserActivity *_Nonnull)userActivity {
}
// UIWindowSceneDelegate
- (void)windowScene:(UIWindowScene *_Nonnull)windowScene didUpdateCoordinateSpace:(id<UICoordinateSpace>_Nonnull)previousCoordinateSpace interfaceOrientation:(UIInterfaceOrientation)previousInterfaceOrientation traitCollection:(UITraitCollection *_Nonnull)previousTraitCollection {
}
- (void)windowScene:(UIWindowScene *_Nonnull)windowScene performActionForShortcutItem:(UIApplicationShortcutItem *_Nonnull)shortcutItem completionHandler:(void(^_Nonnull)(BOOL succeeded))completionHandler {
}
- (void)windowScene:(UIWindowScene *_Nonnull)windowScene userDidAcceptCloudKitShareWithMetadata:(CKShareMetadata *_Nonnull)cloudKitShareMetadata {
}
@end
// Replace this:
- (void) applicationDidFinishLaunching: (UIApplication*) application
{
ignoreUnused (application);
initialiseJuce_GUI();
// if (auto* app = JUCEApplicationBase::createInstance())
// {
// if (! app->initialiseApp())
// exit (app->shutdownApp());
// }
// else
// {
// jassertfalse; // you must supply an application object for an iOS app!
// }
}
// Add this (which initialises the UIScene)
- (UISceneConfiguration *)application:(UIApplication *)application
configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
UISceneConfiguration* result = [[UISceneConfiguration alloc] initWithName:@"MyUIScene" sessionRole:UIWindowSceneSessionRoleApplication];
result.sceneClass = MyUIScene.class;
result.delegateClass = MyUISceneDelegate.class;
return result;
}
In juce_UIViewComponentPeer_ios.mm
In UIViewComponentPeer::UIViewComponentPeer method…
Replace code as shown:
if (isSharedWindow)
{
window = [viewToAttachTo window];
[viewToAttachTo addSubview: view];
}
else
{
r = convertToCGRect (component.getBounds());
r.origin.y = [UIScreen mainScreen].bounds.size.height - (r.origin.y + r.size.height);
// window = [[JuceUIWindow alloc] initWithFrame: r];
// [((JuceUIWindow*) window) setOwner: this];
// Create window so that it is owned by the scene (scene should already be available)
bool bFoundScene = false;
UIApplication* sharedApplication = [UIApplication sharedApplication];
if (sharedApplication != nil) {
for (UIScene* scene in [sharedApplication connectedScenes]) {
if ([scene isKindOfClass: [UIWindowScene class]]) {
UIWindowScene* uiWindowScene = (UIWindowScene*)scene;
bFoundScene = true;
window = [[JuceUIWindow alloc] initWithWindowScene:uiWindowScene];
break;
}
}
}
if (bFoundScene == false) {
// Unexpected!
window = [[JuceUIWindow alloc] initWithFrame: r];
}
[((JuceUIWindow*) window) setOwner: this];
controller = [[JuceUIViewController alloc] init];
