UIScrollView không cuộn


128

Tôi có một UIScrollViewcái chứa nhiều UIImageViews, UILabels, v.v ... các nhãn dài hơn nhiều UIScrollView, nhưng khi tôi chạy ứng dụng, tôi không thể nhấp và cuộn xuống ...

Tại sao điều này có thể được?

Cảm ơn


26/03/2013 Mới, tôi đã vấp phải một cách dễ dàng hơn để làm điều này mà không cần mã (cài đặt nội dung Kích thước) stackoverflow.com/a/15649607/1705353
Dickey Singh

Câu trả lời:


169

Thật tốt khi hiển thị một đoạn mã làm việc hoàn chỉnh:

// in viewDidLoad (if using Autolayout check note below):

UIScrollView *myScrollView;
UIView *contentView;
// scrollview won't scroll unless content size explicitly set

[myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size

Swift 4.0

let myScrollView
let contentView

// scrollview won't scroll unless content size explicitly set

myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc

myScrollView.contentSize = contentView.frame.size //sets ScrollView content size

Tôi chưa tìm thấy cách đặt contentSize trong IB (kể từ Xcode 5.0) .

Lưu ý: Nếu bạn đang sử dụng Autolayout, nơi tốt nhất để đặt mã này là bên trong -(void)viewDidLayoutSubviewsphương thức.


12
Đừng quên đặt myScrollView.delegate = selfCSONG, nếu điều này vẫn không hoạt động, câu trả lời bên dưới câu hỏi này có lời khuyên TUYỆT VỜI (hãy truy cập xib / StoryBoard của bạn và đảm bảo "AutoLayout" bị tắt). Pro-Tip: Bạn cũng có thể bao gồm <UIScrollViewDelegate>trong tệp .h của mình nếu bạn muốn làm những việc như cuộn UIScrollView theo chương trình.
Albert Renshaw

1
@AlbertRenshaw bạn nên thêm một câu trả lời để tôi có thể cho bạn +1 :) AutoLayout là vấn đề với tôi .... khiến tôi phát điên trong 4 giờ.
nghiên cứu logic học

2
Đặt mã vào viewDidLayoutSubviewslàm cho nó hoạt động cho tôi.
Amr Lotfy

Đối với tôi, vấn đề là nó không cần phải cuộn, vì mọi thứ đều vừa vặn trên màn hình.
Daniel Springer

122

Nếu bạn không thể cuộn chế độ xem ngay cả sau khi bạn đặt chính xác Kích thước nội dung , hãy đảm bảo bạn bỏ chọn "Sử dụng Tự động thanh toán" trong Trình tạo giao diện -> Trình kiểm tra tệp.


164
Ngoài ra, bạn có thể đặt contentSize trong viewDidLayoutSubview : , và nó sẽ được áp dụng sau khi quá trình tự động hoàn thành.
Chris Vasselli

2
@ "Chris Vasselli" yêu thích vấn đề của tôi .. GR8 .. :-)
Ayaz 18/03/13

3
Nhận xét của Chris nên là một câu trả lời riêng biệt!
ninjaneer

1
Cảm ơn bạn rất nhiều Chris Vasselli! Với tính năng Bố trí tự động được bật, nó sẽ không hoạt động trong viewDidLoad nhưng nó hoạt động với viewDidLayoutSubview!
Romain

1
Woah, tôi chưa bao giờ nhận thấy tất cả những bình luận này trước đây! Vui mừng tôi có thể giúp rất nhiều bạn ra ngoài! Tôi chỉ đăng một câu trả lời riêng vì vậy hy vọng nó sẽ dễ tìm thấy hơn.
Chris Vasselli

68

Bạn cần đặt thuộc contentSizetính của chế độ xem cuộn để cuộn đúng.

Nếu bạn đang sử dụng autolayout, bạn cần phải thiết lập contentSizetrong viewDidLayoutSubviewsđể cho nó được áp dụng sau khi Hoàn thành autolayout.

Mã có thể trông như thế này:

-(void)viewDidLayoutSubviews
{
    // The scrollview needs to know the content size for it to work correctly
    self.scrollView.contentSize = CGSizeMake(
        self.scrollContent.frame.size.width,
        self.scrollContent.frame.size.height + 300
    );
}

