2016-03-23 17 views
2

UIScrollView numaralı sayfalar bölümünde yer alan dersini takip ederek, bir önceki UICollectionViewController'dan indirilen fotoğraflarla slayt gösterisi olarak kullanmak üzere bir ScrollView uyguladık. Kaydırma görünümü yüklendiğinde Bunları olanları görmek, bunun nedeni iyi çalışmıyor:Swift: Bir ScrollView sayfası PageControl ile nasıl çalışır?

enter image description here yerine enter image description hereenter image description here

, onlar doğru yolu, her sayfa için bir tane görüntülenen görüntüleri geri kaydırın. Ya da daha iyisi, slayt gösterisinde 4'lü görüntüyü aldığımda bu sorun ortadan kalkıyor ve sadece bu noktada aşağıdakilerin hepsi doğru ve bir de önceki. İlk 2 veya 3 görüntüyü etkileyen bir sorundur.

Ayrıca, slayt gösterisi, kullanıcının yeni araca bağladığı UICollectionViewCell'dan bile başlamaz, ancak her zaman ilkinden itibaren. Sorunun ben öğretici anlaşılmaktadır değil bir şeydir /***/ ile hat olabilir sanırım

import Foundation 
import UIKit 

class PagedScrollViewController: UIViewController, UIScrollViewDelegate { 

@IBOutlet var scrollView: UIScrollView! 
@IBOutlet var pageControl: UIPageControl! 

/* This will hold all the images to display – 1 per page. 
    It must be set from the previous view controller in prepareforsegue() method: 
    it will be the array of downloaded images for that photo gallery */ 
var pageImages:[UIImage]! 

/* position in array images of the first to be showed, i.e. the one the user has just tapped */ 
var firstToShow:Int! 

var currentImageViewForZoom:UIImageView? 

/* This will hold instances of UIImageView to display each image on its respective page. 
    It’s an array of optionals, because you’ll be loading the pages lazily (i.e. as and when you need them) 
    so you need to be able to handle nil values from the array. */ 
var pageViews:[UIImageView?] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 

    self.scrollView.delegate = self 
    self.scrollView.maximumZoomScale = 1.0 
    self.scrollView.zoomScale = 10.0 

    self.pageControl.numberOfPages = self.pageImages.count 
    self.pageControl.currentPage = self.firstToShow 

    for _ in 0..<self.pageImages.count { 
     self.pageViews.append(nil) 
    } 

    /* The scroll view, as before, needs to know its content size. 
     Since you want a horizontal paging scroll view, you calculate the width to be the number of pages multiplied by the width of the scroll view. 
     The height of the content is the same as the height of the scroll view 
    */ 
    let pagesScrollViewSize = self.scrollView.frame.size 
    self.scrollView.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(self.pageImages.count), 
     height: pagesScrollViewSize.height) 

    // You’re going to need some pages shown initially, so you call loadVisiblePages() 
    self.loadVisiblePages() 

} 

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? { 
    return self.currentImageViewForZoom 
} 

func scrollViewDidScroll(scrollView: UIScrollView) { 
    self.loadVisiblePages() 
} 

/* 
Remember each page is a UIImageView stored in an array of optionals. 
When the view controller loads, the array is filled with nil. 
This method will load the content of each page. 

1 - If it's outside the range of what you have to display, then do nothing 

2 - If pageView is nil, then you need to create a page. So first, work out the frame for this page. 
    It’s calculated as being the same size as the scroll view, positioned at zero y offset, 
    and then offset by the width of a page multiplied by the page number in the x (horizontal) direction. 

3 - Finally, you replace the nil in the pageViews array with the view you’ve just created, 
    so that if this page was asked to load again, you would now not go into the if statement and instead do nothing, 
    since the view for the page has already been created 

*/ 
func loadPage(page: Int) { 
    if page < 0 || page >= self.pageImages.count { 
     //1 
     return 
    } 

    //2 
    if let _ = self.pageViews[page] {/*Do nothing. The view is already loaded*/} 
    else { 
     // 2 
     var frame = self.scrollView.bounds 
     frame.origin.x = frame.size.width * CGFloat(page) 
     frame.origin.y = 0.0 

     let newPageView = UIImageView(image: self.pageImages[page]) 
     newPageView.contentMode = .ScaleAspectFit 
     newPageView.frame = frame 
     self.scrollView.addSubview(newPageView) 

     // 3 
     self.pageViews[page] = newPageView 
     self.currentImageViewForZoom = newPageView 
    } 
} 

