视图控制器不在视图层次结构中吗? [英] View controller not in view hierarchy?

查看:129
本文介绍了视图控制器不在视图层次结构中吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我尝试通过编程将一个视图控制器从一个视图控制器过渡到另一个视图控制器,以便仅在用户需要登录时才可以对其进行初始化.但是,xcode不断给我一个错误,它不在视图层次结构中,因此拒绝加载它.

So I am trying to transition from one view controller to another with a segue programmatically so that I can only initialize it when a user needs to login. However, xcode keeps giving me the error that it is not in the view hierarchy and refuses to load to it.

ViewController.h

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@end

ViewController.m

ViewController.m

#import "ViewController.h"
#import "API.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    if (![[API sharedInstance] isAuthorized]) {
        [self performSegueWithIdentifier:@"ShowLogin" sender:nil];
    }// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

LoginScreen.h(不在层次结构中的控制器)

LoginScreen.h (the controller not in the hierarchy)

#import <UIKit/UIKit.h>

@interface LoginScreen : UIViewController
{
    //the login form fields
    IBOutlet UITextField *fldUsername;
    IBOutlet UITextField *fldPassword;
}

//action for when either button is pressed
-(IBAction)btnLoginRegisterTapped:(id)sender;

@end

LoginScreen.m(该控制器显然不在层次结构中)

LoginScreen.m (the controller apparently not in the hierarchy)

#import "LoginScreen.h"
#import "UIAlertView+error.h"
#import "API.h"
#include <CommonCrypto/CommonDigest.h>

#define kSalt @"(protected value)"

@implementation LoginScreen

-(void)viewDidLoad {
    [super viewDidLoad];

}

#pragma mark - View lifecycle

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

-(IBAction)btnLoginRegisterTapped:(UIButton*)sender {
    //form fields validation
    if (fldUsername.text.length < 4 || fldPassword.text.length < 4) {
        [UIAlertView error:@"Enter username and password over 4 chars each."];
        return;
    }
    //salt the password
    NSString* saltedPassword = [NSString stringWithFormat:@"%@%@", fldPassword.text, kSalt];
    //prepare the hashed storage
    NSString* hashedPassword = nil;
    unsigned char hashedPasswordData[CC_SHA1_DIGEST_LENGTH];
    //hash the pass
    NSData *data = [saltedPassword dataUsingEncoding: NSUTF8StringEncoding];
    if (CC_SHA1([data bytes], [data length], hashedPasswordData)) {
        hashedPassword = [[NSString alloc] initWithBytes:hashedPasswordData length:sizeof(hashedPasswordData) encoding:NSASCIIStringEncoding];
    } else {
        [UIAlertView error:@"Password can't be sent"];
        return;
    }
    //check whether it's a login or register
    NSString* command = (sender.tag==1)?@"register":@"login";
    NSMutableDictionary* params =[NSMutableDictionary dictionaryWithObjectsAndKeys:command, @"command", fldUsername.text, @"username", hashedPassword, @"password", nil];
    //make the call to the web API
    [[API sharedInstance] commandWithParams:params onCompletion:^(NSDictionary *json) {
        //result returned
        NSDictionary* res = [[json objectForKey:@"result"] objectAtIndex:0];
        if ([json objectForKey:@"error"]==nil && [[res objectForKey:@"IdUser"] intValue]>0) {
            [[API sharedInstance] setUser: res];
            [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
            //show message to the user
            [[[UIAlertView alloc] initWithTitle:@"Logged in" message:[NSString stringWithFormat:@"Welcome %@",[res objectForKey:@"username"]] delegate:nil cancelButtonTitle:@"Close" otherButtonTitles: nil] show];
        } else {
            //error
            [UIAlertView error:[json objectForKey:@"error"]];
        }
    }];

}

@end

API.h(调用我的Web服务)

API.h (calling my web service)

#import "AFHTTPClient.h"
#import "AFNetworking.h"

typedef void (^JSONResponseBlock)(NSDictionary* json);

@interface API : AFHTTPClient

@property (strong, nonatomic) NSDictionary* user;

+(API*)sharedInstance;
//check whether there's an authorized user
-(BOOL)isAuthorized;
//send an API command to the server
-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock;
-(NSURL*)urlForImageWithId:(NSNumber*)IdPhoto isThumb:(BOOL)isThumb;

@end

API.m(调用我的Web服务)

API.m (calling my web service)

#import "API.h"

//the web location of the service
#define kAPIHost @"(protected web address)"
#define kAPIPath @""

@implementation API

@synthesize user;

#pragma mark - Singleton methods
/**
 * Singleton methods
 */
+(API*)sharedInstance {
    static API *sharedInstance = nil;
    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^{
        sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kAPIHost]];
    });

    return sharedInstance;
}

#pragma mark - init
//intialize the API class with the deistination host name

-(API*)init {
    //call super init
    self = [super init];
    if (self != nil) {
        //initialize the object
        user = nil;
        [self registerHTTPOperationClass:[AFJSONRequestOperation class]];
        // Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
        [self setDefaultHeader:@"Accept" value:@"application/json"];
    }
    return self;
}

-(BOOL)isAuthorized {
    return [[user objectForKey:@"IdUser"] intValue]>0;
}

-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock {
    NSData* uploadFile = nil;
    if ([params objectForKey:@"file"]) {
        uploadFile = (NSData*)[params objectForKey:@"file"];
        [params removeObjectForKey:@"file"];
    }

    NSMutableURLRequest *apiRequest = [self multipartFormRequestWithMethod:@"POST" path:kAPIPath parameters:params constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
        if (uploadFile) {
            [formData appendPartWithFileData:uploadFile name:@"file" fileName:@"photo.jpg" mimeType:@"image/jpeg"];
        }
    }];
    AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest];
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        //success!
        completionBlock(responseObject);
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        //failure :(
        completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]);
    }];
    [operation start];
}

-(NSURL*)urlForImageWithId:(NSNumber*)IdPhoto isThumb:(BOOL)isThumb {
    NSString* urlString = [NSString stringWithFormat:@"%@/%@upload/%@%@.jpg", kAPIHost, kAPIPath, IdPhoto, (isThumb)?@"-thumb":@""];
    return [NSURL URLWithString:urlString];
}

@end

推荐答案

问题是,在调用viewDidLoad时,尚未将初始视图控制器的视图添加到窗口中.

The issue is that the view of your initial view controller has not been added to the window by the time viewDidLoad is called.

将该呼叫移至viewDidAppear:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if (![[API sharedInstance] isAuthorized]) {
        [self performSegueWithIdentifier:@"ShowLogin" sender:self];
    }
}

这篇关于视图控制器不在视图层次结构中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