Objective c UIScrollView在iOS11中不滚动

Objective c UIScrollView在iOS11中不滚动,objective-c,uiscrollview,nslayoutconstraint,ios11,Objective C,Uiscrollview,Nslayoutconstraint,Ios11,我在code中创建了一个UIScrollView,它在iOS10中工作。我今天更新了我的Xcode,它不再在iOS11中滚动(模拟器是iOS11,不能工作;物理iPad仍然是iOS10,可以工作) 用户可以在需要时添加子视图。当它是第一个子视图时,我将它锚定到滚动视图的左侧、顶部和底部。然后我将子视图的右侧锚定到滚动视图的右侧,滚动视图给出了contentSize的大小,因此它知道需要启用滚动 UIScrollView *scrollViewMain = [UIScrollView new];

我在code中创建了一个
UIScrollView
,它在iOS10中工作。我今天更新了我的Xcode,它不再在iOS11中滚动(模拟器是iOS11,不能工作;物理iPad仍然是iOS10,可以工作)

用户可以在需要时添加子视图。当它是第一个子视图时,我将它锚定到滚动视图的左侧、顶部和底部。然后我将子视图的右侧锚定到滚动视图的右侧,滚动视图给出了
contentSize
的大小,因此它知道需要启用滚动

UIScrollView *scrollViewMain = [UIScrollView new];
scrollViewMain.delegate = self;
scrollViewMain.backgroundColor = [UIColor greenColor];
scrollViewMain.translatesAutoresizingMaskIntoConstraints = NO;
scrollViewMain.directionalLockEnabled = YES;
self.scrollViewMain = scrollViewMain;

... // other code

if (self.countPlayers == 1) {
    [self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[playerCardView(400)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
    [self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[playerCardView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeRight multiplier:1 constant:10];

    self.constraintScrollViewRight = constraint;

    [self.scrollViewMain addConstraint:constraint];
}
else {
    [self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[previousPlayerCardView]-[playerCardView(==previousPlayerCardView)]" options:0 metrics:nil views:@{@"previousPlayerCardView": player.previousPlayer.playerViewCard, @"playerCardView": player.playerViewCard}]];

    [self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[playerCardView]|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
}

if (self.constraintScrollViewRight) {
    [self.scrollViewMain removeConstraint:self.constraintScrollViewRight];
}

NSLayoutConstraint *constraintRight = [NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeRight multiplier:1 constant:10];
self.constraintScrollViewRight = constraintRight;
[self.scrollViewMain addConstraint:constraintRight];

[self.scrollViewMain layoutIfNeeded];
DLog(@"self.scrollViewMain: %@", self.scrollViewMain);
DLog(@"self.scrollViewMain.contentSize: %@", NSStringFromCGSize(self.scrollViewMain.contentSize));
contentSize
确实比滚动视图的框架更大:

2017-10-04 20:01:58.479446-0500 [ViewController addPlayer]_block_invoke [Line 242] self.scrollViewMain: <UIScrollView: 0x7fa9fd01b000; frame = (286 20; 462 1014); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60000005ff20>; layer = <CALayer: 0x600000233580>; contentOffset: {0, 0}; contentSize: {826, 89}; adjustedContentInset: {0, 0, 0, 0}>
2017-10-04 20:01:58.479969-0500 [ViewController addPlayer]_block_invoke [Line 243] self.scrollViewMain.contentSize: {826, 89}
它什么也不做

解决方案:

我变了

[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[playerCardView(200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];

UIScrollView
现在有一个左右定位点,可以计算其
contentSize

这是一个糟糕的错误,视觉格式现在部分被破坏了

为什么iOS11会破坏我的代码


因为这是苹果的工作。

尝试创建所有约束,而不使用NSLAYOUTCONSTRAINTS WITH VISUALFORMAT:

在升级到XCode 9之后,我在iOS 11上的应用程序中遇到了完全相同的问题

在几个小时试图找出是什么约束导致了代码中的问题后,我碰巧用VisualFormat:替换了对NSLayoutConstraints的所有调用,而是使用NSLayoutConstraintWithitem:通过“代码”构建约束;现在,它的工作原理是


我猜苹果修改了视觉格式分析器,导致了一些意想不到的副作用…

哈哈,这是一个快速的反应!:这是真正的男人。每次新的iOS出现时,都会有一些东西坏掉。希望有一个切实可行的解决办法。同时,很抱歉滥用了答案部分。这里有同样的问题,同样的问题。我还有一个“无限循环”,计算
内容大小
,当添加布局约束时,它会使我的应用程序冻结。iOS 11.1测试版上仍然存在相同的问题:(这是一个重要的重构…是否有其他人与@Hypo取得了相同的成功?还有@Hypo,您重构了所有约束还是仅重构了UIScrollView的子视图?仅重构了UIScrollView的直接子视图…我猜,只有约束连接到UIScrollView的内容宽度和/或高度才是最重要的。)重构…至少在我的例子中是这样的…这样做了。我将VF更改为约束,它现在可以滚动。添加了解决方案。我猜它只与
UIScrollView
有关;子视图需要附加到滚动视图的侧面,这样它就可以计算
contentSize
并知道是否需要滚动。是否有有没有人向苹果公司提出过这个问题?
[self.scrollViewMain addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[playerCardView(200)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(playerCardView)]];
[self.scrollViewMain addConstraint:[NSLayoutConstraint constraintWithItem:self.scrollViewMain attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:playerCardView attribute:NSLayoutAttributeLeft multiplier:1 constant:10]];