/* 
This function purges a page that was previously created via loadPage(). 
It first checks that the object in the pageViews array for this page is not nil. 
If it’s not, it removes the view from the scroll view and updates the pageViews array with nil again to indicate that this page is no longer there. 
Why bother lazy loading and purging pages, you ask? 
Well, in this example, it won’t matter too much if you load all the pages at the start, since there are only five and they won’t be large enough to eat up too much memory. 
But imagine you had 100 pages and each image was 5MB in size. That would take up 500MB of memory if you loaded all the pages at once! 
Your app would quickly exceed the amount of memory available and be killed by the operating system. 
Lazy loading means that you’ll only have a certain number of pages in memory at any given time. 
*/ 
func purgePage(page: Int) { 
    if page < 0 || page >= self.pageImages.count { 
     // If it's outside the range of what you have to display, then do nothing 
     return 
    } 

    // Remove a page from the scroll view and reset the container array 
    if let pageView = self.pageViews[page] { 
     pageView.removeFromSuperview() 
     self.pageViews[page] = nil 
    } 
} 

func loadVisiblePages() { 
    // First, determine which page is currently visible 
    let pageWidth = self.scrollView.frame.size.width 

    // floor() function will round a decimal number to the next lowest integer 
    let page = Int(floor((self.scrollView.contentOffset.x * 2.0 + pageWidth)/(pageWidth * 2.0))) /***/ 

    // Update the page control 
    self.pageControl.currentPage = page 

    // Work out which pages you want to load 
    let firstPage = page - 1 
    let lastPage = page + 1 

    // Purge anything before the first page 
    for var index = 0; index < firstPage; ++index { 
     self.purgePage(index) 
    } 

    // Load pages in our range 
    for index in firstPage...lastPage { 
     self.loadPage(index) 
    } 

    // Purge anything after the last page 
    for var index = lastPage+1; index < self.pageImages.count; ++index { 
     self.purgePage(index) 
    } 
} 
} 

: Burada tüm kodu okuyabilir.

override func viewDidLayoutSubviews() { 
    self.loadVisiblePages() 
} 

ve şimdi görüntüleri doğru şunlardır: işte ben sadece denedim buydu GÜNCELLEME burada Looking SO benzer mesajlar için, birisi viewDidLayoutSubviews() yılında subviews oluşturmak için tavsiye

İlginiz için teşekkür ederiz görüntülendi ve ilk 3 görüntü için bu kadar garip bir etki yok. Ama neden? Ben genç bir iOS geliştiricisiyim ve hala geçersiz kılma yöntemlerini ve çalıştıkları sıralamayı bilmiyorum. Her neyse, devam eden diğer problem, görüntülerin her zaman ilkinden, başka bir görüntüye dokunulsa bile gösterilmesidir. hep

enter image description here

(köşesini sol) ilk görüntü diğeri dokunulduğunda bile görüntülenir: Örneğin, bu bir göz. Son olarak, kodumda, yakınlaştırmaya sahip olmak için temsilci yöntemini uyguladım, ancak çalışmaz. Kullanıcı bir hücreyi dokunduğunda İşte GÜNCELLEME 2

önceki UICollectionViewController den prepareForSegue() ait kod:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "toSlideShow") { 
     let pagedScrollViewController:PagedScrollViewController = segue.destinationViewController as! PagedScrollViewController 
     pagedScrollViewController.pageImages = self.imagesDownloaded 
     pagedScrollViewController.firstToShow = self.collectionView?.indexPathsForSelectedItems()![0].row 
    } 
} 
+1

