SwiftySKScrollView 2.5.0

SwiftySKScrollView 2.5.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布日期上次发布2022年5月
SPM支持 SPM

Dominik Ringler 维护。



  • Dominik Ringler

SwiftySKScrollView

Swift 5.0 Platform CocoaPods Compatible

一个辅助类,用于将 UIScrollView 添加到您的 SpriteKit 场景中。

辅助类将自动将按钮点击事件转发到相关的 SKScene 和节点子类。

请阅读

通常,将 UIKit 元素添加到 SpriteKit 游戏中并不是一个好的实践,您应该使用 SpriteKit API(SKSpriteNodes、SKLabelNodes、SKNodes 等)在相关的 SKScene 中直接完成所有 UI 制作。然而,UIKit 中有几个东西,特别是 UIScrollViews 和 UICollectionViews,使用 SpriteKit API 想要复现会比较困难。

这是一个较老的项目,实际上我已经不再在我的应用程序中使用它,因为它不是在世界上实现可滚动列表的最优雅的解决方案。它仅应用于非常小的内容,例如角色选择菜单。

由于单元格的重用和效率,使用 UICollectionView 来实现可滚动列表要更好。您可以用与这个辅助类类似的方式来创建 UICollectionViews 的子类。

我将无限期地维护这个仓库。

需求

  • iOS 10.3+
  • Swift 5.0+

安装

Cocoa Pods

CocoaPods是一个用于Cocoa项目的依赖管理器。只需将以下行添加到您的Podfile中即可安装pod:

pod 'SwiftySKScrollView'

现在有一个app,它使处理pod变得更容易

或者,您也可以手动将swift文件拖入您的项目。

Swift Package Manager

Swift Package Manager是一个用于自动分发Swift代码的工具,它集成到Swift编译器中。

要将swift包添加到您的项目中,只需在XCode中打开项目,然后点击File > Swift Packages > Add Package Dependency。然后输入https://github.com/crashoverride777/swifty-sk-scroll-view作为存储库URL,并完成设置向导。

或者,如果您有一个需要在Package.swift的依赖项值中添加SwiftySKScrollView的框架,只需将其添加到依赖项值中即可。

dependencies: [
.package(url: "https://github.com/crashoverride777/swifty-sk-scroll-view.git", from: "2.4.0")
]

手动安装

将SwiftySKScrollView.swift文件添加到您的项目中

使用说明

  • 当使用CocoaPods或SwiftPackageManager时,请添加导入语句
import SwiftySKScrollView 
  • 在您想使用它的相关SKScene中,创建这两个属性
class MenuScene: SKScene {
    var scrollView: SwiftySKScrollView?
    let moveableNode = SKNode()
    ...
}
  • 设置上述步骤中的属性。

在didMoveToView中添加可移动节点

addChild(moveableNode)

并设置scrollView

垂直滚动

scrollView = SwiftySKScrollView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height), moveableNode: moveableNode, direction: .vertical)
scrollView?.contentSize = CGSize(width: scrollView!.frame.width, height: scrollView!.frame.height * 3) // makes it 3 times the height
view?.addSubview(scrollView!)

水平滚动

scrollView = SwiftySKScrollView(frame: CGRect(x: 0, y: 0, width: size.width, height: size.height), moveableNode: moveableNode, direction: .horizontal)
scrollView?.contentSize = CGSize(width: scrollView!.frame.width * 3, height: scrollView!.frame.height) // * 3 makes it three times as wide
view?.addSubview(scrollView!)
scrollView?.setContentOffset(CGPoint(x: 0 + scrollView!.frame.width * 2, y: 0), animated: true)

第1行初始化辅助工具,传入场景尺寸。同时传入在第2步创建的可移动节点和你想要的滚动方向。

第2行设置scrollView的内容大小。

第3行添加scrollView。

第4行(水平)重置内容偏移量,以便从左到右开始(UIKit坐标与SpriteKits不同)。

  • 为scrollView中的每一页添加精灵以使后续定位实际内容更容易。

垂直滚动

guard let scrollView = scrollView else { return } // unwrap  optional 

let page1ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page1ScrollView.position = CGPoint(x: frame.midX, y: frame.midY)
moveableNode.addChild(page1ScrollView)
        
let page2ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page2ScrollView.position = CGPoint(x: frame.midX, y: frame.midY - scrollView.frame.height)
moveableNode.addChild(page2ScrollView)
        
