Как отключить горизонтальную прокрутку, и страница будет меняться при нажатии на пейджинг с использованием UIScrollView?

У меня есть UIScrollView с pagingEnabled. Добавлено 5 UIStackView для UIStackView UIScrollView а также один UISegmentedControl. Я хочу показать выбранный сегмент в данный момент, а также хочу отключить горизонтальную прокрутку, но просмотр будет способен прокручивать по вертикали.

давайте возьмем пример:

  • Пусть выбранный индекс страницы = 0
  • Пользователь не может прокручивать или перетаскивать по горизонтали, чтобы перейти к следующей странице.
  • Пользователь может прокручивать по вертикали
  • Теперь выбранная пользователем страница index = 1 в UISegmentedControl
  • 2-я страница будет видна
  • Теперь пользователь не может прокручивать или перетаскивать до 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];

}

но используя этот UIScrollView после смены страницы. Когда я снова прокручу страницу, перейдите на страницу 0.

Ответ 1

Вы можете использовать UICollectionView с включенным пейджингом, и внутри вы можете реализовать UIScrollView с возможностью вертикальной прокрутки. Отключите прокрутку UICollectionView и измените ячейку коллекции индексов на клик, используя следующий код:

принят Новый, Отредактированный ответ:

Добавьте это в viewDidLayoutSubviews

СВИФТ

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

Обычно,.центрально.

Objective-C

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

Ответ 2

Я использую это решение по своему собственному вопросу

В segmentDidChange()

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

self.arrSubViews = [NSMutableArray array];

// Loading view 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 и ограничение высоты содержимого subView не отразилось на каких-либо изменениях?

Но эта логика отлично работает в раскадровке?

Storyboard Demo

Ответ 3

Следуя вашему вопросу, ответьте, чтобы установить свойство isScrollEnabled UIScrollView в false следующим образом:

Для цели-C

[self.scrollView setScrollEnabled:NO];

Для быстрых

self.scrollView.isScrollEnabled = false

Как сказано в документации Apple об этом свойстве:

Логическое значение, определяющее, включена ли прокрутка.

Если значение этого свойства истинно, прокрутка включена, а если она ложна, прокрутка отключена. Значение по умолчанию - true. Когда прокрутка отключена, просмотр прокрутки не принимает события касания; он перенаправляет их на цепочку ответчиков.

Таким образом, ваш scrollView не будет принимать штрихи, но содержимое вашего scrollView будет.

И это не запрещает вам прокручивание scrollView программно (который меняется contentOffset свойства вашего scrollView). Поэтому, когда выбранный сегмент вашего UISegmentedControl изменился, вы должны рассчитать новое смещение контента для вашего scrollView зависимости от размера страницы и установить его. Я рекомендую использовать setContentOffset(_:animated:) UIScrollView для достижения прокрутки.

Надеюсь, поможет.