2019 년 2 월 21 일 업데이트
수요
최근의 프로젝트는 수요가있는 모든 네트워크 요청 (즉, 상태 표시 줄에 작은 원을 회전) NetworkActvityIndicator을 표시되지 않습니다.
해결 방법 1 :
NetworkIndicator 글로벌 검색 키워드는, 모든 코드는 예를 들어, NetworkIndicator 제거를 포함 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
.
테스트는 새로운 문제를 발견
인터페이스는 여전히 재생 비디오 디스플레이입니다 제외하고 모든 인터페이스는 더 이상 NetworkActvityIndicator 표시되지 않습니다.
추측 : 타사 라이브러리로 인한 문제를
아무리 정상적인 상황에서 타사 라이브러리는 상태 표시 줄 setNetworkActivityIndicatorVisible을 통해 작은 원이 될 것입니다 무슨.
검증 과정 (1)
상속 UIApplication을 통해 setNetworkActivityIndicatorVisible 방법을 다시 작성합니다. (UIApplication을 상속하는 방법, 여기 참조) 및 메소드 본문에 중단 점 히트를 넣어.
테스트 정상 호출은 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
중단 점을 트리거합니다. 그러나 비디오 인터페이스, 중단 점, 일반 디스플레이 작은 원을 유발하지 않았다 유일한 경우.
검증 과정 2
networkActivityIndicatorVisible 재산의 KVO 청취 UIApplication으로, 결과는 같은 상황 및 검증 1이었다.
일반 전화는 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
트리거 모니터하지 않고, 그 비디오 인터페이스를 제외하고, 모니터를 유발하고, 일반 디스플레이 작은 원됩니다.
따라서, 일반적인 호출 영상 표시 작은 원의 화면과 확실히이 setNetworkActivityIndicatorVisible
방법을 표시.
업데이트 추측 : 문제는 타사 라이브러리에 의한, 대신 기존의 방법으로 호출
검증 과정 3
상태 표시에있는 작은 원 인터페이스의 뷰 구조 분석을 보여 UIActivityIndicatorView 타입 뷰 (두 홀수의 존재)이 존재한다.
정상적인 상황 즉,로 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
작은 원을 표시, 뷰 계층은 어떻게입니까? 분석에 의한 검증은 동일하다.
레벨은 UIStatusBarView -> UIStatusBarForegroundView -> UIStatusBarActivityItemView -> UIActivityIndicatorView
솔루션의 생각 :
UIActivityIndicatorView 루틴 호출하는 애니메이션을 시작하면서 작은 원하기 때문에 뷰의 UIActivityIndicatorView 유형이 있습니다 startAnimation
방법을.
그런데 왜 그 무시하는 마술 (방법 스위 즐링)를 사용하지 startAnimation
, 방법을
만약 그렇다면, 직접 그것을 밖으로 수퍼 "UIStatusBarActivityItemView"타입 여부를 결정합니다. 그렇지 않으면, 원래 startAnimation 방법.
토크는 저렴합니다. 나에게 코드를 표시합니다.
여기에 코드하는 .m 파일입니다
@implementation UIActivityIndicatorView (HideNetworkActivityIndicator)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(startAnimating);
SEL swizzledSelector = @selector(xxx_startAnimating);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
// ...
// Method originalMethod = class_getClassMethod(class, originalSelector);
// Method swizzledMethod = class_getClassMethod(class, swizzledSelector);
BOOL didAddMethod =
class_addMethod(class,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
#pragma mark - Method Swizzling
- (void)xxx_startAnimating{
if (self.superview != nil && [NSStringFromClass([self.superview class]) isEqualToString: @"UIStatusBarActivityItemView"]) {
NSLog(@"黑魔法禁止状态栏的loading显示: %@", self);
} else {
[self xxx_startAnimating];
}
}
@end
성공! ! !
(생체 xxx_startAnimation 브레이크 포인트, 비디오 플레이어 인터페이스 프로그램을 시작, 중단 점을 트리거, 호출 스택은 정말 타사 라이브러리로 인한 문제가, 볼 수 있습니다.)