Cảm ơn rất nhiều .. Điều này hoạt động vì một số lý do, ngay cả khi tôi đặt giá trị contentSizethành kích thước contentView, kích thước của scrollView và contentView dường như được đặt như nhau. Nhưng thiết lập chiều cao của contentSizegiá trị lớn hơn chiều cao của contentViewnó, nó đã hoạt động.
Skywalker

viewDidLayoutSubviewscó thể được gọi nhiều lần trong suốt vòng đời để bạn có nguy cơ tăng chiều cao lớn hơn dự kiến.
anon_nerd

@anon_nerd chỉ cần kiểm tra xem nó đã được gọi chưa và chỉ thêm chiều cao nếu không
Daniel Springer

45

Câu trả lời ở trên là chính xác - để thực hiện cuộn, cần phải đặt kích thước nội dung.

Nếu bạn đang sử dụng trình xây dựng giao diện, một cách gọn gàng để thực hiện việc này là với các thuộc tính thời gian chạy do người dùng xác định. Ví dụ:

nhập mô tả hình ảnh ở đây


điều này đã không làm bất cứ điều gì cho tôi.
coolcool1994

4
Rất tiếc, pic hiển thị {0, 0}, nhưng tất nhiên bạn phải đặt số lượng đủ lớn vào. . Cách tiếp cận này sẽ chỉ hoạt động đối với các chế độ xem đơn giản mà bạn biết trước kích thước nội dung. . . (trên thực tế, đối với các chế độ xem phức tạp, dù sao tôi cũng khuyên dùng mã thuần túy).
Jasper Blues

Ít hack hơn nhiều so với làm nó lập trình. Cảm ơn bạn!
Jake Stoeffler

1
@JakeStoeffler xin chào mừng! :) Khi sử dụng IB, tôi muốn giữ tất cả các cấu hình ở đó (không bị phân mảnh). Nhưng khi mọi thứ trở nên phức tạp (các widget xem có thể sử dụng lại, các bộ điều hợp mô hình, các thao tác lớp; CAAnimations, v.v.) thì tôi thích các khung nhìn lập trình đầy đủ. . . trôi chảy hơn.
Jasper Blues

Tôi đã thử điều này, hoạt động khi chế độ xem xuất hiện, nhưng khi thay đổi hướng, nội dung Kích thước được xác định trên màn hình ở trên bị bỏ qua và nhật ký của tôi cho biết nội dung Kích thước được đặt lại 0,0. Bất cứ ý tưởng làm thế nào để khắc phục điều đó?
Shoogle

40

Cố gắng thay đổi kích thước kích thước nội dung thành số lượng lớn. Tôi không thể hiểu tại sao chế độ xem cuộn của tôi không cuộn ngay cả khi kích thước nội dung của nó dường như lớn hơn kích thước kiểm soát. Tôi phát hiện ra rằng nếu kích thước nội dung nhỏ hơn mức cần thiết thì nó cũng không hoạt động.

self.scrollView.contentSize = CGSizeMake(2000, 2000);

Thay vì 2000 bạn có thể đặt số lượng lớn của riêng bạn. Và nếu nó hoạt động, điều đó có nghĩa là kích thước nội dung của bạn không đủ lớn khi bạn thay đổi kích thước.

Đại biểu là không cần thiết để xem cuộn để làm việc.


2
Thiên tài - một cách đơn giản để kiểm tra những gì đang xảy ra. Cảm ơn nhiều!
Tinh tinh điên

13

Đảm bảo rằng bạn có thuộc tính contentSize của chế độ xem cuộn được đặt ở kích thước chính xác (nghĩa là một thuộc tính đủ lớn để bao gồm tất cả nội dung của bạn.)


1
Tôi có phải làm điều này theo chương trình không? hoặc tôi có thể làm điều đó trong IB?
Đánh dấu

Nếu bạn đang sử dụng IB, bạn có thể đặt nó từ đó - xem bên dưới. . (Câu trả lời riêng biệt, vì vậy tôi có thể bao gồm các bức ảnh).
Jasper Blues

7

Bỏ chọn 'Sử dụng Autolayout' đã giúp tôi.

Môi trường: xCode 5.0.2 Bảng phân cảnh ios7


5

Trong trường hợp của tôi, tôi phải đặt delaysContentTouchesthành đúng vì các đối tượng bên trong scrollView đều nắm bắt các sự kiện chạm và tự xử lý thay vì để cho scrollView tự xử lý nó.


