UIScrollView kaydırılmıyor


128

Bir var UIScrollViewbir çok içeren UIImageViewvb s, UILabels ... etiketler bu kadar uzun olanUIScrollView , ama app çalıştırdığınızda, ben tıklayın ve aşağı kaydırın olamaz ...

Bu neden olabilir?

Teşekkürler


Yeni 26.03.2013 Bunu kod olmadan yapmanın daha kolay bir yolunu buldum (contentSize ayarlayarak) stackoverflow.com/a/15649607/1705353
Dickey Singh

Yanıtlar:


169

Tam bir çalışan kod pasajı göstermek her zaman iyidir:

// 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

IB'de contentSize ayarlamanın bir yolunu bulamadım (Xcode 5.0 itibariyle) .

Not: Otomatik Düzen'i kullanıyorsanız, bu kodu yerleştirmek için en iyi yer yöntemin içidir -(void)viewDidLayoutSubviews.


12
myScrollView.delegate = selfAYRICA ayarlamayı unutmayın , eğer bu hala çalışmıyorsa, bunun altındaki yanıtta HARİKA bir tavsiye var (xib / StoryBoard'unuza gidin ve "Otomatik Yerleşim" in devre dışı bırakıldığından emin olun). Uzman İpucu: <UIScrollViewDelegate>UIScrollView'unuzu programlı olarak kaydırmak gibi şeyler yapmak istiyorsanız, .h dosyanıza da ekleyebilirsiniz .
Albert Renshaw

1
@AlbertRenshaw, size +1 verebilmem için bir cevap eklemeliydiniz :) AutoLayout benimle ilgili bir sorundu .... beni 4 saat kadar çıldırttı.
logixologist

2
Kod koymak viewDidLayoutSubviewsbenim için çalışmasını sağladı.
Amr Lotfy

Benim için sorun, her şey ekrana sığdığı için kaydırılmasına gerek olmamasıydı.
Daniel Springer

122

ContentSize'ı doğru bir şekilde ayarladıktan sonra bile görünümü kaydıramıyorsanız , Interface Builder -> File Inspector'da " Otomatik Yerleşimi Kullan" seçeneğinin işaretini kaldırdığınızdan emin olun .


165
Alternatif olarak, Belirleyebileceğiniz contentSize içinde viewDidLayoutSubviews: ve autolayout tamamlanıncaya sonra uygulanacaktır.
Chris Vasselli

2
@ "Chris Vasselli" sorunumu çözüyor .. GR8 .. :-)
Ayaz

3
Chris'in yorumu ayrı bir cevap olmalı!
ninjaneer

1
Çok teşekkür ederim Chris Vasselli! Otomatik Düzen etkinleştirildiğinde, viewDidLoad'da çalışmaz, ancak viewDidLayoutSubviews'larda çalışır!
Romain

1
Woah, bu yorumları daha önce hiç fark etmemiştim! Birçoğunuza yardım edebildiğime sevindim! Az önce ayrı bir cevap yayınladım, umarım bulması daha kolay olur.
Chris Vasselli

68

Ayarlamanız gerekiyor contentSizeDüzgün kaydırılması için kaydırma görünümünün özelliğini gerekir.

Eğer autolayout kullanıyorsanız, sette gerek contentSizede viewDidLayoutSubviewso autolayout tamamlanıncaya sonra uygulanacak sırayla.

Kod şöyle görünebilir:

-(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
    );
}

Bir ton teşekkürler .. Bu işe yaradı çünkü bazı nedenlerden dolayı değerini contentSizeboyutuna ayarlasam bile contentView, scrollView ve contentView boyutlarının aynı şekilde ayarlandığı görülüyor. Ancak yüksekliği, yüksekliğinden contentSizedaha büyük bir değere ayarlandığında contentViewişe yaradı.
Skywalker

viewDidLayoutSubviewsbir yaşam döngüsü boyunca birden çok kez çağrılabilir, böylece yüksekliği beklenenden daha fazla artırma riskini alırsınız.
anon_nerd

@anon_nerd sadece önceden çağrılıp çağrılmadığını kontrol edin ve değilse sadece yüksekliği ekleyin
Daniel Springer

45

Yukarıdaki cevap doğrudur - kaydırmayı gerçekleştirmek için içerik boyutunu ayarlamak gerekir.

Arayüz oluşturucuyu kullanıyorsanız, bunu yapmanın düzgün bir yolu kullanıcı tanımlı çalışma zamanı öznitelikleridir. Örneğin:

görüntü açıklamasını buraya girin


bu benim için hiçbir şey yapmadı.
coolcool1994

