我尝试在IOS7下制作一个小动画。我的视图控制器有2个视图:tableview和mapview。我有一个按钮,可以在“显示地图全屏”和“显示地图和桌面视图”状态之间切换。
这是我的实验代码:
float mapNewX = self.mapView.frame.origin.x == 0 ? 375 : 0;
float mapNewWidth = mapNewX == 0 ? self.view.frame.size.width : self.view.frame.size.width - mapNewX;
[UIView animateKeyframesWithDuration:0.1 delay:0.0 options:UIViewAnimationCurveEaseOut animations:^
{
CGRect mapViewFrame = self.mapView.frame;
mapViewFrame.origin.x = (mapNewX);
mapViewFrame.size.width = mapNewWidth;
self.mapView.frame = mapViewFrame;
}
completion:^(BOOL finished)
{
NSLog(@"OK");
}];
它可以工作,但是当我旋转设备时,它会切换回原始状态。因此,当我有完整的地图显示时,当旋转设备时,它会切换回屏幕上的tableview + mapview。
如果我通过导航控制器从另一个视图控制器返回,也会发生同样的情况。如果我点击地图引脚的详细信息,它会切换回原始布局。
我该怎么办?非常感谢!
更新:这里是旋转之前/之后的屏幕截图(一些敏感数据被屏蔽掉)
答案 0 :(得分:6)
如果在旋转或屏幕导航后松开帧更改,则可能与视图控制器的布局方法viewWillLayoutSubviews
,viewDidLayoutSubviews
或生命周期方法viewWillAppear:
,viewDidAppear:
有关。如果覆盖它们,请检查这些方法的实现。
因为你使用自动布局,所以更好地设置其约束而不是帧。
据我了解,您的任务是移动地图的左侧以显示下方的桌面视图(打开/关闭状态)。使用自动布局,您的屏幕可能看起来很简单:
(UIImageView视图扮演地图的角色)
UITableView
约束
UIImageView
约束
为了实现所需的效果,我们需要将前导空间设置为超视图约束(在屏幕截图中选择)。我们为此约束创建了一个出口,并将其constant
属性更改为打开/关闭状态。
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *mapLeadingSpace;
设置菜单的初始状态,然后才会出现在屏幕上。我们设置了默认值,但您可以从NSUserDefaults
恢复适当的布尔值设置。
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.mapLeadingSpace.constant = 0; // default is closed
}
接下来,按下按钮上的切换动画。
- (IBAction)toggle:(id)sender
{
self.mapLeadingSpace.constant = self.mapLeadingSpace.constant == 0
? self.tableView.frame.size.width // opened
: 0; // closed
[UIView animateWithDuration:.2 animations:^{
[self.imageView layoutIfNeeded];
}];
}
答案 1 :(得分:1)
使用
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
创建一个变量来指示它是全屏幕地图还是拆分视图,然后在旋转完成后运行例程?不确定解决方案是如何高科技的,但这就是我要做的! :)
答案 2 :(得分:1)
我有类似的拆分视图(2个UItableViews),这是我设法修复它的方法。
首先,让一个全局静态变量调用它static BOOL _isViewSplitted
它是静态的,所以当你按或弹出viewContorller留在内存中。
覆盖didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
检查你的变量在这里,如果是,如果没有则拆分它们,只需返回。
此外,当弹出viewController时,您必须在viewWillAppear
中检查(与上面相同)。
答案 3 :(得分:1)
您可以通过编码约束然后设置动画来解决这个问题。
这样的事情(此代码中的值与示例中的值不匹配):
[subview setTranslatesAutoresizingMaskIntoConstraints:NO];
[parentview setTranslatesAutoresizingMaskIntoConstraints:NO];
[parentview addSubview:subview];
NSDictionary *views = NSDictionaryOfVariableBindings(subview);
[parentview addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[subview]"
options:0
metrics:nil
views:views]];
NSArray *firstConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[subview]"
options:0
metrics:nil
views:views];
[parentview addConstraints:firstConstraints];
[parentview layoutSubtreeIfNeeded];
[parentview removeConstraints:firstConstraints];
NSArray *secondConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[subview]-100-|"
options:0
metrics:nil
views:views];
[parentview addConstraints:secondConstraints];
subview.superview.wantsLayer = YES;
[NSAnimationContext runAnimationGroup:^(NSAnimationContext* context) {
[context setDuration:.3];
[context setAllowsImplicitAnimation:YES];
[context setTimingFunction: [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]];
[subview layoutSubtreeIfNeeded];
} completionHandler:^{
[[self delegate] createOptionMenuForPDFViewWithInvoice:invoice andSuperView:parentview];
}];
答案 4 :(得分:1)
答案 5 :(得分:1)
如果在原帖中提供了以下信息,这个问题更有可能在不需要赏金的情况下相对快速地得到回答(一般来说,这可能是针对iOS中布局相关帖子的一套很好的指导方针):
(1。)是否在故事板中启用了自动布局?
(2。)您使用的是混合(混合)方法还是纯自动布局?换句话说,哪些观点的translatesAutoresizingMaskIntoConstraints
设置为YES
?
(3。)如果覆盖任何布局方法或旋转回调方法,请提供该实现
(4.)向我们展示你的约束
我能够从评论中找到#1的答案。
我的答案很少,我知道这个问题:
如果在地图视图上使用“自动布局”,则在动画块中设置其框架将不会永久地重新定位视图,因为地图视图的约束尚未更改。相反,在动画块之前更新地图视图的约束,然后将layoutIfNeeded
发送到动画块内的self.view
。
// update constraints…
[UIView animateWithDuration:0.5 animations:^{
[self.view layoutIfNeeded];
}];
答案 6 :(得分:1)
还可以在Viewcontroller类的viewDidload中尝试此操作
if ([self respondsToSelector:@selector(edgesForExtendedLayout)]) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}