Tôi cũng có vấn đề tương tự. Vấn đề đối với tôi là bằng cách biến độ trễContentTouches thành true, bạn sẽ kết thúc với các bản vẽ chất lượng thấp hơn bằng bút chì táo. Nhưng đây là một trường hợp cạnh :) trong hầu hết các trường hợp, nó giải quyết được vấn đề
RomOne

4

Đặt contentSizethuộc tính của UIScrollviewtrong ViewDidLayoutSubviewsphương thức. Một cái gì đó như thế này

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}

3

Ý tưởng về lý do tại sao chế độ xem cuộn không cuộn vì bạn đặt kích thước nội dung để cuộn nhỏ hơn kích thước của chế độ xem cuộn, điều này là sai. Bạn nên đặt kích thước nội dung lớn hơn kích thước của chế độ xem cuộn của bạn để điều hướng qua nó trong khi cuộn.

Cùng một ý tưởng với thu phóng, bạn đặt giá trị tối thiểu và tối đa cho thu phóng sẽ được áp dụng thông qua hành động thu phóng.

chào mừng :)


3

Một bổ sung nhỏ, tất cả ở trên là những lý do thực tế tại sao chế độ xem cuộn của bạn có thể không cuộn nhưng đôi khi vô thức đây có thể là lý do đặc biệt khi scrollview được thêm thông qua mã chứ không phải IB, bạn có thể đã thêm các lượt xem của mình vào chế độ xem phụ huynh chứ không phải cuộn xem điều này làm cho các khung nhìn không cuộn

và giữ kích thước nội dung được đặt và lớn hơn khung xem chính (duhh !!)


3

Tôi đã làm cho nó hoạt động ở lần thử đầu tiên của tôi. Với bố trí tự động và tất cả mọi thứ, không có mã bổ sung. Sau đó, chế độ xem bộ sưu tập bị hỏng, gặp sự cố khi chạy, tôi không thể tìm thấy cái gì sai, vì vậy tôi đã xóa và tạo lại nó (Tôi đang sử dụng Xcode 10 Beta 4. Cảm giác như một lỗi) và sau đó cuộn đã biến mất. Chế độ xem Bộ sưu tập đã hoạt động trở lại!

Nhiều giờ sau .. đây là những gì đã sửa nó cho tôi. Tôi đã có bố cục như sau:

UIView

  • Khu vực an toàn
  • Chế độ xem cuộn
    • Xem nội dung

Đó là tất cả trong các ràng buộc. Khu vực an toàn được tự động xác định bởi hệ thống. Trong trường hợp xấu nhất, hãy xóa tất cả các ràng buộc cho chế độ xem cuộn và nội dung và không có IB đặt lại / tạo chúng cho bạn. Làm cho chúng bằng tay, nó hoạt động.

  • Đối với chế độ xem Cuộn tôi đã làm: Căn chỉnh Trailing / Top đến Vùng an toàn. Chiều rộng / chiều cao bằng với khu vực an toàn .
  • Đối với chế độ xem Nội dung tôi đã thực hiện: Căn chỉnh Trailing / Dẫn đầu / Trên / Dưới với Superview (chế độ xem cuộn)

về cơ bản, khái niệm này là có Scrollview phù hợp với Chế độ xem Nội dung, phù hợp với Vùng an toàn.

Nhưng như vậy nó không hoạt động. Xem nội dung bỏ lỡ chiều cao. Tôi đã thử tất cả những gì có thể và người duy nhất thực hiện thủ thuật là chiều cao của chế độ xem Nội dung được tạo điều khiển - kéo chế độ xem Nội dung .. sang chính nó . Điều đó đã xác định chiều cao cố định, giá trị này đã được tính từ Kích thước của bộ điều khiển chế độ xem (được xác định là dạng tự do, dài hơn màn hình thực, để chứa tất cả các bản xem trước của tôi) và cuối cùng nó hoạt động trở lại!


Bạn được chào đón! Tôi biết chính xác cảm giác của bạn .. ;-)
Michele Dall'Agata

Thaaaaks, tôi đã dành rất nhiều giờ và điều này đã giải quyết vấn đề của tôi
Andoni Da Silva

3