4
Hay aksi, resimde {0, 0} gösteriliyor, ancak elbette yeterince büyük sayılar girmelisiniz. . bu yaklaşım yalnızca içerik boyutunu önceden bildiğiniz basit görünümler için işe yarar. . . (aslında, karmaşık görünümler için yine de saf kodu öneririm).
Jasper Blues

Programlı olarak yapmaktan çok daha az zahmetli. Teşekkür ederim!
Jake Stoeffler

1
@JakeStoeffler hoş geldiniz! :) IB'yi kullanırken, tüm yapılandırmayı orada tutmayı seviyorum (parçalanmış değil). Ancak işler karmaşıklaştığında (yeniden kullanılabilir görünüm widget'ları; model bağdaştırıcıları, katman manipülasyonları; CA Animasyonları, vb.) O zaman tamamen programlı görünümleri tercih ederim. . . daha akıcı.
Jasper Blues

Bunu denedim, görünüm göründüğünde çalışıyor, ancak yön değişikliğinde yukarıdaki ekranda tanımlanan contentSize yok sayılıyor ve günlüğüm contentSize değerinin 0,0 geri ayarlandığını söylüyor. Bunu nasıl düzelteceğine dair bir fikrin var mı?
Shoogle

40

İçerik boyutunu çok büyük sayılara yeniden boyutlandırmayı deneyin. İçerik boyutu kontrol boyutundan daha büyük görünse bile kaydırma görünümümün neden kaydırılmadığını anlayamadım. İçerik boyutu gerekenden daha küçükse işe yaramadığını keşfettim.

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

2000 yerine kendi büyük sayılarınızı koyabilirsiniz. Ve işe yararsa, yeniden boyutlandırdığınızda içerik boyutunuzun yeterince büyük olmadığı anlamına gelir.

Kaydırma görünümünün çalışması için temsilci gerekli değildir.


2
Dahi - neler olup bittiğini kontrol etmenin çok basit bir yolu. Çok teşekkürler!
The Crazy Chimp

13

Kaydırma görünümünün contentSize özelliğinin doğru boyuta ayarlandığından emin olun (yani, tüm içeriğinizi kaplayacak kadar büyük bir tane.)


1
bunu programlı olarak yapmak zorunda mıyım? ya da IB'de yapabilir miyim?
Mark

IB kullanıyorsanız, oradan ayarlayabilirsiniz - aşağıya bakın. . (Ayrı cevap, böylece resimleri ekleyebilirim).
Jasper Blues

7

"Otomatik Düzen Kullan" seçeneğinin işaretini kaldırın, benim için hile yaptı.

Ortam: xCode 5.0.2 Storyboard'lar ios7


5

Benim durumumda delaysContentTouches, scrollView içindeki nesnelerin tümü touchView'ın kendisinin işlemesine izin vermek yerine dokunma olaylarını yakaladığı ve kendilerini işlediği için true olarak ayarlamak zorunda kaldım .


Ben de aynı sorunu yaşıyorum. Benim için sorun şu ki, DelaysContentTouches'ı doğruya çevirerek, elma kalemiyle daha düşük kaliteli çizimlerle bitireceksiniz. Ancak bu uç bir durumdur :) çoğu durumda sorunu çözer
RomOne

4

Set contentSizemalıdır UIScrollviewiçinde ViewDidLayoutSubviewsyöntemle. Bunun gibi bir şey

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

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

3

Kaydırma görünümünün neden kaydırılmadığı fikri, kaydırmak için içerik boyutunu kaydırma görünümünün boyutundan daha az ayarladığınız için yanlıştır. Kaydırma sırasında gezinmek için içerik boyutunu kaydırma görünümünüzün boyutundan daha büyük ayarlamalısınız.

Yakınlaştırmayla aynı fikirde, yakınlaştırma eylemi aracılığıyla uygulanacak yakınlaştırma için minimum ve maksimum değeri ayarlarsınız.

Hoşgeldiniz :)


3

Küçük bir ekleme, yukarıdakilerin tümü, kaydırma görünümünüzün kaydırılmamasının gerçek nedenleridir, ancak bazen bu, özellikle kaydırma görünümü IB aracılığıyla değil de kod aracılığıyla eklendiğinde neden olabilir, alt görünümlerinizi ana görünüme eklemiş olabilirsiniz. kaydırma görünümü alt görünümün kaydırılmamasına neden olur

ve içerik boyutunu ayarlanmış ve üst görünüm çerçevesinden daha büyük tutun (duhh !!)


3

İlk denememde çalıştırdım. Otomatik düzen ve her şeyle, ek kod yok. Sonra bir koleksiyon görünümü muz oldu, çalışma zamanında çöktü, neyin yanlış olduğunu bulamadım, bu yüzden onu sildim ve yeniden oluşturdum (Xcode 10 Beta 4 kullanıyorum, bir hata gibi hissettim) ve sonra kaydırma gitti. Koleksiyon görünümü yine çalıştı!

