Scrollview在某个时刻停止

时间:2016-08-03 04:45:11

标签: ios swift uiscrollview sprite-kit

嗨我目前有一个水平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")) 有一个“可移动节点”,其中包含多个包含所有精灵的页面,如下所示:

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

但是我不知道如何在我的代码中实现它,因为我的scrollview包含在另一个类中,可以在这里看到:

extension CustomScrollView: UIScrollViewDelegate {

  func scrollViewDidScroll(scrollView: UIScrollView) {

    if scrollDirection == .Horizontal {
        moveableNode.position.x = scrollView.contentOffset.x
    } else {
        moveableNode.position.y = scrollView.contentOffset.y
    }
  }
}

修改

> xtabs(value~name+color, df)
      color
name   blue green red yellow
  Dave    6     7   4      8
  John    2     1   1      3
  Mark    5     3   5      2

1 个答案:

答案 0 :(得分:0)

CustomScrollView是一个项目,展示UIKit如何在sprite-kit中使用,但这会导致渲染过程中的大量工作会导致游戏速度变慢(由于fps较低),因此它会导致;建议合理地使用它只是为了你的游戏菜单而不是游戏。

iOS8.x的一种方式:

您可以构建例如许多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页面选择器

说过我们遇到你的情况,假设你的所有页面都在数组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)
    }
}