Я хочу соответствовать UIAlertController, используемому в iOS 8, поскольку UIAlertView теперь устарел. Есть ли способ, которым я могу использовать это, не нарушая поддержку iOS 7? Есть ли какое-то условие, которое я могу выполнить, чтобы проверить iOS 8, иначе сделать что-то еще для поддержки iOS 7?
UIAlertController, если iOS 8, иначе UIAlertView
Ответы (10)
См. ответ Эрвана (под моим ответом), поскольку я вижу, что он лучший.
--
Вы можете проверить версию iOS, чтобы использовать соответствующий элемент управления, например:
if (([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] == NSOrderedAscending)) {
// use UIAlertView
}
else {
// use UIAlertController
}
Я думаю, что гораздо лучший способ проверить, существует ли класс (начиная с iOS 4.2):
if([ClassToBeChecked class]) {
// use it
} else {
// use alternative
}
В вашем случае это будет:
if ([UIAlertController class]) {
// use UIAlertController
} else {
// use UIAlertView
}
Задача C (как указано выше)
if ([UIAlertController class]) {
// use UIAlertController
} else {
// use UIAlertView
}
Быстрый
if objc_getClass("UIAlertController") == nil {
// use UIAlertView
} else {
// use UIAlertController
}
Не используйте if NSClassFromString("UIAlertController") == nil
. Он не работает, потому что сигнатура для этого метода func NSClassFromString(_ aClassName: String!) -> AnyClass!
.
Как уже упоминалось, всегда проверяйте, существует ли функция. Я считаю, что самый безопасный подход следующий:
if (NSClassFromString(@"UIAlertController")) {
// use UIAlertController
} else {
// use UIAlertView
}
С очевидным риском ввода имени класса с опечаткой. :)
Из документации NClassFromString:
[Возвращает] Объект класса с именем aClassName или nil, если класс с таким именем в настоящее время не загружен. Если aClassName равно nil, возвращает nil.
Доступность iOS (2.0 и выше)
Решение для проверки версии iOS в Swift
switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
case .OrderedAscending:
println("iOS < 8.0")
case .OrderedSame, .OrderedDescending:
println("iOS >= 8.0")
}
Минус этого решения: просто плохая практика сверяться с номерами версий ОС, как бы вы это ни делали. Никогда не следует жестко кодировать зависимости таким образом, всегда проверяйте функции, возможности или существование класса. Учти это; Apple может выпустить обратно совместимую версию класса, если они это сделают, то предлагаемый вами код никогда не будет использовать его, поскольку ваша логика ищет номер версии ОС, а НЕ существование класса.
Решение для проверки существования класса в Swift
if (objc_getClass("UIAlertController") == nil) {
// iOS 7
} else {
// iOS 8+
}
Не используйте if (NSClassFromString("UIAlertController") == nil)
, потому что он корректно работает на симуляторе iOS с использованием iOS 7.1 и 8.2, но если вы протестируете на реальном устройстве с iOS 7.1, вы, к сожалению, заметите, что никогда не пройдете через else часть фрагмента кода.
Создайте простой utility function
, чтобы сократить объем кода
КОД:
// pass minimum required iOS version
BOOL isOSSupported(NSString *minRequiredVersion)
{
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL isOSSupported = ([currSysVer compare:minRequiredVersion options:NSNumericSearch] != NSOrderedAscending) &&
![currSysVer isEqualToString:@"Unknown"];
return isOSSupported;
}
ИСПОЛЬЗОВАНИЕ:
if(isOSSupported("8.0")
{
// Code for iOS8 and above
}
else
{
// Code for iOS7 and below
}
Или используйте системную константу
NSFoundationVersionNumber_iOS_7_1
, как показано ниже
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1)
{
// Code for iOS8 and above
}
else
{
// Code for iOS7 and below
}
дополнительные параметры Link
Я создал очень простую обертку на Objective-C, которая поддерживает как старый iOS UIAlertView, так и новый UIAlertViewController
https://github.com/MartinPerry/UIAlert/
Это также приводит к использованию новых блоков действий в старом UIAlertView
.
Образец:
MyAlertMessage * a = [[MyAlertMessage alloc] initWithTitle:@"Hello" WithMessage:@"World"];
[a addButton:BUTTON_OK WithTitle:@"OK" WithAction:^(void *action) {
NSLog(@"Button OK at index 0 click");
}];
[a addButton:BUTTON_CANCEL WithTitle:@"Cancel" WithAction:^(void *action) {
NSLog(@"Button Cancel at index 1 click");
}];
[a show];
Я написал один класс, который обертывает UIAlertView и использует UIAlertController. Для программиста прозрачно, поэтому достаточно импортировать эти классы в проект. Полезность этих классов заключается в том, что в старом проекте нужно изменить больше UIAlertView. Ссылка: https://github.com/kennymuse/UIAlertView
Способ первый
по проверке версии системы ios
#define iOSVersionLessThan(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
// below ios8 ,create UIAlertView
if(iOSVersionLessThan(@"7.0")){
// todo
// ios8 and above ,UIActionController avaliable
}else{
// todo
}
Способ второй
по обнаружению системной функции
// create UIActionController
if([UIActionController class]){
// todo
// create UIAlertView
}else{
// todo
}
Но есть и третья библиотека с именем PSTAlertController, которая обеспечивает обратную совместимость с iOS 7 UIActionSheet и UIAlertView.
ссылка на
Попробуйте код ниже. Он отлично работает как для iOS 8, так и для более ранних версий.
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}
UIAlertView
. Это сделает ваш код намного проще. - person rmaddy   schedule 17.06.2014