Saatler sonra ... bu benim için düzeltti. Aşağıdaki düzene sahiptim:

UIView

  • Güvenli bölge
  • Kaydırma görünümü
    • İçerik görünümü

Hepsi kısıtlamada. Güvenli Alan, sistem tarafından otomatik olarak tanımlanır. En kötü durumda, kaydırma ve içerik görünümleri için tüm kısıtlamaları kaldırın ve bunları sizin için IB sıfırlama / oluşturmaya sahip olmayın . El ile yapın, işe yarıyor.

  • Kaydırma görünümü için yaptım: İzleyen / Üstü Güvenli Alana Hizala. Güvenli alana Eşit Genişlik / Yükseklik .
  • Yaptığım İçerik görünümü için: Sonu / Başı / Üstü / Alta Hizala (kaydırma görünümü)

temelde konsept, Güvenli Alana uyan Scrollview'a uygun İçerik görünümüne sahip olmaktır.

Ama böyle olmadı. İçerik görünümü yüksekliği kaçırdı. Elimden gelen her şeyi denedim ve hile yapan tek kişi, İçerik görünümünü kontrol edip sürükleyerek oluşturulan bir İçerik görünümü yüksekliği oldu .. kendine . Bu, değer görüntüleme denetleyicisinin Boyutundan hesaplanan sabit bir yüksekliği tanımladı (serbest form olarak tanımlanır, gerçek ekrandan daha uzun, tüm alt görünümlerimi içerir) ve sonunda tekrar çalıştı!


Çok rica ederim! Ben nasıl hissettiğini iyi biliyorum .. ;-)
Michele Dall'Agata

Thaaaaks, çok saat harcadım ve bu sorunumu çözdü
Andoni Da Silva

3

Mevcut olmayan bir mesaj (IOS8 / swift) alıyorsanız viewDidLayoutSubviews, bunun yerine aşağıdakileri kullanın

override func viewDidAppear(animated: Bool)

Bu benim için düzeltti


2

Daha önce bahsedilmeyen bir şey!

Çıkışınızın scrollView'a doğru şekilde bağlandığından emin olun! Dolu bir daireye sahip olmalıdır, ancak daireyi doldurmuş olsanız bile, scrollView bağlanmamış olabilir - bu yüzden iki kez kontrol edin! Dairenin üzerine gelin ve gerçek kaydırma görünümünün vurgulanıp vurgulanmadığını görün! (Bu benim için bir durumdu)

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

2

Eğer bir öğretici izledi ama ne birçok başlayanlar değil biliyorum do scrollview olmasıdır varsa çok zaman kod doğrudur DEĞİL simülatör aracılığıyla normalde kaydırmak için gidiyor. Yalnızca fare altlığına bastığınızda ve aynı anda kaydırdığınızda kaydırma yapması gerekir . Birçok Deneyimli XCode / Swift / Obj-C kullanıcısı bunu yapmaya çok alışkındır ve bu nedenle yeni başlayanlar tarafından nasıl gözden kaçabileceklerini bilmiyorlar. 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)
}

Yukarıda söylediğimi yaptığınız sürece bu kod mükemmel şekilde çalışacaktır.


1

Diğer çözümlerden hiçbiri sizin için işe yaramazsa, kaydırma görünümünüzün aslında bir UIScrollViewArayüz Oluşturucu'da olup olmadığını iki kez kontrol edin .

Son birkaç gün içinde bir noktada, benim UIScrollView kendiliğinden değişmiş tip bir etmek UIView, olsa onun sınıf bahsedilen UIScrollViewdenetçisindeki. Kullanıyorum Xcode 5.1 (5B130a).

Ya yeni bir kaydırma görünümü oluşturmak ve eski görünümünden ölçümler, ayarları ve kısıtlamaları kopyalamak veya el ile için görünümünüzü değiştirebilir olabilir UIScrollViewde xibdosyaya. Bir karşılaştırma yaptım ve aşağıdaki farklılıkları buldum:

Orijinal:

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

Tip kendiliğinden değiştikten sonra:

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

Bu yüzden <view>çizgiyi orijinal <scrollView>çizgimle değiştirdim.

Ayrıca görünümün kapatma etiketini </view>ile değiştirdim </scrollView>.

Kimliği geçerli görünümle aynı tuttuğunuzdan emin olun, bu durumda: id = "qRn-TP-cXd".

Ayrıca, uygulamanın türetilen verilerini silerek xib'i Xcode'un önbelleğinden temizlemek zorunda kaldım:

  • Xcode->Window->Organizer->Projects, projenizi seçin, Türetilmiş Veriler satırında Sil ...

