Objective c 如何禁用水平滚动,并使用UIScrollView在分页时单击页面将发生更改?

Objective c 如何禁用水平滚动,并使用UIScrollView在分页时单击页面将发生更改?,objective-c,swift,uiscrollview,uisegmentedcontrol,uistackview,Objective C,Swift,Uiscrollview,Uisegmentedcontrol,Uistackview,我有一个UIScrollView,带有paginEnabled。在UIScrollView的子视图中添加了5个UIStackView,并且还有一个UISegmentedControl。我想显示当前选定的部分,还想禁用水平滚动,但视图将能够垂直滚动 让我们举一个例子: 让所选页面索引=0 用户无法水平滚动或拖动以导航到下一页 用户可以垂直滚动 现在用户在UISegmentedControl 第二页将可见 现在用户无法滚动或拖动到0和2索引 如何使用UIScrollView 尝试逻辑: - (v

我有一个
UIScrollView
,带有
paginEnabled
。在
UIScrollView
的子视图中添加了5个
UIStackView
,并且还有一个
UISegmentedControl
。我想显示当前选定的部分,还想禁用水平滚动,但视图将能够垂直滚动

让我们举一个例子:

  • 让所选页面索引=0
  • 用户无法水平滚动或拖动以导航到下一页
  • 用户可以垂直滚动
  • 现在用户在
    UISegmentedControl
  • 第二页将可见
  • 现在用户无法滚动或拖动到0和2索引
如何使用
UIScrollView

尝试逻辑:

- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];

CGFloat xOff = self.scrollView.frame.size.width * self.currentPage;
[self.scrollView setContentSize:CGSizeMake(xOff, self.scrollView.contentSize.height)];
//[self.scrollView setContentOffset:CGPointMake(xOff, 0) animated:true];

}

但是当我再次滚动到0页时,在更改页面后使用此UIScrollView。

我根据自己的问题使用此解决方案

segmentDidChange()
方法中

[self.scrollView.subviews makeObjectsPerformSelector: @selector(removeFromSuperview)];
self.scrollView.showsVerticalScrollIndicator = false;
self.scrollView.showsHorizontalScrollIndicator = false;

self.arrSubViews = [NSMutableArray array];

// Loading view's from xib's
// Now
UIView *containerView = [[UIView alloc]initWithFrame:self.scrollView.frame];
    containerView.translatesAutoresizingMaskIntoConstraints = false;

[self prepareStackViewforPage:index withContainerView:containerView];
现在正在为所选索引准备stackView

- (void)prepareStackViewforPage:(NSInteger)index withContainerView:(UIView *)containerView {

  [self.scrollView addSubview:containerView];

  [self applyConstraintsToParent:self.scrollView andSubView:containerView];


  UIStackView *stackView = [[UIStackView alloc] initWithArrangedSubviews:self.arrSubViews];
  [stackView setFrame:self.scrollView.frame];
  stackView.translatesAutoresizingMaskIntoConstraints = false;
  stackView.axis = UILayoutConstraintAxisVertical;
  stackView.spacing = 0;
  stackView.distribution = UIStackViewDistributionFill;
  stackView.alignment = UIStackViewAlignmentFill;
  [containerView addSubview:stackView];

  [self applyConstraintsToParent:containerView andSubView:stackView];

  [self.view updateConstraintsIfNeeded];
  [self.view layoutIfNeeded];
  [self.view layoutSubviews];
}
在applyConstraintsToParent:和subview:方法中

- (void)applyConstraintsToParent:(UIView *)parentView andSubView:(UIView *)subView {
//constraints

NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
[parentView addConstraint:leading];

NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTrailing multiplier:1.0 constant:0];
[parentView addConstraint:trailing];

NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
[parentView addConstraint:top];

NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-8];
[parentView addConstraint:bottom];

NSLayoutConstraint *equalWidth = [NSLayoutConstraint constraintWithItem:subView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:parentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];
[parentView addConstraint:equalWidth];

leading.active = true;
trailing.active = true;
top.active = true;
bottom.active = true;
equalWidth.active = true;
}
现在它只是工作良好,但现在我有以下问题

  • 通过xib高度添加的视图未动态更改
我已经就这个问题提出了一个问题

但这种逻辑在故事板中运行良好吗


在您的问题之后,将
IsScrolEnabled
属性
UIScrollView
设置为
false
的答案如下:

目标C

斯威夫特

正如苹果公司文档中所述,该属性:

确定是否启用滚动的布尔值

如果此属性的值为true,则启用滚动;如果为false,则禁用滚动。默认值为true。 禁用滚动时,滚动视图不接受触摸事件;它将它们转发到应答器链上

因此,您的
scrollView
将不接受触摸,但
scrollView
的内容将接受触摸

这并不禁止您以编程方式滚动
滚动视图
(这将更改
滚动视图
内容偏移量
属性)。因此,当您的
UISegmentedControl
的选定部分发生更改时,您应该根据页面大小计算
scrollView
的新内容偏移量并进行设置,我建议您使用
setContentOffset(uuuuu:animated:)
方法
UIScrollView
来实现滚动


希望有帮助。

您可以在启用分页的情况下使用UICollectionView,并在内部实现启用垂直滚动的UIScrollView。使用以下代码禁用UICollectionView滚动并在单击时更改索引集合单元格:

接受 新编辑的答案:

将此添加到ViewDidLayoutSubView中

SWIFT

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let indexPath = IndexPath(item: 12, section: 0)
    self.collectionView.scrollToItem(at: indexPath, at: [ .centeredHorizontally], animated: true)
}
通常情况下,.centervertical就是这种情况

目标-C

-(void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
   [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}

计算所选页面的Y位置,并将滚动视图的contentOffSet设置为该位置。正如您在注释行中所做的,但是这里X将始终为0,只需正确计算Y。但我的问题是,如何使用我的方法禁用水平滚动,我无法禁用它。另外,X不总是0,让宽度为355,选择的页面为1,所以X将为355?你能详细说明一下吗?我不明白你想说什么?请给出一个更好的解释。它会帮助我更好。你为什么要去掉Swift标签。我对这两种语言都非常熟悉,因此我不认为这是一个特定于语言的问题。可以使用UIPageViewController和UIViewController(将UIScrollView作为子视图)来实现所解释的功能。如果您正在执行此操作,则仅限于UIScrollView,我可以为您提供解决方案。如果您在执行此操作时遇到任何问题,请告诉我。谢谢,您的代码运行良好。我正在寻找更规范的答案。如果它运行良好,它应该是正确的答案。您需要什么样的更多信息。我目前正在研究此解决方案。如果它运行良好,我将标记它很快被接受。而且,在应用it内容时,也不需要.centeredVertical始终滚动到中心。从你的答案中删除它。好的,酷。如果你需要什么,请告诉我。
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let indexPath = IndexPath(item: 12, section: 0)
    self.collectionView.scrollToItem(at: indexPath, at: [ .centeredHorizontally], animated: true)
}
-(void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
   [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}