在Swift 4.0中阻止UIScrollView上的垂直滚动问题

Chi*_*dog 7 xcode uiscrollview swift

我在我的应用程序中有一个Image carousel我使用UIScrollView来显示里面的图像.一切正常,只是我想知道如何阻止UIScrollView中的移动

我试图阻止垂直滚动:

scrollView.showsVerticalScrollIndicator = false
scrollView.contentSize  = CGSize(width: scrollView.contentSize.width, height: 0) //disable vertical
Run Code Online (Sandbox Code Playgroud)

一切都很好,它真的阻止了垂直滚动

问题是,我还有一个计时器,它UIScrollView通过以下方式以编程方式移动:

var frame: CGRect = scrollView.frame
frame.origin.x = frame.size.width * CGFloat(pageToMove)
frame.origin.y = -35
scrollView.scrollRectToVisible(frame, animated: true)
Run Code Online (Sandbox Code Playgroud)

并且一旦我阻止垂直滚动,这个功能scrollReactToVisible就不会做任何事情.我没有得到任何错误.

有没有一种方法可以垂直阻止滚动(并允许像往常一样左右滚动),并以编程方式移动滚动视图?

我正在附加我的全视图控制器:

class CaruselleScreenViewController: UIViewController, CaruselleScreenViewProtocol, UIScrollViewDelegate {

    var myPresenter: CaruselleScreenPresenterProtocol?

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

    var slides:[CaruselleTipsCard] = [];

    var timer:Timer?
    var currentPageMultiplayer = 0

    override func viewDidLoad() {
        super.viewDidLoad()

        myPresenter = CaruselleScreenPresenter(controller: self)

        //initlizes view
        pageControl.numberOfPages = slides.count
        pageControl.currentPage = 0
        view.bringSubview(toFront: pageControl)

        //delegates
        scrollView.delegate = self

        ////blocks vertical movement
        scrollView.showsVerticalScrollIndicator = false
        //scrollView.contentSize  = CGSize(width: scrollView.contentSize.width, height: 0) //disable vertical
    }

    func scheduleTimer(_ timeInterval: TimeInterval){
        timer = Timer.scheduledTimer(timeInterval: timeInterval, target: self, selector: #selector(timerCall), userInfo: nil, repeats: false)
    }

    @objc func timerCall(){
        print("Timer executed")

        currentPageMultiplayer = currentPageMultiplayer + 1

        if (currentPageMultiplayer == 5) {
            currentPageMultiplayer = 0
        }
        pageControl.currentPage = currentPageMultiplayer
        scrollToPage(pageToMove: currentPageMultiplayer)

        scheduleTimer(5)
    }

    func scrollToPage(pageToMove: Int) {
        print ("new one")
        var frame: CGRect = scrollView.frame
        frame.origin.x = frame.size.width * CGFloat(pageToMove)
        frame.origin.y = -35
        scrollView.scrollRectToVisible(frame, animated: true)
    }

    func createSlides() -> [CaruselleTipsCard] {

        let slide1:CaruselleTipsCard = Bundle.main.loadNibNamed("CaruselleTipsCard", owner: self, options: nil)?.first as! CaruselleTipsCard
        slide1.mainPic.image = UIImage(named: "backlightingIllo")

        //
        let slide2:CaruselleTipsCard = Bundle.main.loadNibNamed("CaruselleTipsCard", owner: self, options: nil)?.first as! CaruselleTipsCard
        slide2.mainPic.image = UIImage(named: "comfortableIllo")

        //
        let slide3:CaruselleTipsCard = Bundle.main.loadNibNamed("CaruselleTipsCard", owner: self, options: nil)?.first as! CaruselleTipsCard
        slide3.mainPic.image = UIImage(named: "pharmacyIllo")

        //
        let slide4:CaruselleTipsCard = Bundle.main.loadNibNamed("CaruselleTipsCard", owner: self, options: nil)?.first as! CaruselleTipsCard
        slide4.mainPic.image = UIImage(named: "batteryIllo")

        //
        let slide5:CaruselleTipsCard = Bundle.main.loadNibNamed("CaruselleTipsCard", owner: self, options: nil)?.first as! CaruselleTipsCard
        slide5.mainPic.image = UIImage(named: "wiFiIllo")

        return [slide1, slide2, slide3, slide4, slide5]
    }

    func setupSlideScrollView(slides : [CaruselleTipsCard]) {
        scrollView.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height)
        scrollView.contentSize = CGSize(width: view.frame.width * CGFloat(slides.count), height: view.frame.height)
        scrollView.isPagingEnabled = true

        for i in 0 ..< slides.count {
            slides[i].frame = CGRect(x: view.frame.width * CGFloat(i), y: 0, width: view.frame.width, height: view.frame.height)
            scrollView.addSubview(slides[i])
        }
    }


