1
votes

I would like my scrollview's frame to be the same size as the superview's frame. And set the contentsize so that it contains all the imageViews.

The problem is with AutoLayout, the width and height is 600 x 480, I use an iphone5 and the size class is w:Compact / h:Any.(I expected something like : 320 x 523 ).
My constraints are : Equal Width with superview, Equal Height with superview (multiplier 0.8), horizontal center X, and vertical center Y.

let pagesScrollViewSize = scrollView.frame.size
println("pagesScrollViewSize : \(pagesScrollViewSize)") //600x480
scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(pageCount), pagesScrollViewSize.height)

Would someone know how to solve this? The imageview appears bigger than the frame of the screen, so the .SizeAspectFit does not follow the right dimensions. Instead of scrolling to another imageView, it scrolls to see the rest of the image, which I don't want.

EDIT:
This is the whole code in ViewController.swift :

class ViewController: UIViewController, UIScrollViewDelegate {

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

    var pageViews: [UIImageView?] = []
    var pageImages : [UIImage?] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        pageImages = [UIImage(named:"photo1.png"),
        UIImage(named:"photo2.png"),
        UIImage(named:"photo3.png"),
        UIImage(named:"photo4.png")]

        let pageCount = pageImages.count
        pageControl.currentPage = 0
        pageControl.numberOfPages = pageCount

        for _ in 0..<pageCount {
            pageViews.append(nil)
        }

        let pagesScrollViewSize = scrollView.frame.size
        println("pagesScrollViewSize : \(pagesScrollViewSize)")
        scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * CGFloat(pageCount), pagesScrollViewSize.height)
        loadVisiblePages()
    }

    //when scrolling
    func scrollViewDidScroll(scrollView: UIScrollView!){
        loadVisiblePages()
    }

    func loadVisiblePages(){
        let pageWidth = scrollView.frame.size.width
        let page = Int(floor( (scrollView.contentOffset.x * 2.0 + pageWidth) / (pageWidth*2.0) ))
        println("page: \(page)")
        pageControl.currentPage = page
        let firstPage = page-1
        let lastPage = page+1
        //remove all the pages before firstPage
        for var index = 0; index < firstPage; ++index{
            purgePage(index)
        }
        //load pages in our range
        for var index = firstPage; index <= lastPage; ++index {
            loadPage(index)
        }
        //remove after lastPage
        for var index = lastPage+1; index < pageImages.count; ++index {
            purgePage(index)
        }
    }

    func loadPage(index:Int){
        if index < 0 || index >= pageImages.count {
            return
        }
        if let pageView = pageViews[index] {
            //already loaded
        }
        else {
            var frame = scrollView.bounds
            frame.origin.x = frame.size.width * CGFloat(index)
            frame.origin.y = 0.0
            println("\(frame)")

            var newImageView = UIImageView(image:pageImages[index])
            newImageView.contentMode = .ScaleAspectFit
            newImageView.frame = frame
            scrollView.addSubview(newImageView)

            pageViews[index] = newImageView
        }
    }

    func purgePage(index:Int){
        if index < 0 || index >= pageImages.count {
            return
        }
        if let pageView = pageViews[index] {
            pageView.removeFromSuperview()
            pageViews[index] = nil
        }
    }

}

Thanks

1
where are you checking these frames?bjtitus
@bjtitus I edited my message with the codePaul

1 Answers

4
votes

Size classes (or any auto layout changes, for that matter) are not applied until after viewDidAppear or viewDidLayoutSubviews. You will need to move this code into one of those. You are seeing the frame of the view as it is loaded out of the Interface Builder document (xib or storyboard). You should never be checking frames until after those lifecycle events.

Unable to set frame correctly before viewDidAppear