iOS-анимация перестает работать в моем приложении в iOS7
Я вижу, что все анимации ios в моем приложении перестают работать. Это происходит очень часто в iOS7.
Эй, ребята, у меня было приложение, которое поддерживает iOS 5, 6 и 7. Я недавно вижу, что все анимации iOS перестают работать в приложении в iOS7??
3 ответа
В IOS 7, когда какое-либо действие основного метода выполняется в фоновом потоке, анимации отключаются.
так что для этого вам нужно снова включить анимацию, как (Обходной путь)
[UIView setAnimationsEnabled:YES];
Может быть, это может помочь.
Я столкнулся с этой проблемой недавно с некоторыми представлениями, которые я выкладываю для расчета размера в фоновом потоке. Мошенником setAnimationsEnabled:
Я обнаружил, что единственный раз, когда я отключал анимацию из фонового потока, был в -[UIImageView setImage:]
,
Поскольку это представление никогда не отображалось, а изменения изображений не требовались для моих расчетов, я смог заключить этот тест в вызов основного потока:
if ([NSThread isMainThread]) {
self.answerImageView.image = [UIImage imageNamed:imgName];
}
Стоит отметить, что я не столкнулся с этой проблемой при первоначальном создании представления, потому что я уже загружал свои представления шаблона в главном потоке, чтобы избежать проблемы загрузки Xib.
Другие проблемы могут быть более сложными, но вы должны быть в состоянии найти аналогичные обходные пути. Вот категория, которую я использую, чтобы обнаружить отключение фона анимации.
#import <UIKit/UIKit.h>
#import <JRSwizzle/JRSwizzle.h>
#ifdef DEBUG
@implementation UIView (BadBackgroundBehavior)
+ (void)load
{
NSError *error = nil;
if (![self jr_swizzleClassMethod:@selector(setAnimationsEnabled:) withClassMethod:@selector(SE_setAnimationsEnabled:) error:&error]) {
NSLog(@"Error! %@", error);
}
}
+ (void)SE_setAnimationsEnabled:(BOOL)enabled
{
NSAssert([NSThread isMainThread], @"This method is not thread safe. Look at the backtrace and decide if you really need to be doing this here.");
[self SE_setAnimationsEnabled:enabled];
}
@end
#endif
Обновить
Оказывается, что UIWebView
на самом деле делает небезопасные звонки setAnimationsEnabled:
при отображении медиаэлемента (rdar://20314684). Это делает описанный выше метод очень болезненным, если он постоянно активен, если ваше приложение допускает произвольный веб-контент. Вместо этого я начал использовать метод ниже, так как он позволяет мне включать и выключать точку останова и продолжать работу после сбоя:
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#ifdef DEBUG
void SEViewAlertForUnsafeBackgroundCalls() {
NSLog(@"----------------------------------------------------------------------------------");
NSLog(@"Background call to setAnimationsEnabled: detected. This method is not thread safe.");
NSLog(@"Set a breakpoint at SEUIViewDidSetAnimationsOffMainThread to inspect this call.");
NSLog(@"----------------------------------------------------------------------------------");
}
@implementation UIView (BadBackgroundBehavior)
+ (void)load
{
method_exchangeImplementations(class_getInstanceMethod(object_getClass(self), @selector(setAnimationsEnabled:)),
class_getInstanceMethod(object_getClass(self), @selector(SE_setAnimationsEnabled:)));
}
+ (void)SE_setAnimationsEnabled:(BOOL)enabled
{
if (![NSThread isMainThread]) {
SEViewAlertForUnsafeBackgroundCalls();
}
[self SE_setAnimationsEnabled:enabled];
}
@end
#endif
С помощью этого кода вы можете остановить свое приложение, добавив символическую точку останова на SEViewAlertForUnsafeBackgroundCalls
или просто вставьте точку останова в теле функции.
Расширяя решение Vinay, вот что я делаю:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//make calculations
dispatch_async(dispatch_get_main_queue(),
^{
[UIView setAnimationsEnabled:YES];
});
});
Кажется, чтобы решить проблему.