nếu bạn nhận được một tin nhắn (IOS8 / swift) viewDidLayoutSubviewskhông tồn tại, thay vào đó hãy sử dụng thông báo sau

override func viewDidAppear(animated: Bool)

CÁi này đã sửa nó giúp tôi


2

Một cái gì đó đã không được đề cập trước đó!

Đảm bảo ổ cắm của bạn được kết nối chính xác với scrollView! Nó nên có một vòng tròn được lấp đầy, nhưng ngay cả khi bạn đã lấp đầy vòng tròn, scrollView có thể không được kết nối - vì vậy hãy kiểm tra kỹ! Di chuột qua vòng tròn và xem nếu cuộn xem thực tế được tô sáng! (Đây là một trường hợp đối với tôi)

//Connect below well to the scrollView in the storyBoard
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

2

Rất nhiều thời gian mã là chính xác nếu bạn đã làm theo một hướng dẫn nhưng điều mà nhiều người mới bắt đầu không biết là scrollView sẽ KHÔNG cuộn bình thường thông qua trình giả lập. Giả sử chỉ cuộn khi bạn nhấn xuống bàn di chuột cuộn đồng thời. Nhiều người dùng XCode / Swift / Obj-C có kinh nghiệm thường sử dụng để làm điều này và vì vậy họ không biết làm thế nào nó có thể bị bỏ qua bởi những người mới bắt đầu. Ciao :-)

@IBOutlet weak var scrollView: UIScrollView!
override func viewDidLoad() {
    super.viewDidLoad()
    view.addSubview(scrollView)
    // Do any additional setup after the view
}

override func viewWillLayoutSubviews(){
    super.viewWillLayoutSubviews()
    scrollView.contentSize = CGSize(width: 375, height: 800)
}

Mã này sẽ hoạt động hoàn toàn tốt miễn là bạn làm những gì tôi đã nói ở trên


1

Nếu không có giải pháp nào khác phù hợp với bạn, hãy kiểm tra kỹ xem chế độ xem cuộn của bạn có thực sự là UIScrollViewtrong Trình tạo giao diện không.

Tại một số thời điểm trong vài ngày qua, UIScrollView loại tự nhiên của tôi thay đổi thành một UIView, mặc dù lớp học của nó nói UIScrollViewtrong thanh tra. Tôi đang sử dụng Xcode 5.1 (5B130a).

Bạn có thể tạo chế độ xem cuộn mới và sao chép các phép đo, cài đặt và ràng buộc từ chế độ xem cũ hoặc bạn có thể tự thay đổi chế độ xem của mình thành một UIScrollViewtrong xibtệp. Tôi đã làm một so sánh và tìm thấy sự khác biệt sau đây:

Nguyên:

<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH">
...
</scrollView>

Sau khi thay đổi tự phát:

<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd">
...
</view>

Vì vậy, tôi đã thay thế <view>dòng với <scrollView>dòng ban đầu của tôi .

Tôi cũng thay thế thẻ đóng của view </view>bằng </scrollView>.

Hãy chắc chắn giữ id giống như chế độ xem hiện tại, trong trường hợp này: id = "qRn-TP-cXd".

Tôi cũng đã phải xóa xib khỏi bộ đệm của Xcode bằng cách xóa dữ liệu dẫn xuất của ứng dụng:

  • Xcode->Window->Organizer->Projects, chọn dự án của bạn, trên dòng Dữ liệu đã tạo, nhấp vào Xóa ...

Hoặc nếu sử dụng thiết bị:

  • Xcode->Window->Organizer->Device, chọn thiết bị của bạn-> Ứng dụng, chọn ứng dụng của bạn, nhấp (-)

Bây giờ làm sạch dự án và xóa ứng dụng khỏi trình giả lập / thiết bị:

  • Xcode->Product->Clean
  • iOS Simulator/device->pressvà giữ app->click(X) để xóa nó

Sau đó, bạn có thể xây dựng và chạy ứng dụng của mình và có chức năng cuộn lại.

PS Tôi không phải đặt kích thước nội dung của chế độ xem cuộn trong viewDidLayoutSubviewshoặc tắt bố cục tự động, nhưng YMMV.


1

