Подтвердить что ты не робот

Добавить прокручиваемую кнопку для прокрутки

Я хочу прокрутить пять кнопок внутри прокрутки. Когда пользователь перестает перетаскивать кнопку, он должен перейти к следующей кнопке. Что я здесь делаю неправильно?

class ViewController: UIViewController {

    @IBOutlet weak var categoryScrollView: UIScrollView!
    var categoryArr = ["Jack","Mark","Down","Bill","Steve"]

    override func viewDidLoad() {
        super.viewDidLoad()
        let scrollingView = colorButtonsView(CGSizeMake(150,categoryScrollView.frame.size.height), buttonCount: 5)
        categoryScrollView.contentSize = scrollingView.frame.size
        categoryScrollView.addSubview(scrollingView)
        categoryScrollView.showsVerticalScrollIndicator = false
        categoryScrollView.delegate = self
        categoryScrollView.pagingEnabled = true
        categoryScrollView.indicatorStyle = .Default
    }


func colorButtonsView(buttonSize:CGSize, buttonCount:Int) -> UIView {
        let buttonView = UIView()
        buttonView.frame.origin = CGPointMake(0,0)
        let padding = CGSizeMake(10, 10)
        buttonView.frame.size.width = (buttonSize.width + padding.width) * CGFloat(buttonCount)
        var buttonPosition = CGPointMake(padding.width * 0.5, padding.height)
        let buttonIncrement = buttonSize.width + padding.width
        for i in 0...(buttonCount - 1)  {
            var button = UIButton.buttonWithType(.Custom) as! UIButton
            button.frame.size = buttonSize
            button.frame.origin = buttonPosition
            buttonPosition.x = buttonPosition.x + buttonIncrement
            button.setTitle(categoryArr[i], forState: UIControlState.Normal)
            buttonView.addSubview(button)
        }
        return buttonView
    }
}
extension ViewController:UIScrollViewDelegate{
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

        let index = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        print(index)
    }
}

Прокрутка прокрутки хорошо... но только дважды. Не прокручивается до следующей кнопки. Что мне делать?

4b9b3361

Ответ 1

func setContentOffset(scrollView: UIScrollView) {

    let numOfItems = itemCount  // 5
    let stopOver = scrollView.contentSize.width / CGFloat(numOfItems)
    let x = round(scrollView.contentOffset.x / stopOver) * stopOver

    guard x >= 0 && x <= scrollView.contentSize.width - scrollView.frame.width else {
        return
    }

    scrollView.setContentOffset(CGPointMake(x, scrollView.contentOffset.y), animated: true)
}

extension ViewController: UIScrollViewDelegate {

    func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {

        setContentOffset(scrollView)
    }

    func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {

        guard !decelerate else {
            return
        }

        setContentOffset(scrollView)
    }
}

Также сделал демонстрационный проект в Github
https://github.com/rishi420/ScrollViewCustomPaging


Обновление:

Попытка рассмотреть скорость прокрутки, когда пользователь заканчивает работу.

var velocityX = CGFloat(0.0) 

.

func setContentOffset(scrollView: UIScrollView) {

    let numOfItems = itemCount
    let stopOver = scrollView.contentSize.width / CGFloat(numOfItems)
    var x = round((scrollView.contentOffset.x + (velocityX * 150)) / stopOver) * stopOver // 150 is for test. Change it for your liking

    x = max(0, min(x, scrollView.contentSize.width - scrollView.frame.width))

    scrollView.setContentOffset(CGPointMake(x, scrollView.contentOffset.y), animated: true)
}

.

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
    velocityX = velocity.x
}

Ответ 2

Пробовали ли вы использовать UITableView вместо UIScrollView и делаете размер tableview равным размеру кнопки, которую вы хотите. Затем добавьте кнопку в свою ячейку. Включите UITableView "Пейджинг"

Это поможет вам лучше управлять контентом, то есть удобнее, поскольку вы можете передать массив кнопок в tableview и управлять его методом cellForAtIndex.

Ответ 3

После вычисления индекса кнопки в вашем методе scrollViewDidEndDecelerating() просто вызовите scrollRectToVisible(rect, animated:) с кадром кнопки в этом индексе.

Ответ 4

UIScrollView не всегда замедляется. Вы можете использовать подход из этого ответа: fooobar.com/questions/168726/... или использовать метод targetContentOffset из scrollViewWillEndDragging:withVelocity:targetContentOffset:.