Bir UIScrollView ile çalışmayı yakınlaştırmak için kaydırma görünümünün minimumZoomScale değerini ayarlamanız gerekir. Kodunuzu viewDidLayoutSubviews'a taşımanızın gerekçesi, otomatik düzen kullanmanız ve viewDidLoad öğesinin, görünüm düzenleyicinizin çerçevesinin otomatik düzen motoru tarafından değiştirilmesinden önce çağrılmasıdır. Self.view.frame'i viewDidLoad uygulamasında yazdırırsanız, genellikle bir storyboard'daki varsayılan boyut olan 0,0,600,600 değerini görürsünüz. Self.scrollView.contentSize = CGSize (width: pagesScrollViewSize.width * CGFloat (self.pageImages.count), yükseklik: pagesScrollViewSize.height) yanlış. – beyowulf

+1

Bir hücreye dokunarak başlatılan segue için kodu readyForSegue'e yazın. – beyowulf

+0

@beyowulf Sorunuzu, yalnızca sorduğunuz kodu ekleyerek güncelledim. Umarım iyi biçimlendirilmiş çünkü smartphone'umla düzenledim çünkü şu an ofisteyim ... HERHANGİ BİR hücreye dokunduğunuzda gerçekten –

cevap

2

güncelleyebilir gereken kaydırma görünümü en ofset ofset eşit olması geçiş yaptıktan sonra göstermek istediğiniz görüntü. self.scrollView.contentOffset = CGPoint(x: pagesScrollViewSize.width * CGFloat(self.firstToShow), y: 0.0) Bunu süsü hangi, viewDidLayoutSubviews yapabilirsiniz: vurgulu

override func viewDidLayoutSubviews() { 
     super.viewDidLayoutSubviews() 
     self.scrollView.delegate = self 
     self.scrollView.maximumZoomScale = 2.0 
     self.scrollView.zoomScale = 1.0 
     self.scrollView.minimumZoomScale = 0.5 

     self.pageControl.numberOfPages = self.pageImages.count 
     self.pageControl.currentPage = self.firstToShow 

     for _ in 0..<self.pageImages.count { 
      self.pageViews.append(nil) 
     } 

     /* The scroll view, as before, needs to know its content size. 
     Since you want a horizontal paging scroll view, you calculate the width to be the number of pages multiplied by the width of the scroll view. 
     The height of the content is the same as the height of the scroll view 
     */ 
     let pagesScrollViewSize = self.scrollView.frame.size 
     self.scrollView.contentSize = CGSize(width: pagesScrollViewSize.width * CGFloat(self.pageImages.count), 
      height: pagesScrollViewSize.height) 

     self.scrollView.contentOffset = CGPoint(x: pagesScrollViewSize.width * CGFloat(self.firstToShow), y: 0.0) 

     // You’re going to need some pages shown initially, so you call loadVisiblePages() 
     self.loadVisiblePages() 

    } 

hat sadece kaydırma görünümü üzerinde ne sayfa belirlemek için en yakın görüntü endeksine aşağı yuvarlama. Sorun, görüntüleyici denetleyicinizin görüntülendiğinde, kaydırma yapılmadığı için her zaman ilk resmi gösterir. İlk önce göstermek istediğiniz görüntüyü elde etmek için, sadece görüntü için kaymanın ne olması gerektiğini, kaydırma görünümünüzü yukarıda gösterildiği gibi ayarlayacağını hesaplayabilirsiniz.

+0

gerçekten teşekkür ederim. Şimdi gördüğüm ilk görüntü, dokunulduğu. Her neyse, artık diğer görüntüleri kaydırmıyorum ... kaydırmaya çalıştığımda, geçerli resmin bir bölümünü ve önceki veya sonraki kısmının bir kısmını görüyorum ... ve sayfa güncellenmiyor ... –

İlgili konular