滚动查看在某个点停止

嗨,我目前有一个水平的UIScrollView ,允许我在我的游戏中select一个字符,然后select它,但现在我有的问题是我试图让scrollview停止在精灵/字符在中间点屏幕,而不是让它停在任何地方。

我的UIScrollView有一个“可移动的节点”,其中包含多个页面,其中包含所有的精灵,如下所示:

  scrollViewHorizontal = CustomScrollView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveableNode: moveableNodeHorizontal, scrollDirection: .Horizontal) scrollViewHorizontal.contentSize = CGSizeMake(self.frame.size.width * 4, self.frame.size.height) // * 4 makes it three times as wide as screen view?.addSubview(scrollViewHorizontal) scrollViewHorizontal.hidden = true addChild(moveableNodeHorizontal) moveableNodeHorizontal.hidden = true moveableNodeHorizontal.zPosition = 100000 scrollViewHorizontal.setContentOffset(CGPoint(x: 0 + self.frame.size.width + self.frame.size.width * 2, y: 0), animated: false) let page1ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(scrollViewHorizontal.frame.size.width, scrollViewHorizontal.frame.size.height)) page1ScrollView.zPosition = -1 page1ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width * 3.5), CGRectGetMidY(self.frame) - (self.frame.height / 2)) moveableNodeHorizontal.addChild(page1ScrollView) let page2ScrollView = SKSpriteNode(color: SKColor.clearColor(), size: CGSizeMake(scrollViewHorizontal.frame.size.width, scrollViewHorizontal.frame.size.height)) page2ScrollView.zPosition = -1 page2ScrollView.position = CGPointMake(CGRectGetMidX(self.frame) - (self.frame.size.width * 2.5), CGRectGetMidY(self.frame) - (self.frame.height / 2)) moveableNodeHorizontal.addChild(page2ScrollView) Characters.append(generateCharacters(CGPointMake(0, 0), page:(page1ScrollView), tex: "YellowFrog")) Characters.append(generateCharacters(CGPointMake(100, 0), page:(page1ScrollView), tex: "Frog")) Characters.append(generateCharacters(CGPointMake(0, 0), page:(page2ScrollView), tex: "ball")) Characters.append(generateCharacters(CGPointMake(100, 0), page:(page2ScrollView), tex: "ball")) 

