Browse Source

iOS: show message boxes using the new UIAlertController APIs when supported, rather than the deprecated UIAlertView.

UIAlertController is also supported on tvOS, whereas UIAlertView is not.
Alex Szpakowski 10 years ago
parent
commit
ab2a350033

+ 9 - 5
src/joystick/iphoneos/SDL_sysjoystick.m

@@ -181,7 +181,7 @@ SDL_SYS_AddJoystickDevice(GCController *controller, SDL_bool accelerometer)
 #endif /* !SDL_EVENTS_DISABLED */
 }
 
-SDL_JoystickDeviceItem *
+static SDL_JoystickDeviceItem *
 SDL_SYS_RemoveJoystickDevice(SDL_JoystickDeviceItem *device)
 {
     SDL_JoystickDeviceItem *prev = NULL;
@@ -374,12 +374,14 @@ SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
 }
 
 /* Function to determine if this joystick is attached to the system right now */
-SDL_bool SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
+SDL_bool
+SDL_SYS_JoystickAttached(SDL_Joystick *joystick)
 {
     return joystick->hwdata != NULL;
 }
 
-static void SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
+static void
+SDL_SYS_AccelerometerUpdate(SDL_Joystick * joystick)
 {
     const float maxgforce = SDL_IPHONE_MAX_GFORCE;
     const SInt16 maxsint16 = 0x7FFF;
@@ -579,7 +581,8 @@ SDL_SYS_JoystickQuit(void)
     numjoysticks = 0;
 }
 
-SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
+SDL_JoystickGUID
+SDL_SYS_JoystickGetDeviceGUID( int device_index )
 {
     SDL_JoystickDeviceItem *device = GetDeviceForIndex(device_index);
     SDL_JoystickGUID guid;
@@ -591,7 +594,8 @@ SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
     return guid;
 }
 
-SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
+SDL_JoystickGUID
+SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
 {
     SDL_JoystickGUID guid;
     if (joystick->hwdata) {

+ 131 - 33
src/video/uikit/SDL_uikitmessagebox.m

@@ -24,15 +24,103 @@
 
 #include "SDL.h"
 #include "SDL_uikitvideo.h"
-
+#include "SDL_uikitwindow.h"
 
 /* Display a UIKit message box */
 
 static SDL_bool s_showingMessageBox = SDL_FALSE;
 
+SDL_bool
+UIKit_ShowingMessageBox()
+{
+    return s_showingMessageBox;
+}
+
+static void
+UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
+{
+    *clickedindex = messageboxdata->numbuttons;
+
+    @autoreleasepool {
+        /* Run the main event loop until the alert has finished */
+        /* Note that this needs to be done on the main thread */
+        s_showingMessageBox = SDL_TRUE;
+        while ((*clickedindex) == messageboxdata->numbuttons) {
+            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
+        }
+        s_showingMessageBox = SDL_FALSE;
+    }
+}
+
+static BOOL
+UIKit_ShowMessageBoxAlertController(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+#ifdef __IPHONE_8_0
+    int i;
+    int __block clickedindex = messageboxdata->numbuttons;
+    const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+    UIWindow *window = nil;
+    UIWindow *alertwindow = nil;
+
+    if (![UIAlertController class]) {
+        return NO;
+    }
+
+    UIAlertController *alert;
+    alert = [UIAlertController alertControllerWithTitle:@(messageboxdata->title)
+                                                message:@(messageboxdata->message)
+                                         preferredStyle:UIAlertControllerStyleAlert];
+
+    for (i = 0; i < messageboxdata->numbuttons; i++) {
+        UIAlertAction *action;
+        UIAlertActionStyle style = UIAlertActionStyleDefault;
+
+        if (buttons[i].flags & SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT) {
+            style = UIAlertActionStyleCancel;
+        }
+
+        action = [UIAlertAction actionWithTitle:@(buttons[i].text)
+                                          style:style
+                                        handler:^(UIAlertAction *action) {
+                                            clickedindex = i;
+                                        }];
+        [alert addAction:action];
+    }
+
+    if (messageboxdata->window) {
+        SDL_WindowData *data = (__bridge SDL_WindowData *) messageboxdata->window->driverdata;
+        window = data.uiwindow;
+    }
+
+    if (window == nil || window.rootViewController == nil) {
+        alertwindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
+        alertwindow.rootViewController = [UIViewController new];
+        alertwindow.windowLevel = UIWindowLevelAlert;
+
+        window = alertwindow;
+
+        [alertwindow makeKeyAndVisible];
+    }
+
+    [window.rootViewController presentViewController:alert animated:YES completion:nil];
+    UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
+
+    if (alertwindow) {
+        alertwindow.hidden = YES;
+    }
+
+    *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+    return YES;
+#else
+    return NO;
+#endif /* __IPHONE_8_0 */
+}
+
+/* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
 @interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
 
-@property (nonatomic, assign) int clickedIndex;
+@property (nonatomic, assign) int *clickedIndex;
 
 @end
 
@@ -40,52 +128,62 @@ static SDL_bool s_showingMessageBox = SDL_FALSE;
 
 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
 {
-    _clickedIndex = (int)buttonIndex;
+    if (_clickedIndex != NULL) {
+        *_clickedIndex = (int) buttonIndex;
+    }
 }
 
 @end
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
 
-
-SDL_bool
-UIKit_ShowingMessageBox()
-{
-    return s_showingMessageBox;
-}
-
-int
-UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+static BOOL
+UIKit_ShowMessageBoxAlertView(const SDL_MessageBoxData *messageboxdata, int *buttonid)
 {
+    /* UIAlertView is deprecated in iOS 8+ in favor of UIAlertController. */
+#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
     int i;
+    int clickedindex = messageboxdata->numbuttons;
     const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
+    UIAlertView *alert = [[UIAlertView alloc] init];
+    SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
 
-    @autoreleasepool {
-        UIAlertView *alert = [[UIAlertView alloc] init];
-        SDLAlertViewDelegate *delegate = [[SDLAlertViewDelegate alloc] init];
+    alert.delegate = delegate;
+    alert.title = @(messageboxdata->title);
+    alert.message = @(messageboxdata->message);
 
-        alert.delegate = delegate;
-        alert.title = @(messageboxdata->title);
-        alert.message = @(messageboxdata->message);
+    for (i = 0; i < messageboxdata->numbuttons; i++) {
+        [alert addButtonWithTitle:@(buttons[i].text)];
+    }
 
-        for (i = 0; i < messageboxdata->numbuttons; ++i) {
-            [alert addButtonWithTitle:@(buttons[i].text)];
-        }
+    delegate.clickedIndex = &clickedindex;
 
-        /* Set up for showing the alert */
-        delegate.clickedIndex = messageboxdata->numbuttons;
+    [alert show];
 
-        [alert show];
+    UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
 
-        /* Run the main event loop until the alert has finished */
-        /* Note that this needs to be done on the main thread */
-        s_showingMessageBox = SDL_TRUE;
-        while (delegate.clickedIndex == messageboxdata->numbuttons) {
-            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
-        }
-        s_showingMessageBox = SDL_FALSE;
+    alert.delegate = nil;
 
-        *buttonid = messageboxdata->buttons[delegate.clickedIndex].buttonid;
+    *buttonid = messageboxdata->buttons[clickedindex].buttonid;
+    return YES;
+#else
+    return NO;
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
+}
+
+int
+UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+    BOOL success = NO;
+
+    @autoreleasepool {
+        success = UIKit_ShowMessageBoxAlertController(messageboxdata, buttonid);
+        if (!success) {
+            success = UIKit_ShowMessageBoxAlertView(messageboxdata, buttonid);
+        }
+    }
 
-        alert.delegate = nil;
+    if (!success) {
+        return SDL_SetError("Could not show message box.");
     }
 
     return 0;

+ 0 - 2
src/video/uikit/SDL_uikitopengles.m

@@ -52,8 +52,6 @@
 
 @end
 
-static int UIKit_GL_Initialize(_THIS);
-
 void *
 UIKit_GL_GetProcAddress(_THIS, const char *proc)
 {

+ 0 - 2
src/video/uikit/SDL_uikitviewcontroller.h

@@ -47,9 +47,7 @@
 - (void)loadView;
 - (void)viewDidLayoutSubviews;
 - (NSUInteger)supportedInterfaceOrientations;
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)orient;
 - (BOOL)prefersStatusBarHidden;
-- (UIStatusBarStyle)preferredStatusBarStyle;
 
 #if SDL_IPHONE_KEYBOARD
 - (void)showKeyboard;

+ 0 - 6
src/video/uikit/SDL_uikitviewcontroller.m

@@ -135,12 +135,6 @@
     return (window->flags & (SDL_WINDOW_FULLSCREEN|SDL_WINDOW_BORDERLESS)) != 0;
 }
 
-- (UIStatusBarStyle)preferredStatusBarStyle
-{
-    /* We assume most SDL apps don't have a bright white background. */
-    return UIStatusBarStyleLightContent;
-}
-
 /*
  ---- Keyboard related functionality below this line ----
  */