let page3ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page3ScrollView.position = CGPoint(x: frame.midX, y: frame.midY - (scrollView.frame.height * 2))
moveableNode.addChild(page3ScrollView)

水平滚动(定位方向相反)

guard let scrollView = scrollView else { return } // unwrap  optional 

let page1ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page1ScrollView.position = CGPoint(x: frame.midX - (scrollView.frame.width * 2), y: frame.midY)
moveableNode.addChild(page1ScrollView)
        
let page2ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page2ScrollView.position = CGPoint(x: frame.midX - (scrollView.frame.width), y: frame.midY)
moveableNode.addChild(page2ScrollView)
        
let page3ScrollView = SKSpriteNode(color: .clear, size: CGSize(width: scrollView.frame.width, height: scrollView.frame.size.height))
page3ScrollView.zPosition = -1
page3ScrollView.position = CGPoint(x: frame.midX, y: frame.midY)
moveableNode.addChild(page3ScrollView)
  • 添加精灵、标签等。因为你将它们添加到上面的精灵中,所以可以像平常一样定位它们,这就是为什么先做第4步会更简单。

垂直滚动

/// Test sprites page 1
let sprite1Page1 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page1.position = CGPoint(x: 0, y: 0)
page1ScrollView.addChild(sprite1Page1)
        
let sprite2Page1 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page1.position = CGPoint(x: sprite1Page1.position.x, y: sprite1Page1.position.y - sprite2Page1.size.height * 1.5)
sprite1Page1.addChild(sprite2Page1)
        
/// Test sprites page 2
let sprite1Page2 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page2.position = CGPoint(x: 0, y: 0)
page2ScrollView.addChild(sprite1Page2)
        
let sprite2Page2 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page2.position = CGPoint(x: sprite1Page2.position.x, y: sprite1Page2.position.y - (sprite2Page2.size.height * 1.5))
sprite1Page2.addChild(sprite2Page2)
        
/// Test sprites page 3
let sprite1Page3 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page3.position = CGPoint(x: 0, y: 0)
page3ScrollView.addChild(sprite1Page3)
        
let sprite2Page3 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page3.position = CGPoint(x: sprite1Page3.position.x, y: sprite1Page3.position.y - (sprite2Page3.size.height * 1.5))
sprite1Page3.addChild(sprite2Page3)

水平

/// Test sprites page 1
let sprite1Page1 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page1.position = CGPoint(x: 0, y: 0)
page1ScrollView.addChild(sprite1Page1)
        
let sprite2Page1 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page1.position = CGPoint(x: sprite1Page1.position.x + (sprite2Page1.size.width * 1.5), y: sprite1Page1.position.y)
sprite1Page1.addChild(sprite2Page1)
        
/// Test sprites page 2
let sprite1Page2 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page2.position = CGPoint(x: 0, y: 0)
page2ScrollView.addChild(sprite1Page2)
        
let sprite2Page2 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page2.position = CGPoint(x: sprite1Page2.position.x + (sprite2Page2.size.width * 1.5), y: sprite1Page2.position.y)
sprite1Page2.addChild(sprite2Page2)
        
/// Test sprites page 3
let sprite1Page3 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite1Page3.position = CGPoint(x: 0, y: 0)
page3ScrollView.addChild(sprite1Page3)
        
let sprite2Page3 = SKSpriteNode(color: .red, size: CGSize(width: 50, height: 50))
sprite2Page3.position = CGPoint(x: sprite1Page3.position.x + (sprite2Page3.size.width * 1.5), y: sprite1Page3.position.y)
sprite1Page3.addChild(sprite2Page3)
  • 如果你需要禁用scrollView(例如在scrollView之上叠加另一个菜单或者按下按钮时),可以使用isDisabled布尔值。记住,UIKit元素被添加到你的GameViewController中而不是SKScenes中,所以你将不得不在此处进行调整,看看你的SpriteKit UI如何与scrollView交互。
scrollView?.isDisabled = true
  • 最后,在过渡到新场景之前,不要忘记从你的场景中移除滚动视图。正如上面提到的,这是SpriteKit中处理UIKit时的一大痛点。最佳做法是在WillMoveFromView中完成。
override func willMove(from view: SKView) {
    scrollView?.removeFromSuperview()
    scrollView = nil // nil out reference to deallocate properly
}