Using custom AlertView - Window Hierarchy?

298 views Asked by At

So I've been building an App that uses a custom AlertView which I found in another question.

The full code can be found on Github.

Specifically, the CustomiOSAlertView.m can be found HERE.

This is how I create the view, I call the to display the alert form an IBAction attached to an UIImage in the UIStoryboard, here's the action:

- (IBAction)Button1:(id)sender {
    NSString *name      = @"info";
    NSString *content   = @"info 2";
    NSString *info      = @"more info";
    NSString *imageLink = @"image.png";

    NSString *stringContent = [NSString stringWithFormat:@" %@\n\n %@\n\n %@", name, content, info];
    [self ConstructAlertContent:imageLink :stringContent];
}

Which calls this (using the CustomiOSAlertView.m attached above):

-(void)ConstructAlertContent:(NSString *)imgStr :(NSString *)str{
    NSString *imageLink = imgStr;
    NSString *stringContent = str;

    // Here we need to pass a full frame
    CustomIOSAlertView *alertView = [[CustomIOSAlertView alloc] init];

    // Add some custom content to the alert view with above method createDemoView()
    [alertView setContainerView:[self createDemoView:imageLink : stringContent]];

    // Modify the parameters
    [alertView setButtonTitles:[NSMutableArray arrayWithObjects:@"Done", nil]];
    [alertView setDelegate:self]; //add to .h: <CustomIOSAlertViewDelegate>

    // You may use a Block, rather than a delegate.
    [alertView setOnButtonTouchUpInside:^(CustomIOSAlertView *alertView, int buttonIndex) {
        //NSLog(@"Block: Button at position %d is clicked on alertView %d.", buttonIndex, (int)[alertView tag]);
        [alertView close];
    }];

    //allow alert to move with phone motion
    [alertView setUseMotionEffects:true];

    //set alert alpha to slightly transparent
    [alertView setAlpha:0.94];

    // And launch the dialog
    [alertView show];
}

And creating the view like this:

- (UIView *)createDemoView:(NSString *)imgStr :(NSString *)str
{
    UIView *demoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 290, 300)];

    //include image
    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(70, 10, 150, 180)];
    [imageView setImage:[UIImage imageNamed:imgStr]];
    [demoView addSubview:imageView];

    //... with additional subviews

    return demoView;
}

It was working great until I created individual UIStoryboards, and used the following code in the AppDelegate.m to instantiate the correct storyboard for a specific device:

if (iOSScreenSize.height == 480){ //iPhone 3.5"

    //instantiate storyboard for iPhone4S
    UIStoryboard *iPhone35Storyboard = [UIStoryboard storyboardWithName:@"iPhone35" bundle:nil];
    UIViewController *initialViewcontroller = [iPhone35Storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewcontroller;
    [self.window makeKeyAndVisible];
}

if (iOSScreenSize.height == 568){ //iPhone 4"

    //instantiate storyboard for iPhone 5S
    UIStoryboard *iPhone4Storyboard = [UIStoryboard storyboardWithName:@"iPhone4" bundle:nil];
    UIViewController *initialViewcontroller = [iPhone4Storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewcontroller;
    [self.window makeKeyAndVisible];
}

if (iOSScreenSize.height == 667){ //iPhone 4.7"

    //instantiate storyboard for iPhone 6
    UIStoryboard *iPhone47Storyboard = [UIStoryboard storyboardWithName:@"iPhone47" bundle:nil];
    UIViewController *initialViewcontroller = [iPhone47Storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewcontroller;
    [self.window makeKeyAndVisible];
}

if (iOSScreenSize.height == 736){ //iPhone 5.5"

    //instantiate storyboard for iPhone 6+
    UIStoryboard *iPhone55Storyboard = [UIStoryboard storyboardWithName:@"iPhone55" bundle:nil];
    UIViewController *initialViewcontroller = [iPhone55Storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewcontroller;
    [self.window makeKeyAndVisible];
}

Now, when I test the App on (on both simulator and device) it loads the correct storyboard and content but doesn't show the custom AlertView... As soon as I comment out the code above (to instantiate specific storyboard), and run the app, the custom AlertViews work again...

I'm guessing this is something to do with View hierarchy? Is there away to make this appear even by manually instantiating a storyboard as I do with the above code?

Edit

Make sure, using Rob's answer below, you don't have a storyboard selected in the drop-down tab menu in "Main Interface"... Leaving it blank, worked for me and now instantiates a storyboard from the AppDelegate and also creates an AlertView on top of the UIStoryboard when called.

Deployment Info - xCode

1

There are 1 answers

8
Rob Contreras On BEST ANSWER

It sounds to me that you're calling the custom view method inside the AppDelegate before instantiating the storyboard.

You should instantiate the storyboard first and then call the method from within the correct storyboard's controller.

for example:

AppDelegate:

if (iOSScreenSize.height == 667){ //iPhone 4.7"

    //instantiate storyboard for iPhone 6
    UIStoryboard *iPhone47Storyboard = [UIStoryboard storyboardWithName:@"iPhone47" bundle:nil];
    UIViewController *initialViewcontroller = [iPhone47Storyboard instantiateInitialViewController];
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.rootViewController = initialViewcontroller;
    [self.window makeKeyAndVisible];
}

InitialViewController.m

-(void)viewDidAppear(Bool animated){

  [super animated:animated];

  [self createDemoView:"myImage.png" str:"Custom Alert"]'

}

EDIT: Added sample code here: https://github.com/robcontreras/CustomAlert