将可滚动button添加到滚动视图

我想滚动滚动视图中的五个button。 当用户停止拖动一个button,它应该移动到下一个button。 我在这里做错了什么?

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) } } 

scrollview很好的滚动..但只有两次。 它不滚动到下一个button。 我该怎么办?

 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


更新:

尝试考虑用户endDragging时的滚动速度。

 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 } 

您是否尝试过使用UITableView而不是UIScrollView,并使tableview的大小等于所需button的大小。 然后将button添加到其单元格。 启用UITableView的“分页”

这将帮助你更好地pipe理内容,例如button,因为你可以将button数组传递给tableview,并在cellForAtIndex方法中进行pipe理。

在计算scrollViewDidEndDecelerating()方法中的button索引之后,只需scrollRectToVisible(rect, animated:)该索引处button的框架调用scrollRectToVisible(rect, animated:)即可。

UIScrollView并不总是减速。 您可以使用这个答案的方法: https scrollViewWillEndDragging:withVelocity:targetContentOffset: ,或从scrollViewWillEndDragging:withVelocity:targetContentOffset:方法使用targetContentOffset

微调了一下Aruna的代码。 设置一些背景颜色以便于debugging,以查看预期的行为。

 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) } } 

请检查这个修改后的代码:

 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 } }