my initial problems with UIScrollView now appear t

2019-03-04 16:52发布

问题:

For my first challenge using UIScrollView I modified this example to make UIScrollView display not just another background colour but another UIView and UILabel on each page. But I could have just as easily chosen to display objects like UITableView, UIButton or UIImage.

Potentially, UIScrollView could be much more than a giant content view where users scroll from one part to the next, e.g., some pages might have a UIButton that takes a user to a specific page, the same way we use books.

Code Improvements

My question has evolved since I first posted it. Initially the labels piled up on page 1 (as shown below) but this has now been corrected. I also included this extension to make the font larger.

Further improvement ?

As the code evolved I became more aware of other issues e.g. iPhone 5 images (below) appear differently on iPhone 7 where the UILabel is centred but not the UIView. So my next challenge is possibly to learn how to combine UIScrollView with Autolayout. I invite anyone to spot other things that might be wrong.

ViewController.swift (corrected)

import UIKit

class ViewController: UIViewController,UIScrollViewDelegate {

let scrollView       = UIScrollView(frame: CGRect(x: 0, y: 0, width: 320, height: 480))

var views            = [UIView]()
var lables           = [UILabel]()

var colors:[UIColor] = [UIColor.red, UIColor.magenta, UIColor.blue, UIColor.cyan, UIColor.green, UIColor.yellow]
var frame: CGRect    = CGRect.zero
var pageControl: UIPageControl = UIPageControl(frame: CGRect(x: 50, y: 500, width: 200, height: 50))


override func viewDidLoad() {
    super.viewDidLoad()

    initialiseViewsAndLables()
    configurePageControl()

    scrollView.delegate = self
    self.view.addSubview(scrollView)

    for index in 0..<colors.count {

        frame.origin.x = self.scrollView.frame.size.width * CGFloat(index)
        frame.size                            = self.scrollView.frame.size
        self.scrollView.isPagingEnabled       = true

        views[index].frame               = frame
        views[index].backgroundColor     = colors[Int(index)]
        views[index].layer.cornerRadius  = 20
        views[index].layer.masksToBounds = true

        lables[index].frame              = frame
        lables[index].center             = CGPoint(x: (view.frame.midX + frame.origin.x), y: view.frame.midY)
        lables[index].text               = String(index + 1)
        lables[index].defaultFont        = UIFont(name: "HelveticaNeue", size: CGFloat(200))
        lables[index].textAlignment      = .center
        lables[index].textColor          = .black

        let subView1                     = views[index]
        let subView2                     = lables[index]

        self.scrollView .addSubview(subView1)
        self.scrollView .addSubview(subView2)
    }

    print(views, lables)

    self.scrollView.contentSize               = CGSize(width: self.scrollView.frame.size.width * CGFloat(colors.count), height: self.scrollView.frame.size.height)
    pageControl.addTarget(self, action: Selector(("changePage:")), for: UIControlEvents.valueChanged)
}


func initialiseViewsAndLables() {
    // Size of views[] and lables[] is linked to available colors
    for index in 0..<colors.count {
        views.insert(UIView(), at:index)
        lables.insert(UILabel(), at: index)
    }
}

func configurePageControl() {
    // Total number of available pages is based on available colors
    self.pageControl.numberOfPages                 = colors.count
    self.pageControl.currentPage                   = 0
    self.pageControl.backgroundColor               = getColour()
    self.pageControl.pageIndicatorTintColor        = UIColor.black
    self.pageControl.currentPageIndicatorTintColor = UIColor.green
    self.view.addSubview(pageControl)

}

func getColour() -> UIColor {
    let index = colors[pageControl.currentPage]
    return (index)
}

func changePage(sender: AnyObject) -> () {
    scrollView.setContentOffset(CGPoint(x: CGFloat(pageControl.currentPage) * scrollView.frame.size.width, y: 0), animated: true)
}

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

    let pageNumber                                  = round(scrollView.contentOffset.x / scrollView.frame.size.width)
    pageControl.currentPage                         = Int(pageNumber)
    pageControl.backgroundColor                     = getColour()
    }
}

Extension

    extension UILabel{
    var defaultFont: UIFont? {
        get { return self.font }
        set { self.font = newValue }
    }
}

回答1:

The centre point of the lable on each frame must be offset by the origin of the content view (as Baglan pointed out). I've modified the following line of code accordingly.

lables[Int(index)].center = CGPoint(x: (view.frame.midX + frame.origin.x), y: view.frame.midY)