iOS 8表单模式对话框在显示后调整大小

时间:2015-02-13 00:37:54

标签: objective-c ios8 resize modal-dialog

我在一个应用程序上工作,它通过使用表单模式样式然后是水平翻转动画执行segue来显示模态弹出窗口。在iOS 7中,通过调用:

使表单占用正确的屏幕大小
self.view.superview.bounds = CGRectMake(0,0,300,300);
例如,

这会将模态对话框尺寸设置为正确的尺寸。此模式对话框中还有一个按钮,允许用户查看更多细节'为此,视图增长以显示一些其他内容。我们通过动画视图再次做了这个,然后打电话将界限设置为超级视图上更大的东西。

例如:

self.view.superview.bounds = CGRectMake(0,0,600,600);

在iOS 7中,这非常有用。但是在iOS 8中,它已停止工作。我们现在不得不调用超级视图的边界而不是调用:

self.preferredContentSize = CGSizeMake(300, 300);

这解决了打开后的表格外观,但我无法找到一种方法来操纵之后的视图大小。设置超级视图边界无效。

我可以在iOS8中看到Apple已经对表单进行了更改,以便拥有3个视图层次结构(您的视图 - >阴影视图 - >转换视图 - >窗口),而在iOS 7中它只是一个2视图层次结构(您的视图 - >阴影视图 - >窗口)。

我试过操纵超级视图的超级视图但是没有达到预期的效果。

是否有其他人看到这个/找到了解决方法?这是一个示例项目:

https://github.com/ingybing/FormSheet

在iOS 7 Simulator中运行它,您将看到所需的行为。这就是我在iOS 8中努力工作的原因

查看控制器示例:

#import "ModalWindowViewController.h"

@interface ModalWindowViewController ()
@property bool minimised;
@property bool isInitialViewLoadLayout;
@end

#define is_iOS8 ([[[UIDevice currentDevice] systemVersion]floatValue] >= 8)

@implementation ModalWindowViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.minimised = YES;
    self.isInitialViewLoadLayout = YES;

    if(is_iOS8)
    {
        // Set initial size in iOS 8 etc.
        self.preferredContentSize = CGSizeMake(300, 300);
    }
}

- (void) viewWillLayoutSubviews
{
    if (self.isInitialViewLoadLayout)
    {
        self.isInitialViewLoadLayout = NO;

        if(!is_iOS8)
        {
            // Set initial size in iOS 6,7 etc.
            self.view.superview.bounds = CGRectMake(0, 0, 300, 300);
        }
    }
}

- (IBAction)minMaxTouched:(id)sender
{
    CGRect newSize = CGRectMake(0, 0, 300, 300);

    if (self.minimised == YES)
    {
        newSize = CGRectMake(0, 0, 600, 600);
    }

    if(is_iOS8)
    {
        // Doesn't Work
        // self.view.superview.bounds = newSize;

        // Doesn't seem to do anything either.
        self.preferredContentSize = newSize.size;
    }
    else
    {
        // Works a treat on ios7
        self.view.superview.bounds = newSize;
    }

    self.minimised = !self.minimised;
}

- (IBAction)closeTouched:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}
@end

1 个答案:

答案 0 :(得分:4)

经过多次搞乱之后..如果你更新了view.superview的界限,然后在superview上调用layoutIfNeeded。这将导致调用willLayoutSubviews方法。如果在那里设置了超视图边界,它将更新模式对话框大小,但如果你在其他任何地方进行,则不会。但

示例视图控制器解决方案:

#import "ModalWindowViewController.h"

@interface ModalWindowViewController ()
@property bool minimised;
@property CGRect windowBounds;
@end

#define is_iOS8 ([[[UIDevice currentDevice] systemVersion]floatValue] >= 8)

@implementation ModalWindowViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    // Start with a minimised window size.
    self.minimised = YES;
    self.windowBounds = CGRectMake(0, 0, 300, 300);

    if(is_iOS8)
    {
        // Set initial size in iOS 8 etc.
        self.preferredContentSize = self.windowBounds.size;
    }
}

- (void) viewWillLayoutSubviews
{
    // Resize the window based on it's current required size.
    // The supeview bounds only seems to actually changed on screen
    // if changed inside this method.
    self.view.superview.bounds = self.windowBounds;
}

- (IBAction)minMaxTouched:(id)sender
{
    // Toggle the dimensions of the window bases on minimised / maximised state.
    if (self.minimised == YES)
    {
        self.windowBounds = CGRectMake(0, 0, 600, 600);
    }
    else
    {
        self.windowBounds = CGRectMake(0, 0, 300, 300);
    }

    // Set some value that will get overridden in viewWillLayoutSubviews
    // You need to change the view bounds or it won't actually invoke a layout.
    self.view.superview.bounds = CGRectMake(0, 0, 100, 100);

    // Toggle minimised state before we layout.
    self.minimised = !self.minimised;

    // Manually request a layout. Since the superview bounds have been changed
    // to a temporary value it should cause a layout where we set the real
    // desired size.
    [self.view.superview layoutIfNeeded];
}

- (IBAction)closeTouched:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}
@end