如何禁用水平滚动并且页面将在使用 UIScrollView 的分页中单击时更改?

How can I disable horizontal scrolling and page will change on click in paging using UIScrollView?

我有一个 UIScrollViewpagingEnabled。添加了 5 UIStackViewUIScrollView 的子视图,还有一个 UISegmentedControl。我想显示当前选择的片段,也想禁用水平滚动,但视图可以垂直滚动。

举个例子:

如何使用 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];

}

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

我正在使用我自己的问题的解决方案

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:andSubView中:方法

- (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 添加的视图高度不会动态变化

我已经在 UIStackView 上提出了这个问题:从 xib 加载视图并更新子视图的高度约束没有反映任何变化?

但是这个逻辑在情节提要中工作得很好吗?

根据您的问题,将 UIScrollViewisScrollEnabled 属性 设置为 false 的答案如下:

For Objective-C

[self.scrollView setScrollEnabled:NO];

For swift

self.scrollView.isScrollEnabled = false

正如 Apple 文档所说 属性:

A Boolean value that determines whether scrolling is enabled.

If the value of this property is true , scrolling is enabled, and if it is false , scrolling is disabled. The default is true. When scrolling is disabled, the scroll view does not accept touch events; it forwards them up the responder chain.

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

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

希望对您有所帮助。

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

已接受 新的、经过编辑的答案:

在viewDidLayoutSubviews中添加这个

SWIFT

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let indexPath = IndexPath(item: 12, section: 0)
    self.collectionView.scrollToItem(at: indexPath, at: [ .centeredHorizontally], animated: true)
}

正常情况下.centerVertically是这样的

Objective-C

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