Ответ 5

Пожалуйста, проверьте этот измененный код:

class ViewController: UIViewController {

@IBOutlet weak var categoryScrollView: UIScrollView!
var categoryArr = ["Jack","Mark","Down","Bill","Steve"]

override func viewDidLoad() {
    super.viewDidLoad()
    let scrollingView = colorButtonsView(CGSizeMake(categoryScrollView.frame.size.width / 3 ,categoryScrollView.frame.size.height), buttonCount: 5)
    categoryScrollView.contentSize = scrollingView.frame.size
    categoryScrollView.addSubview(scrollingView)
    categoryScrollView.showsVerticalScrollIndicator = false
    categoryScrollView.delegate = self
    categoryScrollView.pagingEnabled = false
    categoryScrollView.bounces = false
    categoryScrollView.indicatorStyle = .Default
}


func colorButtonsView(buttonSize:CGSize, buttonCount:Int) -> UIView {
    let buttonView = UIView()
    buttonView.frame.origin = CGPointMake(0,0)
    let padding = CGSizeMake(10, 10)
    buttonView.frame.size.width = (buttonSize.width + padding.width) * CGFloat(buttonCount)
    var buttonPosition = CGPointMake(padding.width * 0.5, padding.height)
    let buttonIncrement = buttonSize.width + padding.width
    for i in 0...(buttonCount - 1)  {
        let button = UIButton(type: .Custom)
        button.backgroundColor = UIColor.redColor()
        button.frame.size = buttonSize
        button.frame.origin = buttonPosition
        buttonPosition.x = buttonPosition.x + buttonIncrement
        button.setTitle(categoryArr[i], forState: UIControlState.Normal)
        buttonView.addSubview(button)
    }
    return buttonView
}

}

extension ViewController:UIScrollViewDelegate{

    func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
        let buttonWidth = scrollView.frame.size.width / 3
        let index = round(scrollView.contentOffset.x / buttonWidth)
        targetContentOffset.memory.x = index*buttonWidth + index*10
    }

}

Ответ 6

Тонко настроенный код Aruna. Установите некоторые цвета фона для легкой отладки, чтобы увидеть, что ожидаемое поведение получено.

class ViewController: UIViewController {

    @IBOutlet weak var categoryScrollView: UIScrollView!
    var categoryArr = ["Jack","Mark","Down","Bill","Steve"]
    var buttonColors = [UIColor.greenColor(), UIColor.blueColor(), UIColor.blackColor(), UIColor.cyanColor(), UIColor.magentaColor()]
    let kPadding:CGFloat = 10

    override func viewDidLoad() {
        super.viewDidLoad()

        let buttonSize = CGSizeMake(categoryScrollView.bounds.size.width/2, categoryScrollView.bounds.size.height/2)//hal

        let scrollingView = colorButtonsView(buttonSize, buttonCount: 5)
        categoryScrollView.contentSize = scrollingView.frame.size
        categoryScrollView.addSubview(scrollingView)
        categoryScrollView.showsVerticalScrollIndicator = false
        categoryScrollView.delegate = self
        categoryScrollView.pagingEnabled = true
        categoryScrollView.indicatorStyle = .Default
        categoryScrollView.contentOffset = CGPointMake(0, 0)
    }


    func colorButtonsView(buttonSize:CGSize, buttonCount:Int) -> UIView {
        let buttonView = UIView()
        buttonView.frame.origin = CGPointMake(0,0)
        let padding = CGSizeMake(kPadding, kPadding)
        buttonView.frame.size.width = (buttonSize.width + padding.width) * CGFloat(buttonCount)
        var buttonPosition = CGPointMake(0, padding.height)
        let buttonIncrement = buttonSize.width + padding.width
        for i in 0...(buttonCount - 1)  {
            let button = UIButton(type: .Custom)
            button.frame.size = buttonSize
            button.frame.origin = buttonPosition
            buttonPosition.x = buttonPosition.x + buttonIncrement
            button.setTitle(categoryArr[i], forState: UIControlState.Normal)
            button.backgroundColor = buttonColors[i]
            buttonView.addSubview(button)
        }
        buttonView.backgroundColor = UIColor.redColor()
        return buttonView
    }
}
extension ViewController:UIScrollViewDelegate{
    func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

        let index = round(scrollView.contentOffset.x / scrollView.frame.size.width)
        print(index)
    }
}