Nếu bạn scrollViewlà người phụ containerViewcủa một loại nào đó, thì hãy chắc chắn rằng bạn scrollViewđang ở trong khung hoặc giới hạn của containerView. Tôi containerView.clipsToBounds = NOvẫn có cho phép tôi xem scrollView, nhưng vì scrollViewkhông nằm trong giới hạn của containerViewnó sẽ không phát hiện ra các sự kiện chạm.

Ví dụ:

containerView.frame = CGRectMake(0, 0, 200, 200);
scrollView.frame = CGRectMake(0, 200, 200, 200);
[containerView addSubview:scrollView];
scrollView.userInteractionEnabled = YES;

Bạn sẽ có thể xem scrollView nhưng nó sẽ không nhận được tương tác của người dùng.


1

thêm mã sau vào viewDidLayoutSubviewslàm việc cho tôi với Autolayout. Sau khi thử tất cả các câu trả lời:

- (void)viewDidLayoutSubviews
{
    self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620);

}

//set the height of content size as required

1

Thêm UIScrollViewDelegatevà thêm đoạn mã sau vào viewDidAppearphương thức đã sửa nó cho tôi.

@interface testScrollViewController () <UIScrollViewDelegate>

-(void)viewDidAppear:(BOOL)animated {
    self.scrollView.delegate = self;
    self.scrollView.scrollEnabled = YES;
    self.scrollView.contentSize = CGSizeMake(375, 800);
}

1

Vấn đề của tôi đã được giải quyết bằng cách:

  1. đặt kích thước nội dung trên cuộn Xem ở độ cao lớn
  2. NHƯNG tôi cũng phải sửa các ràng buộc trên và / hoặc dưới cùng cho các chế độ xem trong cuộn Xem, có nghĩa là các chỉ báo cuộn hiển thị trên màn hình nhưng nội dung không cuộn

Khi tôi đã loại bỏ các ràng buộc trên và / hoặc dưới cùng bị ràng buộc vào vùng an toàn và / hoặc giám sát, các chế độ xem trong cuộn Xem có thể cuộn lại và không cố định ở phía trên cùng của màn hình!

Hy vọng điều này ngăn người khác khỏi hàng giờ đau đớn với vấn đề đặc biệt này.


1

một trường hợp thú vị khác:

scrollview.superview.userInteractionEnables phải đúng

Tôi đã lãng phí hơn 2 giờ để theo đuổi điều này chỉ để tìm ra cha mẹ là UIImageView, một cách tự nhiên, có userInteractionEnables == false


0

Sau khi thất bại với các câu trả lời được cung cấp trong chủ đề này, tôi tình cờ thấy bài viết này với giải pháp.

Có hai điều không trực quan về việc thiết lập scrollview với autolayout:

  1. Các ràng buộc bạn thiết lập làm lề giữa nội dung xem và cuộn xem không ảnh hưởng đến kích thước của nội dung. Họ thực sự là lợi nhuận. Và để làm cho nó hoạt động, nội dung nên có một kích thước cố định.
  2. Mẹo cho kích thước cố định là bạn có thể đặt chiều rộng của nội dung xem bằng với chiều rộng của cha mẹ của cuộn xem. Chỉ cần chọn cả hai khung nhìn trong cây bên trái và thêm các ràng buộc độ rộng bằng nhau.

Đây là ý chính của bài báo đó. Để giải thích đầy đủ, bao gồm cả hình minh họa, hãy kiểm tra nó.


@PredragManojlovic Làm thế nào nó có thể nhận được tổng quát hơn thế này? Đây là cách duy nhất tôi có thể khiến cho scrollview hoạt động bình thường, sử dụng bố cục tự động.
H. de Jrid

0

Tôi thấy rằng với vấn đề AutoLayout này ... nếu tôi chỉ ViewControllersử dụng UIViewthay vì UIScrollViewcho lớp ... thì chỉ cần thêm một UIScrollViewbản thân mình ... rằng nó hoạt động.


0

Tôi đã có cùng một vấn đề trong IB.

Sau khi đặt hàng đầu, theo dõi, trên cùng và dưới cùng của scrollView thành superView của nó. Tôi đã thực hiện các thay đổi sau để làm cho containerView có thể cuộn, hoạt động được.

Để làm cho scrollView chỉ cuộn theo hướng ngang, hãy tạo ràng buộc với scrollView's centre = ContainerView's centre

và để làm cho nó có thể cuộn theo chiều dọc, hãy làm cho scrollView's centre = ContainerView's centre

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.