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.
This commit is contained in:
Alex Szpakowski 2015-09-25 15:17:20 -03:00
parent 774b077513
commit ab2a350033
5 changed files with 147 additions and 55 deletions

View File

@ -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) {

View File

@ -24,41 +24,126 @@
#include "SDL.h"
#include "SDL_uikitvideo.h"
#include "SDL_uikitwindow.h"
/* Display a UIKit message box */
static SDL_bool s_showingMessageBox = SDL_FALSE;
@interface SDLAlertViewDelegate : NSObject <UIAlertViewDelegate>
@property (nonatomic, assign) int clickedIndex;
@end
@implementation SDLAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
_clickedIndex = (int)buttonIndex;
}
@end
SDL_bool
UIKit_ShowingMessageBox()
{
return s_showingMessageBox;
}
int
UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
static void
UIKit_WaitUntilMessageBoxClosed(const SDL_MessageBoxData *messageboxdata, int *clickedindex)
{
int i;
const SDL_MessageBoxButtonData *buttons = messageboxdata->buttons;
*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;
@end
@implementation SDLAlertViewDelegate
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (_clickedIndex != NULL) {
*_clickedIndex = (int) buttonIndex;
}
}
@end
#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 */
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];
@ -66,26 +151,39 @@ UIKit_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
alert.title = @(messageboxdata->title);
alert.message = @(messageboxdata->message);
for (i = 0; i < messageboxdata->numbuttons; ++i) {
for (i = 0; i < messageboxdata->numbuttons; i++) {
[alert addButtonWithTitle:@(buttons[i].text)];
}
/* Set up for showing the alert */
delegate.clickedIndex = messageboxdata->numbuttons;
delegate.clickedIndex = &clickedindex;
[alert show];
/* 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;
*buttonid = messageboxdata->buttons[delegate.clickedIndex].buttonid;
UIKit_WaitUntilMessageBoxClosed(messageboxdata, &clickedindex);
alert.delegate = nil;
*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);
}
}
if (!success) {
return SDL_SetError("Could not show message box.");
}
return 0;

View File

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

View File

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

View File

@ -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 ----
*/