Làm cách nào để tắt tính năng cuộn ngang của UIScrollView?


92

Tôi có một UIViewchiếc Springboard giống như iPhone. Tôi đã tạo nó bằng cách sử dụng UIScrollViewUIButtons. Tôi muốn tắt tính năng cuộn ngang trên chế độ xem cuộn đã nói. Tôi chỉ muốn cuộn dọc. Làm cách nào để thực hiện điều này?


5
Bạn nên thay đổi tiêu đề của mình: bạn yêu cầu chiều ngang trong câu hỏi và chiều dọc trong tiêu đề. Mọi người tìm thấy câu hỏi của bạn sau đó trên các công cụ tìm kiếm, vì vậy nó vẫn quan trọng 2 năm sau :)
Julien

@RahulVyas Người đàn ông ở trên có lý. Thay đổi tiêu đề sẽ giảm bớt sự nhầm lẫn cho những người mới bắt đầu đến đây thông qua công cụ tìm kiếm (chẳng hạn như tôi;)).
SpacyRicochet,

Đã thay mặt người đăng bài chỉnh sửa tiêu đề. (Mặc dù nó đang chờ đánh giá ngang hàng trước khi chỉnh sửa sẽ được hiển thị.)
Duncan Babbage

Câu trả lời:


125

Bạn phải đặt thuộc contentSizetính của UIScrollView. Ví dụ: nếu UIScrollViewchiều rộng của bạn là 320 pixel (chiều rộng của màn hình), thì bạn có thể làm như sau:

CGSize scrollableSize = CGSizeMake(320, myScrollableHeight);
[myScrollView setContentSize:scrollableSize];

Sau UIScrollViewđó, di chúc chỉ cuộn theo chiều dọc, vì nó đã có thể hiển thị mọi thứ theo chiều ngang.


6
Chào. Giải pháp này hoạt động thực sự tốt! Cảm ơn vì điều đó. Tôi đã thử đặt chiều rộng tĩnh thành 0. Đối với tôi, điều này cũng hoạt động. Tôi không biết liệu có thể có một số tác dụng phụ sau này không. Nhưng nếu ai đó không biết kích thước (tức là mã phổ quát cho iPhone và iPad) thì điều này rất tuyệt!
JackPearse

5
Tôi nghĩ tốt hơn nên làm CGSizeMake (0, myScrollableHeight), do đó, tính năng cuộn ngang bị vô hiệu hóa ngay cả khi không phải tất cả các lượt xem phụ đều hiển thị.
LightNight

NB Đặt một trong các kích thước thành 0 khi sử dụng phân trang sẽ khiến VoiceOver thông báo số trang là "trang 1 trong số 1" bất kể giá trị chính xác là gì
josef

1
Thay vì truyền chiều rộng dưới dạng mã cứng 320, chúng ta có thể truyền như: CGSize scrollableSize = CGSizeMake (self.scrollview.frame.size.width, myScrollableHeight); [myScrollView setContentSize: scrollableSize];
Mohit kumar

90

CẬP NHẬT: (Sau khi @EranMarom chỉ ra nhận xét của anh ấy)

Bạn có thể dừng cuộn ngang hoặc cuộn dọc trong ScrollViewDelegatePhương pháp. Đây là cách,

Dừng cuộn ngang:

Nếu bạn muốn cuộn theo chiều ngang, thì bạn cần tăng contentOffset.x. Ngăn chặn việc dừng cuộn chế độ xem cuộn theo hướng ngang.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.x = 0.0
}

Dừng cuộn dọc:

Nếu bạn muốn cuộn theo chiều dọc, thì bạn cần phải tăng contentOffset.y. Ngăn chặn việc dừng cuộn chế độ xem cuộn theo hướng dọc.

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    sender.contentOffset.y = 0.0
}

Đoạn mã trên ngăn chặn những thay đổi trong xycủa a scrollview contentOffsetvà nó dẫn đến việc dừng scrollViewDidScroll:phương thức cuộn trong .


1
Tôi đang cân nhắc phản đối vì câu trả lời này không giải thích được rằng bạn vừa đưa ra mã và thế là xong. Trả lời như vậy không tốt lắm. Câu trả lời tốt tự giải thích, trong khi các nhà phát triển có kinh nghiệm có thể hiểu điều này, các nhà phát triển mới hơn có thể không hiểu chuyện gì đang xảy ra ở đây. Chưa phản đối vì cho cơ hội cải thiện.
Popeye

13
Đây là một loại hack, nhưng nó hoạt động khi mọi thứ khác đều thất bại. Vì vậy, +1, nhưng chỉ sử dụng như một phương sách cuối cùng.
i_am_jorf

5
Tôi cũng sử dụng phương pháp đại biểu này, nhưng tôi thay thế phần thân bằng một lớp lót, ví dụ: scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);để tắt tính năng cuộn ngang. Tôi thấy nó dễ đọc hơn, nó nhỏ hơn và không có ích gì khi thực hiện bài kiểm tra cho điểm 0 vì hầu như không có chi phí nào với mã chạy điều này không thường xuyên (tức là tối đa vài chục lần mỗi giây).
Echelon

bởi vì bạn đang thay đổi contentOffset sau "didscroll", không giống như trước 'willscroll' và đây là một giải pháp tuyệt vời, nhưng bản thân tôi đã không phản đối, bởi vì 18 lượt ủng hộ và câu trả lời là 75, vì vậy không đáng để phản đối
LolaRun

