I have a custom alterviewcontroller which subclasses UIViewController. It works great in apps that are portrait, but in landscape, it's running into issues with the frame orientation. I've tried a bunch of fixes, but none seem to be getting it right.
In the current version, it displays correctly but the main view is the wrong size, so the buttons that are outside of that view are not clickable.
In this image, the Next Turn button is not Clickable, the Go to Black button is. This is landscape left.
.h file
#import <UIKit/UIKit.h> #import "SPRTitleFontLabel.h" @protocol SPRAlertViewControllerDelegate; @interface SPRAlertViewController : UIViewController @property (nonatomic, weak) id <SPRAlertViewControllerDelegate> delegate; @property (weak, nonatomic) IBOutlet UIView *alertview; @property (weak, nonatomic) IBOutlet SPRTitleFontLabel *titleLabel; @property (weak, nonatomic) IBOutlet UITextView *messageLabel; @property (weak, nonatomic) IBOutlet UIButton *yesButton; @property (weak, nonatomic) IBOutlet UIButton *noButton; @property (weak, nonatomic) IBOutlet UIButton *okButton; @property int tag; -(void)setTitle:(NSString *)title message:(NSString *)message andButtonCount:(int)buttonCount; - (IBAction)doDismiss:(id)sender; - (void)show; @end @protocol SPRAlertViewControllerDelegate <NSObject> - (void)alert:(SPRAlertViewController *)alert didDismissWithButtonClick:(int)buttonIndex; @end
.m file
#import "SPRAlertViewController.h" #import "SPRAudioHelper.h" @interface SPRAlertViewController () { UIWindow *alertWindow; } @end @implementation SPRAlertViewController +(instancetype)new { SPRAlertViewController *alvc = [super new]; return alvc; } - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { alertWindow = [self windowWithLevel:UIWindowLevelAlert]; if (!alertWindow) { //rotate the window frame to get the right orientation CGRect tempFrame = [UIScreen mainScreen].bounds; CGRect tempFrame2 = tempFrame; tempFrame2.size.height = tempFrame.size.width; tempFrame2.size.width = tempFrame.size.height; alertWindow = [[UIWindow alloc] initWithFrame:tempFrame2]; alertWindow.windowLevel = UIWindowLevelAlert; [alertWindow makeKeyAndVisible]; NSLog(@"window frame %@", NSStringFromCGRect(alertWindow.frame)); } alertWindow.rootViewController = self; } return self; } - (void)setTitle:(NSString *)title message:(NSString *)message andButtonCount:(int)buttonCount { self.titleLabel.text = title; self.messageLabel.text = message; if (buttonCount == 1) { self.yesButton.hidden = YES; self.noButton.hidden = YES; self.okButton.hidden = NO; } else { self.yesButton.hidden = NO; self.noButton.hidden = NO; self.okButton.hidden = YES; } CGRect frame = self.messageLabel.frame; CGSize size = [self.messageLabel sizeThatFits:CGSizeMake(self.messageLabel.frame.size.width, FLT_MAX)]; frame.size.height = size.height; self.messageLabel.frame = frame; [self.messageLabel setNeedsDisplay]; float buttonTop = frame.size.height + frame.origin.y; self.yesButton.frame = CGRectMake(self.yesButton.frame.origin.x, buttonTop, self.yesButton.frame.size.width, self.yesButton.frame.size.height); self.noButton.frame = CGRectMake(self.noButton.frame.origin.x, buttonTop, self.noButton.frame.size.width, self.noButton.frame.size.height); self.okButton.frame = CGRectMake(self.okButton.frame.origin.x, buttonTop, self.okButton.frame.size.width, self.okButton.frame.size.height); self.alertview.frame = CGRectMake(self.alertview.frame.origin.x, self.alertview.frame.origin.y, self.alertview.frame.size.width, buttonTop+55); NSLog(@"parent frame %@", NSStringFromCGRect(self.parentViewController.view.frame)); NSLog(@"view frame %@", NSStringFromCGRect(self.view.frame)); NSLog(@"alert frame %@", NSStringFromCGRect(self.alertview.frame)); NSLog(@"button frame %@", NSStringFromCGRect(self.yesButton.frame)); } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view from its nib. UIInterpolatingMotionEffect* m1 = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; m1.maximumRelativeValue = @0.0; m1.minimumRelativeValue = @0.0; UIInterpolatingMotionEffect* m2 = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; m2.maximumRelativeValue = @20.0; m2.minimumRelativeValue = @-20.0; UIMotionEffectGroup* g = [UIMotionEffectGroup new]; g.motionEffects = @[m1,m2]; [self.alertview addMotionEffect:g]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } - (void)show { CGRect tempFrame = [UIScreen mainScreen].bounds; CGRect tempFrame2 = tempFrame; tempFrame2.size.height = tempFrame.size.width; tempFrame2.size.width = tempFrame.size.height; self.alertview.center = CGPointMake(CGRectGetMidX(tempFrame2), CGRectGetMidY(tempFrame2)); self.alertview.transform = CGAffineTransformMakeScale(1,1.6); self.alertview.alpha = 0; self.view.alpha = 0; [UIView animateWithDuration:0.1 animations:^{ self.view.alpha = 1; } completion: ^(BOOL finished){ [UIView animateWithDuration:0.25 animations:^{ self.alertview.alpha = 1; self.alertview.transform = CGAffineTransformIdentity; }]; } ]; } - (UIWindow *)windowWithLevel:(UIWindowLevel)windowLevel { NSArray *windows = [[UIApplication sharedApplication] windows]; for (UIWindow *window in windows) { if (window.windowLevel == windowLevel) { return window; } } return nil; } - (IBAction)doDismiss:(id)sender { // [[SPRAudioHelper sharedHelper] playSoundFromTag:lightClick]; NSLog(@"check"); [UIView animateWithDuration:0.25 animations:^{ self.alertview.transform = CGAffineTransformScale(self.alertview.transform, 1,0.5); self.alertview.alpha = 0; }completion:^(BOOL finished) { [UIView animateWithDuration:0.1 animations:^{ self.view.alpha = 0; }completion:^(BOOL finished) { [alertWindow removeFromSuperview]; alertWindow = nil; if (sender == self.yesButton) [self.delegate alert:self didDismissWithButtonClick:1]; else [self.delegate alert:self didDismissWithButtonClick:0]; }]; }]; } @end
Here's the NSLog results:
2014-07-10 10:59:18.603 Damage Report Timer[5166:60b] window frame {{0, 0}, {568, 320}} 2014-07-10 10:59:18.720 Damage Report Timer[5166:60b] parent frame {{0, 0}, {0, 0}} 2014-07-10 10:59:18.722 Damage Report Timer[5166:60b] view frame {{0, 0}, {320, 568}} 2014-07-10 10:59:18.724 Damage Report Timer[5166:60b] alert frame {{0,51}, {568, 146.5}} 2014-07-10 10:59:18.726 Damage Report Timer[5166:60b] button frame {{101, 91.5}, {150, 50}}