    //////

    /*
     * default function called when view is scrolled. In order to enable callback
     * when scrollview is scrolled, the below code needs to be called:
     * slideScrollView.delegate = self or
     */
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        let pageIndex = round(scrollView.contentOffset.x/view.frame.width)
        pageControl.currentPage = Int(pageIndex)

        let maximumHorizontalOffset: CGFloat = scrollView.contentSize.width - scrollView.frame.width
        let currentHorizontalOffset: CGFloat = scrollView.contentOffset.x

        // vertical
        let maximumVerticalOffset: CGFloat = scrollView.contentSize.height - scrollView.frame.height
        let currentVerticalOffset: CGFloat = scrollView.contentOffset.y

        let percentageHorizontalOffset: CGFloat = currentHorizontalOffset / maximumHorizontalOffset
        let percentageVerticalOffset: CGFloat = currentVerticalOffset / maximumVerticalOffset


        /*
         * below code changes the background color of view on paging the scrollview
         */
        //        self.scrollView(scrollView, didScrollToPercentageOffset: percentageHorizontalOffset)


        /*
         * below code scales the imageview on paging the scrollview
         */
        let percentOffset: CGPoint = CGPoint(x: percentageHorizontalOffset, y: percentageVerticalOffset)

        if(percentOffset.x > 0 && percentOffset.x <= 0.25) {

            slides[0].mainPic.transform = CGAffineTransform(scaleX: (0.25-percentOffset.x)/0.25, y: (0.25-percentOffset.x)/0.25)
            slides[1].mainPic.transform = CGAffineTransform(scaleX: percentOffset.x/0.25, y: percentOffset.x/0.25)

        } else if(percentOffset.x > 0.25 && percentOffset.x <= 0.50) {
            slides[1].mainPic.transform = CGAffineTransform(scaleX: (0.50-percentOffset.x)/0.25, y: (0.50-percentOffset.x)/0.25)
            slides[2].mainPic.transform = CGAffineTransform(scaleX: percentOffset.x/0.50, y: percentOffset.x/0.50)

        } else if(percentOffset.x > 0.50 && percentOffset.x <= 0.75) {
            slides[2].mainPic.transform = CGAffineTransform(scaleX: (0.75-percentOffset.x)/0.25, y: (0.75-percentOffset.x)/0.25)
            slides[3].mainPic.transform = CGAffineTransform(scaleX: percentOffset.x/0.75, y: percentOffset.x/0.75)

        } else if(percentOffset.x > 0.75 && percentOffset.x <= 1) {
            slides[3].mainPic.transform = CGAffineTransform(scaleX: (1-percentOffset.x)/0.25, y: (1-percentOffset.x)/0.25)
            slides[4].mainPic.transform = CGAffineTransform(scaleX: percentOffset.x, y: percentOffset.x)
        }
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "findingClinitionSugue" {
            let destination = segue.destination as! FirstAvailableSearchViewController
            //destination.consumer = consumer
        }

        if (timer != nil) {
            timer?.invalidate()
        }
    }

    // protocol functions

    func initlizeSlides() {
        slides = createSlides()
        setupSlideScrollView(slides: slides)
    }

    func initlizeTimer() {
        scheduleTimer(5)
    }
}
Run Code Online (Sandbox Code Playgroud)

emr*_*pun 0

问题可能在于最初将 contentSize 高度值设置为 0,因此即使计时器希望滚动视图移动,它也无法做到这一点。

您可以尝试替换这一行:

scrollView.contentSize = CGSize(width: scrollView.contentSize.width, height: 0)
Run Code Online (Sandbox Code Playgroud)

和:

scrollView.contentInsetAdjustmentBehavior = .never
Run Code Online (Sandbox Code Playgroud)