我之前search过这个问题,并build议我使用这个:

  func scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { 

但我不知道如何将其实现到我的代码,因为我的滚动视图包含在另一个类,可以在这里看到:

 /// Nodes touched var nodesTouched: [AnyObject] = [] // global /// Scroll direction enum ScrollDirection: Int { case None = 0 case Vertical case Horizontal } /// Custom UIScrollView class class CustomScrollView: UIScrollView { // MARK: - Static Properties /// Touches allowed static var disabledTouches = false /// Scroll view private static var scrollView: UIScrollView! // MARK: - Properties /// Nodes touched. This will forward touches to node subclasses. private var nodesTouched = [AnyObject]() /// Current scene private let currentScene: SKScene /// Moveable node private let moveableNode: SKNode /// Scroll direction private let scrollDirection: ScrollDirection // MARK: - Init init(frame: CGRect, scene: SKScene, moveableNode: SKNode, scrollDirection: ScrollDirection) { self.currentScene = scene self.moveableNode = moveableNode self.scrollDirection = scrollDirection super.init(frame: frame) CustomScrollView.scrollView = self self.frame = frame delegate = self indicatorStyle = .White scrollEnabled = true userInteractionEnabled = true //canCancelContentTouches = false //self.minimumZoomScale = 1 //self.maximumZoomScale = 3 if scrollDirection == .Horizontal { let flip = CGAffineTransformMakeScale(-1,-1) transform = flip } } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } // MARK: - Touches extension CustomScrollView { /// Began override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { //super.touchesBegan(touches, withEvent: event) for touch in touches { let location = touch.locationInNode(currentScene) guard !CustomScrollView.disabledTouches else { return } /// Call touches began in current scene currentScene.touchesBegan(touches, withEvent: event) /// Call touches began in all touched nodes in the current scene nodesTouched = currentScene.nodesAtPoint(location) for node in nodesTouched { node.touchesBegan(touches, withEvent: event) } } } /// Moved override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { //super.touchesMoved(touches, withEvent: event) for touch in touches { let location = touch.locationInNode(currentScene) guard !CustomScrollView.disabledTouches else { return } /// Call touches moved in current scene currentScene.touchesMoved(touches, withEvent: event) /// Call touches moved in all touched nodes in the current scene nodesTouched = currentScene.nodesAtPoint(location) for node in nodesTouched { node.touchesMoved(touches, withEvent: event) } } } /// Ended override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { //super.touchesEnded(touches, withEvent: event) for touch in touches { let location = touch.locationInNode(currentScene) guard !CustomScrollView.disabledTouches else { return } /// Call touches ended in current scene currentScene.touchesEnded(touches, withEvent: event) /// Call touches ended in all touched nodes in the current scene nodesTouched = currentScene.nodesAtPoint(location) for node in nodesTouched { node.touchesEnded(touches, withEvent: event) } } } /// Cancelled override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) { //super.touchesCancelled(touches, withEvent: event) for touch in touches! { let location = touch.locationInNode(currentScene) guard !CustomScrollView.disabledTouches else { return } /// Call touches cancelled in current scene currentScene.touchesCancelled(touches, withEvent: event) /// Call touches cancelled in all touched nodes in the current scene nodesTouched = currentScene.nodesAtPoint(location) for node in nodesTouched { node.touchesCancelled(touches, withEvent: event) } } } } // MARK: - Touch Controls extension CustomScrollView { /// Disable class func disable() { CustomScrollView.scrollView?.userInteractionEnabled = false CustomScrollView.disabledTouches = true } /// Enable class func enable() { CustomScrollView.scrollView?.userInteractionEnabled = true CustomScrollView.disabledTouches = false } } // MARK: - Delegates extension CustomScrollView: UIScrollViewDelegate { func scrollViewDidScroll(scrollView: UIScrollView) { if scrollDirection == .Horizontal { moveableNode.position.x = scrollView.contentOffset.x } else { moveableNode.position.y = scrollView.contentOffset.y } } } 

编辑:

 extension CustomScrollView: UIScrollViewDelegate { func scrollViewDidScroll(scrollView: UIScrollView) { if scrollDirection == .Horizontal { moveableNode.position.x = scrollView.contentOffset.x } else { moveableNode.position.y = scrollView.contentOffset.y } } } 

CustomScrollView是一个项目,展示了如何在sprite-kit使用UIKit ,但是在渲染过程中会导致很多工作,从而降低游戏速度(由于fps太低),因此build议仅将它用于游戏菜单,游戏。

一种iOS8.x的方法:

你可以build立例如很多SKSpriteNode背景,跟在另一个之后,在你的update方法中:

 override func update(currentTime: CFTimeInterval) { self.enumerateChildNodesWithName("background") { node, _ in if node is SKSpriteNode { if let p = (node as! SKShapeNode).position { // adjust your background positions to make the scroll } } } } 

一种iOS9x的方法:

Apple在iOS 9中将SKCameraNode类添加到sprite-kit中,以便更容易地滚动和放大sprite-kit场景。

 var gameCamera = SKCameraNode() override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { for touch in touches { let location = touch.locationInNode(self) let previousLocation = touch.previousLocationInNode(self) let deltaX = location.x - previousLocation.x gameCamera.position.x += deltaX } } 

CustomScrollView页面select器

话虽如此,我们来到你的情况,假设你有你所有的页面在数组中称为pages ,你想停止滚动到X页面:

 func scrollToPage(page:Int) { let totalPages : Int = (pages.count - 1) let reversedPage : Int = totalPages - page self.scrollView.setContentOffset(CGPointMake(round(self.frame.size.width*CGFloat(reversedPage)), scrollView.contentOffset.y),animated: true) } 

另一个好主意是拦截滚动委托方法来更新元素:

 func scrollViewDidScroll(scrollView: UIScrollView) { self.scrollView.scrollViewDidScroll(scrollView) updateLayout() // call my method to update elements in scroll checking the current page } 

你可以获得你的页码白色这个代码:

 extension UIScrollView { var currentPage: Int { return abs(Int(round((contentSize.width - self.contentOffset.x) / self.bounds.size.width))-1) } }