简体   繁体   English

屏幕方向更改时,可以在以前的视图控制器上转换视图吗?

[英]Possible to transform view on previous view controller when screen orientation changes?

I have a situation where viewControllerA pushes viewControllerB onto the navigation stack. 我有一种情况,其中viewControllerAviewControllerB推送到导航堆栈上。 When the user rotates the screen and the orientation of viewControllerB changes, I'd like for a subviewA of viewControllerA to transform and reposition itself. 当用户旋转屏幕且viewControllerB的方向发生变化时,我希望subviewAviewControllerA能够自身进行变换和重新定位。 Is this possible? 这可能吗?

I've tried sending a pointer of subviewA to viewControllerB , but anything I do with it regarding its position gets ignored (when viewControllerB is currently on the screen). 我尝试将subviewA的指针发送到viewControllerB ,但是我对它的位置所做的任何操作都被忽略(当viewControllerB当前在屏幕上时)。

I've also tried repositioning the subviewA in viewDidAppear of viewControllerA after viewControllerB pops off the stack but it looks ugly as it quickly repositions itself as it comes on screen. 我也试着重新定位subviewAviewDidAppearviewControllerAviewControllerB离开本层,但它看起来丑陋,因为它很快重新定位自身,因为它涉及在屏幕上。 Also tried manipulating it in viewWillAppear but nothing happens. 还尝试在viewWillAppear对其进行操作,但没有任何反应。

The only thing I can think of is to send viewControllerA 's entire self.view to viewControllerB and attach it as a subview when viewControllerB rotates and then manipulate it, then remove it. 我能想到的唯一的事情就是送viewControllerA的整个self.viewviewControllerB并附它作为一个子视图时viewControllerB旋转,然后操纵它,然后将其删除。 But that's a horrible solution obviously. 但这显然是一个可怕的解决方案。

Is there a way to do this? 有没有办法做到这一点?

Constraints can be made in such a way that the position and size of views can change automatically (no checking on the orientation) when the bounds of the superview change. 可以通过以下方式进行约束:当超级视图的边界发生变化时,视图的位置和大小可以自动更改(无需检查方向)。 If you make the constraints this way, then the view will have the proper arrangement on rotation regardless of whether the view was on screen at the time of the rotation or not. 如果以这种方式进行约束,则无论旋转时视图是否在屏幕上,视图都将在旋转时具有适当的排列。

Constraints have the form y = m*x + b where y and x are two views, m is the multiplier, and b is the constant. 约束的形式为y = m*x + b ,其中y和x是两个视图,m是乘数,b是常数。 It requires doing a bit of math to figure out what values of m and b will give you the constraints you want. 它需要做一些数学运算才能弄清楚m和b的值将为您提供所需的约束。 I've made a category on NSLayoutConstraint that allows you to directly specify what values you want for portrait and landscape. 我在NSLayoutConstraint上创建了一个类别,该类别使您可以直接指定想要的纵向和横向值。 You can use it like this, 你可以这样使用

- (void)viewDidLoad {
    [super viewDidLoad];
    [self.view addConstraint:[NSLayoutConstraint widthConstraintForView:self.rectangle superview:self.view portraitValue:100 landscapeValue:200]];
    [self.view addConstraint:[NSLayoutConstraint heightConstraintForView:self.rectangle superview:self.view portraitValue:150 landscapeValue:80]];
    [self.view addConstraint:[NSLayoutConstraint topConstraintForView:self.rectangle viewAttribute:NSLayoutAttributeTop superview:self.view portraitValue:200 landscapeValue:10]];
    [self.view addConstraint:[NSLayoutConstraint leftConstraintForView:self.rectangle viewAttribute:NSLayoutAttributeLeft superview:self.view portraitValue:100 landscapeValue:100]];
}

If you have any constraints setup in IB that would be replaced by these, you can mark them as placeholders that will be removed at runtime. 如果您在IB中有任何约束设置将被这些约束所替代,则可以将它们标记为占位符,这些占位符将在运行时删除。 The category looks like this, 类别看起来像这样,

+(NSLayoutConstraint *)heightConstraintForView:(UIView *)subview superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (pValue - lValue)/(superview.bounds.size.height - superview.bounds.size.width);
    CGFloat constant = pValue - (superview.bounds.size.height * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeHeight relatedBy:0 toItem:superview attribute:NSLayoutAttributeHeight multiplier:multiplier constant:constant];
    NSLog(@"height coeffs: %f   %f",multiplier,constant);
    return con;
}

+(NSLayoutConstraint *)widthConstraintForView:(UIView *)subview superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (pValue - lValue)/(superview.bounds.size.width - superview.bounds.size.height);
    CGFloat constant = pValue - (superview.bounds.size.width * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeWidth relatedBy:0 toItem:superview attribute:NSLayoutAttributeWidth multiplier:multiplier constant:constant];
    NSLog(@"width coeffs: %f   %f",multiplier,constant);
    return con;
}


+(NSLayoutConstraint *)leftConstraintForView:(UIView *)subview viewAttribute:(NSLayoutAttribute) att superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (pValue - lValue)/(superview.bounds.size.width - superview.bounds.size.height);
    CGFloat constant = pValue - (superview.bounds.size.width * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:att relatedBy:0 toItem:superview attribute:NSLayoutAttributeRight multiplier:multiplier constant:constant];
    NSLog(@"left coeffs: %f   %f",multiplier,constant);
    return con;
}


+(NSLayoutConstraint *)rightConstraintForView:(UIView *)subview viewAttribute:(NSLayoutAttribute) att superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (superview.bounds.size.width - pValue - superview.bounds.size.height + lValue)/(superview.bounds.size.width - superview.bounds.size.height);
    CGFloat constant = superview.bounds.size.width - pValue - (superview.bounds.size.width * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:att relatedBy:0 toItem:superview attribute:NSLayoutAttributeRight multiplier:multiplier constant:constant];
     NSLog(@"right coeffs: %f   %f",multiplier,constant);
    return con;
}

+(NSLayoutConstraint *)topConstraintForView:(UIView *)subview viewAttribute:(NSLayoutAttribute) att superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (pValue - lValue)/(superview.bounds.size.height - superview.bounds.size.width);
    CGFloat constant = pValue - (superview.bounds.size.height * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:att relatedBy:0 toItem:superview attribute:NSLayoutAttributeBottom multiplier:multiplier constant:constant];
     NSLog(@"top coeffs: %f   %f",multiplier,constant);
    return con;
}


+(NSLayoutConstraint *)bottomConstraintForView:(UIView *)subview viewAttribute:(NSLayoutAttribute) att superview:(UIView *)superview portraitValue:(CGFloat)pValue landscapeValue:(CGFloat)lValue {
    CGFloat multiplier = (superview.bounds.size.height - pValue - superview.bounds.size.width + lValue)/(superview.bounds.size.height - superview.bounds.size.width);
    CGFloat constant = superview.bounds.size.height - pValue - (superview.bounds.size.height * multiplier);
    NSLayoutConstraint *con = [NSLayoutConstraint constraintWithItem:subview attribute:att relatedBy:0 toItem:superview attribute:NSLayoutAttributeBottom multiplier:multiplier constant:constant];
     NSLog(@"bottom coeffs: %f   %f",multiplier,constant);
    return con;
}

I have this example project posted here, http://jmp.sh/SYgejs6 我在这里发布了这个示例项目, http://jmp.sh/SYgejs6

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM