简体   繁体   English

如何在 UIScrollView 中将起始页面更改为另一个页面

[英]How to change starting page to another page in UIScrollView

I've created a scroll view where the user can cycle through the pages that I've assigned.我创建了一个滚动视图,用户可以在其中循环浏览我分配的页面。 The first button leads to page1 as the starting page.第一个按钮导致page1作为起始页面。 However I would like the current starting page to be page 2 when I press button 2 that leads me to the page views but I can't seem to find a way around it,但是,当我按下按钮 2 时,我希望当前的起始页面是第 2 页,这会引导我进入页面视图,但我似乎找不到解决方法,

My code in the ViewController is as follows:我在ViewController中的代码如下:

var pages : [View] {
    
    get {
        let page1: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page1.colorLabel.text = "Apartment A3"
        page1.priceLabel.text = "N$ 504 500"
        page1.imageView.image = UIImage(named: "apartment_a3_1")
        
        
        let page2: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page2.colorLabel.text = "Apartment A4"
        page2.priceLabel.text = "N$ 481 000"
        page2.imageView.image = UIImage(named: "apartment_a4_1")
        
        let page3: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page3.colorLabel.text = "Apartment A5"
        page3.priceLabel.text = "N$ 541 000"
        page3.imageView.image = UIImage(named: "apartment_a5_1")
        
        let page4: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page4.colorLabel.text = "Apartment A6"
        page4.priceLabel.text = "N$ 553 000"
        page4.imageView.image = UIImage(named: "apartment_a6_1")
        
        let page5: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page5.colorLabel.text = "Apartment A8"
        page5.priceLabel.text = "N$ 588 000"
        page5.imageView.image = UIImage(named: "apartment_a8_1")
        
        let page6: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page6.colorLabel.text = "Apartment A9"
        page6.priceLabel.text = "N$ 775 000"
        page6.imageView.image = UIImage(named: "apartment_a9a1")
        
        let page7: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
        page7.colorLabel.text = "Apartment A12"
        page7.priceLabel.text = "N$ 775 000"
        page7.imageView.image = UIImage(named: "apartment_a12_a")
        

        return [page1, page2, page3, page4, page5, page6, page7]
    }
}

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

override func viewDidLoad() {
    super.viewDidLoad()
    
    //view.bringSubviewToFront(pageControl)
    
    setupScrollView(pages: pages)
    
    pageControl.numberOfPages = pages.count
    pageControl.currentPage = 0
}

func setupScrollView(pages: [View]) {
    //scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
    scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(pages.count), height: view.frame.height)
    scrollView.isPagingEnabled = true
    
    
    for i in 0 ..< pages.count {
        pages[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
        scrollView.addSubview(pages[i])
    }
}

extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
        pageControl.currentPage = Int(pageIndex)
    }
}

I've tried to change PageControl.currentPage = 0 to 1 but no luck.我试图将PageControl.currentPage = 0更改为1但没有运气。

Couple notes...情侣笔记...

First, you should be using auto-layout -- makes it much easier to manage the frames and the scroll view content.首先,您应该使用自动布局——让管理框架和滚动视图内容变得更加容易。

Second, keep your size calculations relative to the scroll view's frame, not the view's frame... it will keep things more consistent, and avoid problems if you decide to make the scroll view not "full screen" (which you shouldn't do anyway, because you always want to respect the safe-area).其次,保持你的尺寸计算相对于滚动视图的框架,而不是视图的框架......它会使事情更加一致,并且如果你决定让滚动视图不是“全屏”(你不应该这样做),可以避免问题无论如何,因为你总是想尊重安全区)。

Third, if you only have 7 "pages" this approach should be fine.第三,如果你只有7 个“页面”,这种方法应该没问题。 If you may have more than that, you can run into memory issues.如果您可能有更多,您可能会遇到内存问题。 If that's the case, you should look into either a UICollectionView or UIPageViewController .如果是这种情况,您应该查看UICollectionViewUIPageViewController

So, assuming you can stick with the scroll view approach...因此,假设您可以坚持使用滚动视图方法...

To "start at the second page" you can set the scroll view's .contentOffset.x during viewDidLayoutSubviews .要“从第二页开始”,您可以在viewDidLayoutSubviews期间设置滚动视图的.contentOffset.x

Start by adding a var property to track the width of the scroll view's frame:首先添加一个var属性来跟踪滚动视图框架的宽度:

var scrollViewWidth: CGFloat = 0

then implement viewDidLayoutSubviews() :然后实现viewDidLayoutSubviews()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    // we only want to call this once
    if scrollViewWidth != scrollView.frame.width {
        scrollViewWidth = scrollView.frame.width
        scrollView.contentOffset.x = scrollView.frame.width
    }
}

Here's a quick look at some changes you might want to make to take advantage of the benefits of auto-layout:以下是您可能想要进行的一些更改以利用自动布局的好处的快速浏览:

class ViewController: UIViewController {

    var pages : [View] {
        
        get {
            let page1: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page1.colorLabel.text = "Apartment A3"
            page1.priceLabel.text = "N$ 504 500"
            page1.imageView.image = UIImage(named: "apartment_a3_1")
            
            
            let page2: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page2.colorLabel.text = "Apartment A4"
            page2.priceLabel.text = "N$ 481 000"
            page2.imageView.image = UIImage(named: "apartment_a4_1")
            
            let page3: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page3.colorLabel.text = "Apartment A5"
            page3.priceLabel.text = "N$ 541 000"
            page3.imageView.image = UIImage(named: "apartment_a5_1")
            
            let page4: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page4.colorLabel.text = "Apartment A6"
            page4.priceLabel.text = "N$ 553 000"
            page4.imageView.image = UIImage(named: "apartment_a6_1")
            
            let page5: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page5.colorLabel.text = "Apartment A8"
            page5.priceLabel.text = "N$ 588 000"
            page5.imageView.image = UIImage(named: "apartment_a8_1")
            
            let page6: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page6.colorLabel.text = "Apartment A9"
            page6.priceLabel.text = "N$ 775 000"
            page6.imageView.image = UIImage(named: "apartment_a9a1")
            
            let page7: View = Bundle.main.loadNibNamed("View", owner: self, options: nil)?.first as! View
            page7.colorLabel.text = "Apartment A12"
            page7.priceLabel.text = "N$ 775 000"
            page7.imageView.image = UIImage(named: "apartment_a12_a")
            
            
            return [page1, page2, page3, page4, page5, page6, page7]
        }
    }

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var pageControl: UIPageControl!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setupScrollView(pages: pages)
        
        pageControl.numberOfPages = pages.count
        pageControl.currentPage = 0
    }
    
    var scrollViewWidth: CGFloat = 0

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        // we only want to call this once
        if scrollViewWidth != scrollView.frame.width {
            scrollViewWidth = scrollView.frame.width
            scrollView.contentOffset.x = scrollView.frame.width
        }
    }

    func setupScrollView(pages: [View]) {
        
        let stack = UIStackView()
        stack.translatesAutoresizingMaskIntoConstraints = false
        
        let clg = scrollView.contentLayoutGuide
        let flg = scrollView.frameLayoutGuide
        
        scrollView.addSubview(stack)
        NSLayoutConstraint.activate([
            // constrain all 4 sides of stack view to scroll view's Content Layout Guide
            stack.topAnchor.constraint(equalTo: clg.topAnchor),
            stack.leadingAnchor.constraint(equalTo: clg.leadingAnchor),
            stack.trailingAnchor.constraint(equalTo: clg.trailingAnchor),
            stack.bottomAnchor.constraint(equalTo: clg.bottomAnchor),
            
            // constrain height of stack view to scroll view's Frame Layout Guide
            stack.heightAnchor.constraint(equalTo: flg.heightAnchor),
        ])
        
        for i in 0 ..< pages.count {
            // add each page to the stack view
            stack.addArrangedSubview(pages[i])
            // make each page the same width as the scroll view's Frame Layout Guide width
            pages[i].widthAnchor.constraint(equalTo: flg.widthAnchor).isActive = true
        }
        
        scrollView.isPagingEnabled = true
        scrollView.delegate = self

    }
    
    @IBAction func pageControlChanged(_ sender: UIPageControl) {
        UIView.animate(withDuration: 0.3, animations: {
            self.scrollView.contentOffset.x = CGFloat(sender.currentPage) * self.scrollView.frame.width
        })
    }
}
extension ViewController: UIScrollViewDelegate {
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let pageIndex = round(scrollView.contentOffset.x / scrollView.frame.width)
        pageControl.currentPage = Int(pageIndex)
    }
}

Edit - response to comment...编辑- 回复评论...

If you have buttons to "go to a page" you can implement a function like this:如果您有“转到页面”的按钮,则可以实现如下功能:

func showPage(_ pg: Int) {
    UIView.animate(withDuration: 0.3, animations: {
        self.scrollView.contentOffset.x = CGFloat(pg - 1) * self.scrollView.frame.width
    })
}

and call it with, for example:并调用它,例如:

showPage(5)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM