解雇模态视图控制器后框架不能反映汽车布局限制 [英] Frame doesn't reflect auto layout constraints after dismissing modal view controller

查看:143
本文介绍了解雇模态视图控制器后框架不能反映汽车布局限制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是iOS 6,寻呼的UIScrollView,和纯自动布局。

I'm using iOS 6, a paging UIScrollView, and pure auto layout.

摘要:我创建了一个滚动的内容页面视图控制器。有些意见中创建和故事板配置,其他编程。这里的视图层次:

Summary: I created a view controller that scrolls pages of content. Some of the views are created and configured in storyboard, others programmatically. Here's the view hierarchy:

- Main view (storyboard) 
  - UIScrollView (storyboard)
    - content view (programmatically)
      - subviews representing pages of content (programmatically)

滚动视图中的约束IB配置。以下是我配置的约束在code的内容视图:

The constraints for the scroll view are configured in IB. Here's how I configured the constraints for the content view in code:

- (void)viewDidLoad
{
   // ABPageScrollerContentView is a subclass of UIView; it overrides intrinsicContentSize; the size is calculated without referencing the scroll view's dimensions
   self.contentView = [[ABPageScrollerContentView alloc] init];
   self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
   [self.pageScrollerView addSubview:self.contentView];

   // configure constraints between scroll view and content view...
   UIView *contentView = self.contentView;
   NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(contentView);

   [self.pageScrollerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[contentView]|" options:0 metrics:0 views:viewsDictionary]];
   [self.pageScrollerView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[contentView]|" options:0 metrics:0 views:viewsDictionary]];

   // the content view's subviews are added/removed in the tilePages method (not shown); tilePages is called later in the view controller lifecycle...
}

如果用户点击编辑按钮,另一种观点认为控制器是利用故事板一SEGUE psented模态$ P $。视图控制器被驳回后,系统出现莫名其妙地修改内容视图的框架,即使限制不变。

If the user taps an edit button, another view controller is presented modally using a segue in the storyboard. After the view controller is dismissed, the system appears to inexplicably modify the frame of the content view even though the constraints are unchanged.

我驳回presented视图控制器在下面的委托方法:

I dismiss the presented view controller in the following delegate method:

- (void)didExitEditPageViewVC:(id)controller
{
   // update currently displayed page view from data model...

   // logged content view frame = (0, 0; 1020, 460)

   [self dismissViewControllerAnimated:YES completion:^{

      // logged content view frame = (-170, 0; 1020, 460)
   }];
}

我不明白是怎么框架原点的x分量从0变为-170。约束之前和解聘视图控制器后是相同的。

I don't understand how the x component of the frame's origin changed from 0 to -170. The constraints are identical before and after dismissing the view controller.

下面是框架和约束正确调用dismissViewControllerAnimated前:完成:方法:

Here is the frame and the constraints right before calling the dismissViewControllerAnimated:completion: method:

(lldb) po self.contentView
$0 = 0x1ede2b40 <AEBPageScrollerContentView: 0x1ede2b40; frame = (0 0; 1020 460); layer = <CALayer: 0x1edd6f00>>

(lldb) po self.pageScrollerView.constraints
$1 = 0x1ed076c0 <__NSArrayM 0x1ed076c0>(
<NSLayoutConstraint:0x1ede2980 H:|-(0)-[AEBPageScrollerContentView:0x1ede2b40]   (Names: '|':UIScrollView:0x1edd3410 )>,
<NSLayoutConstraint:0x1eded480 H:[AEBPageScrollerContentView:0x1ede2b40]-(0)-|   (Names: '|':UIScrollView:0x1edd3410 )>,
<NSLayoutConstraint:0x1edecbc0 V:|-(0)-[AEBPageScrollerContentView:0x1ede2b40]   (Names: '|':UIScrollView:0x1edd3410 )>,
<NSLayoutConstraint:0x1ede1040 V:[AEBPageScrollerContentView:0x1ede2b40]-(0)-|   (Names: '|':UIScrollView:0x1edd3410 )>
)

下面是框架和presenting视图控制器后的约束再次出现:

Here is the frame and the constraints after the presenting view controller re-appears:

contentView = <AEBPageScrollerContentView: 0x1ede2b40; frame = (-170 0; 1020 460); layer = <CALayer: 0x1edd6f00>>

self.pageScrollerView.constraints =
(
    "<NSLayoutConstraint:0x1ede2980 H:|-(0)-[AEBPageScrollerContentView:0x1ede2b40]   (Names: '|':UIScrollView:0x1edd3410 )>",
    "<NSLayoutConstraint:0x1eded480 H:[AEBPageScrollerContentView:0x1ede2b40]-(0)-|   (Names: '|':UIScrollView:0x1edd3410 )>",
    "<NSLayoutConstraint:0x1edecbc0 V:|-(0)-[AEBPageScrollerContentView:0x1ede2b40]   (Names: '|':UIScrollView:0x1edd3410 )>",
    "<NSLayoutConstraint:0x1ede1040 V:[AEBPageScrollerContentView:0x1ede2b40]-(0)-|   (Names: '|':UIScrollView:0x1edd3410 )>"
)

为什么意外做了内容视图的框架的变化?而为什么没有匹配的是什么限制规定?

Why did the content view's frame change unexpectedly? And why doesn't it match what is dictated by the constraints?

要hasAmbiguousLayout延迟的调用返回false出奇。没有异常抛出。滚动视图滚动甚至,虽然内容视图是部分关闭屏幕。

A delayed call to hasAmbiguousLayout returns false surprisingly. No exceptions are thrown. The scroll view even scrolls, albeit the content view is partly off-screen.

没有哪里可以明确地设置滚动视图的内容大小;我留给系统。内容视图有一个内在的大小(内容视图的大小似乎都很正常,它是内容视图的由来是这样的问题)。

No where do I explicitly set the scroll view's content size; I leave that to the system. The content view has an intrinsic size (the content view's size appears to be fine; it's the content view's origin that is the problem).

滚动视图的内容偏移是之前和解聘视图控制器后的相同。然而,内容视图的原点的x分量的位移正比于内容偏移。内容偏移越大,更多的负面内容视图原点的x分量是模态视图控制器被驳回后。并且,在一个内容的零偏移量,x分量是零。因此,如果模态视图控制器是在观看内容的第一页(当内容偏移量为零),内容视图的框架是在视图控制器的解雇正确psented $ P $。内容偏移的零的情况是在内容视图的框架正确反映其约束的唯一情况。

The scroll view's content offset is the same before and after dismissing the view controller. However, the displacement of the x component of the content view's origin is proportional to the content offset. The greater the content offset, the more negative the x component of the content view's origin is after the modal view controller is dismissed. And, at a content offset of "zero", the x component is zero. So if the modal view controller is presented while viewing the first page of content (when the content offset is "zero"), the content view's frame is correct upon dismissal of the view controller. The content-offset-of-zero case is the only circumstance in which the content view's frame correctly reflects its constraints.

我曾尝试在不同的地方有没有结果插入调用layoutIfNeeded。

I have tried inserting calls to layoutIfNeeded in various places with no results.

有什么建议?

推荐答案

我创建一个UIScrollView子类,解决此问题的工作(这BTW固定在iOS7):

I created a UIScrollView subclass that works around this issue (which BTW is fixed in iOS7):

@interface ConstraintsSafeScrollView : UIScrollView
@end

@implementation ConstraintsSafeScrollView {
  CGPoint _savedContentOffset;
  UIEdgeInsets _savedContentInset;
}

- (void)willMoveToWindow:(UIWindow *)newWindow {
  if (newWindow) {
    // Reset the scrollview to the top.
    [super setContentOffset:CGPointMake(-_savedContentInset.left, -_savedContentInset.top)];
  }
  [super willMoveToWindow:newWindow];
}

// Overridden to store the latest value.
- (void)setContentOffset:(CGPoint)contentOffset {
  _savedContentOffset = contentOffset;
  [super setContentOffset:contentOffset];
}

// Overridden to store the latest value.
- (void)setContentInset:(UIEdgeInsets)contentInset {
  _savedContentInset = contentInset;
  [super setContentInset:contentInset];
}

- (void)didMoveToWindow {
  if (self.window) {
    // Restore offset and insets to their previous values.
    self.contentOffset = _savedContentOffset;
    self.contentInset = _savedContentInset;

  }
  [super didMoveToWindow];
}

@end

这篇关于解雇模态视图控制器后框架不能反映汽车布局限制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