Autolayout正在轮换

时间:2015-08-05 23:31:43

标签: ios objective-c uiscrollview autolayout

要尝试使用自动布局和uiscrollview,我一直在使用this example

我已经编辑过在滚动视图中包含2个视图,我已经设置了自动布局约束来将视图水平定位,并将它们的大小设置为填充滚动视图框。

UIView *beeView = [[[NSBundle mainBundle] loadNibNamed:@"BeeView" owner:nil options:nil] firstObject];
beeView.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:beeView];
UIView *beeView2 = [[[NSBundle mainBundle] loadNibNamed:@"BeeView" owner:nil options:nil] firstObject];
beeView2.backgroundColor= [UIColor orangeColor];
beeView2.translatesAutoresizingMaskIntoConstraints = NO;
[self.scrollView addSubview:beeView2];

NSDictionary *views = @{@"beeView":beeView,@"beeView2":beeView2, @"scrollView":self.scrollView};
NSDictionary *metrics = @{@"height" : @200};
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[beeView(==scrollView)][beeView2(==beeView)]|" options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metrics views:views]];
[self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[beeView(==scrollView)]|" options:kNilOptions metrics:metrics views:views]];

很好地产生了我的意图。

但是,如果滚动视图的contentOffset非零并且设备从纵向旋转到横向,则滚动视图的内容偏移量将自动设置为32px。 (见截图) content offset wrong

我已经尝试保存contentOffset并在调用scrollViewDidEndDecelerating:时将其设置为此保存的值但是很难看,因为滚动视图滚动到32px偏移然后回到我想要的位置是

如何控制滚动视图的contentOffset? autolayout约束是否错误?在调整视图大小时,我可以添加额外的约束来控制contentOffset吗?

4 个答案:

答案 0 :(得分:8)

32px来自哪里?它与你的左右滚动页边距有关吗?

每次更改页面时是否保留错误的偏移量?如果是这种情况,您应该查看您的scrollView的contentInsets值。

否则,我在使用分页管理scrollView上的旋转时所做的就是观察scrollView的contentSize:

首先,加载视图时,添加观察者:

[self.scrollView addObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize)) options:0 context:nil];

然后,当contentSize值改变时,调整contentOffset:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (object == self.scrollView && [keyPath isEqualToString:NSStringFromSelector(@selector(contentSize))]) {

        //Note that you should track your page index
        self.scrollView.contentOffset = CGPointMake(self.pageIndex * self.scrollView.bounds.size.width, self.scrollView.contentOffset.y);

    } else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

最后,在卸载scrollView时删除观察者:

[self.scrollView removeObserver:self forKeyPath:NSStringFromSelector(@selector(contentSize)) context:nil];

答案 1 :(得分:3)

在回顾之前的一些帖子之后:one& two。您似乎可以按照以下步骤之一找到解决方案:

  1. 以编程方式:如果您的UIScrollViews的父VC不直接在导航堆栈上 -
  2. 修改

        // Without a Navigation Controller
    
        self.automaticallyAdjustsScrollViewInsets = NO;
    
        // With a Navigation Controller
    
        self.parentViewController.automaticallyAdjustsScrollViewInsets = NO;
        self.automaticallyAdjustsScrollViewInsets = NO;
    
    1. 界面生成器:属性检查器 - >取消选中布局属性中的 调整滚动视图插入

    2. 如果 仍然不成功 :在显示的视图控制器的ViewWillLayoutSubviews方法中尝试设置以下每个UIScrollView属性:

      self.scrollView.contentOffset = CGPointZero;
      self.scrollView.contentInset = UIEdgeInsetsZero;
      
    3. 我猜测选项1和2的组合将起作用,具体取决于导航堆栈的结构。

答案 2 :(得分:0)

我知道这是一个老问题,但是如果它对任何人都有用 - 我创建了一个名为UIScrollView的{​​{1}}子类,它自动应用必要的布局约束并调整内容偏移量在旋转。该类作为GitHub上MarkupKit项目的一部分提供。用法示例(Swift):

LMPageView

可以在此处找到使用标记初始化页面视图的其他示例:

答案 3 :(得分:0)

对于iOS 11.0和更高版本,以下方法可以为我解决问题:

if (@available(iOS 11.0, *))
{
    self.myScrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
}