Veya bir cihaz kullanıyorsanız:

  • Xcode->Window->Organizer->Device, cihazınızı seçin-> Uygulamalar, uygulamanızı seçin, tıklayın (-)

Şimdi projeyi temizleyin ve uygulamayı simülatörden / cihazdan kaldırın:

  • Xcode->Product->Clean
  • iOS Simulator/device->pressve app->clickkaldırmak için (X) 'i basılı tutun

Daha sonra uygulamanızı oluşturup çalıştırabilmeli ve kaydırma işlevine yeniden sahip olmalısınız.

Not: Kaydırma görünümünün içerik boyutunu viewDidLayoutSubviewsotomatik mizanpajı ayarlamam veya kapatmam gerekmedi , ancak YMMV.


1

Eğer sizin scrollViewa türünün bir alt görünümü ise containerView, o zaman kendinizin scrollViewçerçevesinin veya sınırlarının içinde olduğundan emin olun containerView. containerView.clipsToBounds = NOHala scrollView'i görmeme izin veren bir şey vardı , ancak scrollViewsınırları içinde containerViewolmadığından dokunma olaylarını algılamayacaktı.

Örneğin:

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

ScrollView'i görebileceksiniz, ancak kullanıcı etkileşimlerini almayacaktır.


1

viewDidLayoutSubviewsAutolayout ile benim için aşağıdaki kodu eklemek çalıştı. Tüm cevapları denedikten sonra:

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

}

//set the height of content size as required

1

Benim için düzeltilen yönteme UIScrollViewDelegateaşağıdaki kodu ekleyin ve ekleyin viewDidAppear.

@interface testScrollViewController () <UIScrollViewDelegate>

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

1

Sorunum şu şekilde çözüldü:

  1. scrollView'da contentSize öğesini büyük bir yüksekliğe ayarlama
  2. AMA ayrıca, scrollView içindeki görünümler üzerindeki üst ve / veya alt kısıtlamaları düzeltmek zorunda kaldım, bu da kaydırma göstergelerinin ekranda gösterilmesi ancak içeriğin kaydırılmaması anlamına geliyordu.

Güvenli alana ve / veya denetime bağlı üst ve / veya alt kısıtlamaları kaldırdıktan sonra, scrollView içindeki görünümler tekrar kayabilirdi ve ekranın alt kısmına sabit kalmadı!

Umarım bu, bu sorunla ilgili olarak bir başkasının saatlerce acı çekmesini önler.


1

yine bir başka eğlenceli durum:

scrollview.superview.userInteractionEnabled doğru olmalıdır

Bunu takip ederek 2 saatten fazla zaman harcadım, sadece ebeveynin UIImageView olduğunu anlamak için, doğal olarak userInteractionEnabled == false


0

Bu konudaki verilen cevaplarda başarısız olduktan sonra, bu makaleye rastladım çözüm ile .

Kaydırma görünümünü otomatik düzen ile ayarlamanın sezgisel olmayan iki yönü vardır:

  1. İçerik görünümü ve kaydırma görünümü arasında kenar boşluğu olarak ayarladığınız kısıtlamalar, içerik görünümünün boyutunu etkilemez. Onlar gerçekten marjlar. Ve çalışmasını sağlamak için içerik görünümünün sabit bir boyutu olmalıdır.
  2. Sabit boyutun püf noktası, içerik görünümünün genişliğini kaydırma görünümünün üst öğesinin genişliğine eşit ayarlayabilmenizdir. Soldaki ağaçta her iki görünümü de seçin ve eşit genişlik sınırlamasını ekleyin.

Bu makalenin özü budur. Çizimler dahil tam bir açıklama için kontrol edin.


@PredragManojlovic Nasıl bundan daha genel olabilir? Otomatik mizanpajı kullanarak kaydırma görünümünün düzgün çalışması için tek yol budur.
H. de Jonge

0

Bu AutoLayout sorunu ile buldum ... eğer sınıf için ViewControllerkullanmak UIViewyerine sadece kullanırsam ... o zaman işe yaradığını kendim eklersem.UIScrollViewUIScrollView


0

IB'de de aynı sorunu yaşadım.

ScrollView’un başını, sonunu, üstünü ve altını superView’a ayarladıktan sonra. İşe yarayan containerView kaydırılabilir hale getirmek için aşağıdaki değişiklikleri yaptım.

ScrollView'in yalnızca yatay yönde kaydırmasını sağlamak için, scrollView'in centerY = ContainerView's centerY ile kısıtlamayı yapın.

ve dikey olarak kaydırılabilir hale getirmek için scrollView'in centerX = ContainerView's centerX

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.