【问题标题】:Custom AlertViewController not displaying properly in Landscape自定义 AlertViewController 未在横向中正确显示
【发布时间】:2014-07-10 16:36:37
【问题描述】:

我有一个自定义的 alterviewcontroller,它是 UIViewController 的子类。它在纵向应用程序中效果很好,但在横向应用程序中,它遇到了框架方向的问题。我已经尝试了一堆修复,但似乎没有一个是正确的。

在当前版本中,它可以正确显示,但主视图大小错误,因此该视图之外的按钮不可点击。

在此图像中,Next Turn 按钮不可点击,Go to Black 按钮可点击。这是左边的风景。

.h 文件

#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 文件

#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

这是 NSLog 结果:

2014-07-10 10:59:18.603 损坏报告计时器 [5166:60b] 窗口框架 {{0, 0}, {568, 320}} 2014-07-10 10:59:18.720 损坏报告计时器 [5166:60b] 父框架 {{0, 0}, {0, 0}} 2014-07-10 10:59:18.722 损坏报告计时器 [5166:60b] 视图框架 {{0, 0}, {320, 568}} 2014-07-10 10:59:18.724 损坏报告计时器 [5166:60b] 警报框架 {{0,51}, {568, 146.5}} 2014-07-10 10:59:18.726 损坏报告计时器 [5166:60b] 按钮框架 {{101, 91.5}, {150, 50}}

【问题讨论】:

  • 您是否尝试过修复它?我没有看到任何 AutoResizingMask,没有提到约束,甚至没有看到 didOrientationChange 的回调。
  • 我已经做了很多切换框架的高度和宽度的工作。我不允许在这个应用程序中使用纵向模式,所以我认为我不需要任何方向更改的东西。
  • 对于自动调整大小的蒙版,self.view 和 alertview 都设置为锁定与边缘的距离并调整大小。将 NSLog 结果放在上面

标签: ios objective-c landscape uiwindow


【解决方案1】:

我在进行了越来越多的挖掘之后才弄清楚。我真的让整个事情变得比现在更复杂。需要修复 2 个函数,这里是更新的函数:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        alertWindow = [self windowWithLevel:UIWindowLevelAlert];

        if (!alertWindow)
        {
            alertWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

            alertWindow.windowLevel = UIWindowLevelAlert;

            [alertWindow makeKeyAndVisible];

        }

        alertWindow.rootViewController = self;
    }
    return self;
}

- (void)show
{
    CGRect frame = self.view.bounds;


    self.alertview.center = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame));

    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;
                         }];
                     }
     ];
}

最初,由于 show 将视图置于主屏幕边界的中心,因此将其放置在错误的位置,因为主屏幕边界不会在旋转时更新。然后我犯了调整窗口大小以适应这种情况的错误。这使得按钮不再出现在窗口中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 2016-10-02
    • 1970-01-01
    • 2019-07-15
    • 1970-01-01
    相关资源
    最近更新 更多