2
Dễ dàng hơn nữa, sử dụng scrollView.contentOffset.y = 0.0để dừng cuộn dọc và scrollView.contentOffset.x = 0.0dừng cuộn ngang, trong scrollViewDidScroll()chức năng đại biểu. Tuy nhiên, tôi tin rằng việc đảm bảo giá trị scrollView.contentSizebằng scrollView.frame.sizelà một giải pháp tốt hơn (đúng). Xem câu trả lời của @danbeaulieu.
emem

11

kể từ khi sử dụng iOS7

self.automaticallyAdjustsScrollViewInsets = NO;

// và tạo cho bạn cuộn trang với 3 trang

    self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)];
    [self.pageView setShowsVerticalScrollIndicator:NO];
    [self.pageView setPagingEnabled:YES];
    [self.view addSubview:self.pageView];

Tôi không nghĩ rằng điều này sẽ vô hiệu hóa hành vi cuộn của chế độ xem cuộn. Là nó??
Dinesh Raja

self.collectionView.pagingEnabled = YES;đã giúp tôi giải quyết vấn đề với việc cuộn trơn tru (không kéo). Vấn đề là ở phương thức scrollViewWillEndDragging:- targetContentOffset giống như scrollView.contentOffset và logic phát hiện trang không hoạt động bình thường.
sig

11

Giải pháp nhanh chóng

Tạo hai cửa hàng, một cho chế độ xem của bạn và một cho chế độ xem cuộn của bạn:

@IBOutlet weak var myView: UIView!
@IBOutlet weak var scrollView: UIScrollView!

Sau đó, trong viewDidLayoutSubviews của bạn, bạn có thể thêm mã sau:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: myView.frame.size.height)
scrollView.contentSize = scrollSize

Những gì chúng tôi đã làm là thu thập chiều cao và chiều rộng của chế độ xem và đặt kích thước nội dung scrollViews để phù hợp với nó. Điều này sẽ ngăn chế độ xem cuộn của bạn cuộn theo chiều ngang.


Suy nghĩ thêm:

CGSizeMake lấy chiều rộng và chiều cao bằng cách sử dụng CGFloats. Bạn có thể cần sử dụng chiều cao hiện có của UIScrollViews cho tham số thứ hai. Nó sẽ trông như thế này:

let scrollSize = CGSize(width: myView.frame.size.width, 
                        height: scrollView.contentSize.height)

Nếu bạn không biết chiều cao hoặc chiều rộng (thiết bị phổ thông) thì sao? @danbeaulieu
Lukesivi

@lukesIvi "myView.frame.width" đang tự động kéo chiều rộng từ IBOutlet "myView".
Dan Beaulieu

4

Trong trường hợp của tôi, với Swift 4.2, bạn có thể sử dụng:

Tắt cuộn dọc:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = 0.0
}

Tắt cuộn ngang:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.x = 0.0
}

3

Bạn có thể chọn chế độ xem, sau đó Attributes Inspectorbỏ chọn User Interaction Enabled.


3

Trong trường hợp của tôi, chiều rộng của contentView lớn hơn chiều rộng của UIScrollView và đó là lý do dẫn đến việc cuộn ngang không mong muốn. Tôi đã giải quyết nó bằng cách đặt chiều rộng của contentView bằng chiều rộng của UIScrollView.

Hy vọng nó sẽ giúp ai đó


@Nostradamus rất vui khi được giúp đỡ
Gulfam Khan

0

Tôi đã đặt nội dung tableviewInset trong viewDidLoad (như bên dưới), nguyên nhân gây ra cuộn ngang

self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);

Kiểm tra xem có bất kỳ nội dung chế độ xem bảng nào được đặt vì các lý do khác nhau không và tắt nó


0

Tôi đã đấu tranh với điều này trong một thời gian cố gắng không thành công các đề xuất khác nhau trong chủ đề này và các chủ đề khác.

Tuy nhiên, trong một chuỗi khác (không chắc chắn ở đâu), ai đó đã gợi ý rằng việc sử dụng một ràng buộc tiêu cực trên UIScrollView đã làm việc cho anh ta.

Vì vậy, tôi đã thử kết hợp nhiều ràng buộc khác nhau với kết quả không nhất quán. Điều cuối cùng làm việc với tôi là thêm các ràng buộc đầu và cuối của -32 vào chế độ xem cuộn và thêm chế độ xem văn bản (ẩn) với chiều rộng là 320 (và căn giữa).


0

Thử cái này:

CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight);
[scrollView setContentSize: scrollSize];

0

Tắt tính năng cuộn ngang bằng cách ghi đè contentOffsetthuộc tính trong lớp con.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: 0, y: newValue.y)
  }
}

0

Được giới thiệu trong iOS 11 là một thuộc tính mới trên UIScrollView

var contentLayoutGuide: UILayoutGuide

Tài liệu nói rằng bạn:

Sử dụng hướng dẫn bố cục này khi bạn muốn tạo các ràng buộc Bố cục Tự động liên quan đến vùng nội dung của dạng xem cuộn.

Cùng với bất kỳ trở ngại Autolayout khác mà bạn có thể có thêm bạn sẽ muốn hạn chế widthAnchorcủa UIScrollView's contentLayoutGuideđể có kích thước tương tự như 'khung'. Bạn có thể sử dụng frameLayoutGuide(cũng được giới thiệu trong iOS 11) hoặc bất kỳ chiều rộng bên ngoài nào (chẳng hạn nhưsuperView .)

thí dụ:

NSLayoutConstraint.activate([
  scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor)
])

Tài liệu: https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide



-1

Sử dụng dòng đơn này.

self.automaticallyAdjustsScrollViewInsets = NO;

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.