UIView 不添加到 UIViewController
UIView doesn't add to UIViewController
我有一个在没有网络连接时显示的视图,如果没有网络连接我检查它是否已经恢复,用这个方法。在 viewDidLoad
中首次调用
-(void)checkInternet {
internetReach = [Reachability reachabilityForInternetConnection];
[internetReach startNotifier];
NetworkStatus netStatus = [internetReach currentReachabilityStatus];
switch (netStatus){
case ReachableViaWWAN:{
isReachable = YES;
NSLog(@"4g");
noInternetView.hidden = YES;
break;
}
case ReachableViaWiFi:{
isReachable = YES;
noInternetView.hidden = YES;
NSLog(@"wifi");
break;
}
case NotReachable:{
NSLog(@"NONE");
noInternetView = [[CheckInternetView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:noInternetView]; //IT IS NOT ADDED??
isReachable = NO;
[self checkInternet];
break;
}
}
}
如果没有互联网,该方法会被一遍又一遍地调用,但为什么 noIntenertView
没有进入视图控制器?
编辑
这里是 CheckInternetView Class
#import "CheckInternetView.h"
@implementation CheckInternetView
- (id)initWithFrame:(CGRect)frame {
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
self = [super initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
if (self) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
label.textAlignment = NSTextAlignmentCenter;
label.numberOfLines = 2;
[label setCenter:CGPointMake(self.frame.size.width / 2 , self.frame.size.height / 2 - 25)];
label.text = @"You've lost your internet connection. Please connect to internet.";
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.frame = CGRectMake(0, 0, 80, 80);
[spinner setCenter:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2 + 40)];
[spinner startAnimating];
label.textColor = whiteColorAll;
spinner.color = whiteColorAll;
[self setBackgroundColor:[UIColor blackColor]];
[self addSubview: spinner];
[self addSubview: label];
}
return self;
}
由于您在 UI 主线程上调用 checkInternet
并创建无限递归循环,因此 UI 没有时间更新。它只会在您从 viewDidLoad
return 之后更新。但这不会发生,直到您真正拥有有效的互联网连接。如果你没有,你会循环。
解决此问题:将对 checkInternet
的调用移至后台线程。如果您随后需要呈现视图,请确保再次发生在主线程上。
看看here to see how to properly create a new background thread. And here 看看如何运行 需要UI 代码再次在主线程上。
注意您可能最终会得到大量的 CheckInternetView
实例,因为您一遍又一遍地添加它们。如果还存在 none,最好只创建和添加一个。
此外,您的代码将非常耗费性能,甚至可能导致崩溃,因为您只是在没有适当的超时或中断条件的情况下进行递归。最好每秒或每半秒或该范围内的某个时间间隔检查一次互联网。并且您可能希望在连续循环中而不是在递归中执行此操作以减少对堆和堆栈的影响。
我有一个在没有网络连接时显示的视图,如果没有网络连接我检查它是否已经恢复,用这个方法。在 viewDidLoad
-(void)checkInternet {
internetReach = [Reachability reachabilityForInternetConnection];
[internetReach startNotifier];
NetworkStatus netStatus = [internetReach currentReachabilityStatus];
switch (netStatus){
case ReachableViaWWAN:{
isReachable = YES;
NSLog(@"4g");
noInternetView.hidden = YES;
break;
}
case ReachableViaWiFi:{
isReachable = YES;
noInternetView.hidden = YES;
NSLog(@"wifi");
break;
}
case NotReachable:{
NSLog(@"NONE");
noInternetView = [[CheckInternetView alloc] initWithFrame:self.view.bounds];
[self.view addSubview:noInternetView]; //IT IS NOT ADDED??
isReachable = NO;
[self checkInternet];
break;
}
}
}
如果没有互联网,该方法会被一遍又一遍地调用,但为什么 noIntenertView
没有进入视图控制器?
编辑
这里是 CheckInternetView Class
#import "CheckInternetView.h"
@implementation CheckInternetView
- (id)initWithFrame:(CGRect)frame {
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;
self = [super initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight)];
if (self) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 300, 60)];
label.textAlignment = NSTextAlignmentCenter;
label.numberOfLines = 2;
[label setCenter:CGPointMake(self.frame.size.width / 2 , self.frame.size.height / 2 - 25)];
label.text = @"You've lost your internet connection. Please connect to internet.";
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
spinner.frame = CGRectMake(0, 0, 80, 80);
[spinner setCenter:CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2 + 40)];
[spinner startAnimating];
label.textColor = whiteColorAll;
spinner.color = whiteColorAll;
[self setBackgroundColor:[UIColor blackColor]];
[self addSubview: spinner];
[self addSubview: label];
}
return self;
}
由于您在 UI 主线程上调用 checkInternet
并创建无限递归循环,因此 UI 没有时间更新。它只会在您从 viewDidLoad
return 之后更新。但这不会发生,直到您真正拥有有效的互联网连接。如果你没有,你会循环。
解决此问题:将对 checkInternet
的调用移至后台线程。如果您随后需要呈现视图,请确保再次发生在主线程上。
看看here to see how to properly create a new background thread. And here 看看如何运行 需要UI 代码再次在主线程上。
注意您可能最终会得到大量的 CheckInternetView
实例,因为您一遍又一遍地添加它们。如果还存在 none,最好只创建和添加一个。
此外,您的代码将非常耗费性能,甚至可能导致崩溃,因为您只是在没有适当的超时或中断条件的情况下进行递归。最好每秒或每半秒或该范围内的某个时间间隔检查一次互联网。并且您可能希望在连续循环中而不是在递归中执行此操作以减少对堆和堆栈的影响。