Добавить прокручиваемую кнопку для прокрутки
Я хочу прокрутить пять кнопок внутри прокрутки. Когда пользователь перестает перетаскивать кнопку, он должен перейти к следующей кнопке. Что я здесь делаю неправильно?
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)
}
}
Прокрутка прокрутки хорошо... но только дважды. Не прокручивается до следующей кнопки. Что мне делать?
Ответы
Ответ 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)
}
}