ios – Swift:如何让ScrollView与PageControl一起使用?

ios – Swift:如何让ScrollView与PageControl一起使用?,第1张

概述严格遵循 this教程,在使用UIScrollView进行分页的部分中,我刚刚实现了一个ScrollView,用作幻灯片,其中包含来自先前UICollectionViewController的下载照片.加载滚动视图时,它不能很好地工作,因为我看到这些: 相反,当我向后滑动图像时,它们以正确的方式显示,每页一个.或者更好的是,当我在幻灯片中获得第4个图像时,这个问题就消失了,只有在那个时候,所有以下 严格遵循 this教程,在使用UIScrollVIEw进行分页的部分中,我刚刚实现了一个ScrollVIEw,用作幻灯片,其中包含来自先前UICollectionVIEwController的下载照片.加载滚动视图时,它不能很好地工作,因为我看到这些:

相反,当我向后滑动图像时,它们以正确的方式显示,每页一个.或者更好的是,当我在幻灯片中获得第4个图像时,这个问题就消失了,只有在那个时候,所有以下的图像都是正确的,前面也是如此.这是影响前2或3个图像的问题.

此外,幻灯片甚至不是从用户刚刚点击的UICollectionVIEwCell开始,而是始终从第一个开始.你可以在这里阅读所有代码:

import Foundationimport UIKitclass 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 nothing2 - 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)    }}}

我想问题可能是/ *** /这是我在教程中没有理解的内容.感谢您的关注

UPDATE
在SO中查找类似的帖子,有人建议在vIEwDIDLayoutSubvIEws()中创建子视图,所以这是我刚试过的:

overrIDe func vIEwDIDLayoutSubvIEws() {    self.loadVisiblePages()}

现在图像被正确显示,并且前3个图像不再有那么奇怪的效果.但为什么?我是初级iOS开发人员,我仍然不知道所有要覆盖的方法以及它们的工作顺序.无论如何,另一个持续存在的问题是,即使拍摄了另一个图像,图像也始终从第一个开始显示.例如,看看这个:

即使点击了另一个图像,也始终显示第一个图像(左上角).最后,在我的代码中,我实现了委托方法以进行缩放,但它也不起作用.

更新2

当用户点击一个单元格时,这是来自前一个UICollectionVIEwController的prepareForSegue()代码:

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    }}
解决方法 您应该将滚动视图的偏移更新为等于转换后要显示的图像的偏移量. self.scrollVIEw.contentOffset = CGPoint(x:pagesScrollVIEwSize.wIDth * CGfloat(self.firstToShow),y:0.0)您可以在vIEwDIDLayoutSubvIEws中执行此 *** 作,这将使其看起来像:

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

您突出显示的行只是向下舍入到最近的图像索引,以确定滚动视图所在的页面.问题是当您的视图控制器显示时没有滚动,因此它将始终显示第一个图像.要获得要首先显示的图像,您只需计算图像的偏移量,将滚动视图的偏移量设置为如上所示.

总结

以上是内存溢出为你收集整理的ios – Swift:如何让ScrollView与PageControl一起使用?全部内容,希望文章能够帮你解决ios – Swift:如何让ScrollView与PageControl一起使用?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1065489.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存