Swift SKSpritenodes in a UIScrollView -
okay i'm trying add skspritenode
uiscrollview
, how can that?
what have tried far?. general stack overflow rule should post code if expect help.
i recommend latest version of code github project incase made changes since answer, link @ bottom.
step 1: create new swift file , paste in code
import spritekit /// scroll direction enum scrolldirection { case vertical // cases start small letters following swift 3 guildlines. case horizontal } class customscrollview: uiscrollview { // mark: - static properties /// touches allowed static var disabledtouches = false /// scroll view private static var scrollview: uiscrollview! // mark: - properties /// current scene private let currentscene: skscene /// moveable node private let moveablenode: sknode /// scroll direction private let scrolldirection: scrolldirection /// touched nodes private var nodestouched = [anyobject]() // mark: - init init(frame: cgrect, scene: skscene, moveablenode: sknode) { 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?) { 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 touched nodes in current scene nodestouched = currentscene.nodesatpoint(location) node in nodestouched { node.touchesbegan(touches, withevent: event) } } } /// moved override func touchesmoved(touches: set<uitouch>, withevent event: uievent?) { 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 touched nodes in current scene nodestouched = currentscene.nodesatpoint(location) node in nodestouched { node.touchesmoved(touches, withevent: event) } } } /// ended override func touchesended(touches: set<uitouch>, withevent event: uievent?) { 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 touched nodes in current scene nodestouched = currentscene.nodesatpoint(location) node in nodestouched { node.touchesended(touches, withevent: event) } } } /// cancelled override func touchescancelled(touches: set<uitouch>?, withevent event: uievent?) { 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 touched nodes in current scene nodestouched = currentscene.nodesatpoint(location) 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 } } }
this make subclass of uiscrollview , sets basic properties of it. has own touches method passed along relevant scene.
step2: in relevant scene want use create scroll view , moveable node property so
weak var scrollview: customscrollview! let moveablenode = sknode()
and add them scene in didmovetoview
scrollview = customscrollview(frame: cgrect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height), scene: self, moveablenode: moveablenode, scrolldirection: .vertical) scrollview.contentsize = cgsizemake(self.frame.size.width, self.frame.size.height * 2) view?.addsubview(scrollview) addchild(moveablenode)
what here in line 1 init scroll view helper scene dimensions. pass along scene reference , moveablenode created @ step 2. line 2 set content size of scrollview, in case twice long screen height.
step3: - add labels or nodes etc , position them.
label1.position.y = cgrectgetmidy(self.frame) - self.frame.size.height moveablenode.addchild(label1)
in example label on 2nd page in scrollview. have play around labels , positioning.
i recommend if have lot pages in scroll view , lot of labels following. create skspritenode each page in scroll view , make each of them size of screen. call them page1node, page2node etc. add labels want example on second page page2node. benefit here can position stuff usual within page2node , position page2node in scrollview.
you in luck because using scrollview vertically (which u said want) dont need flipping , reverse positioning.
i made class func if need disable scrollview incase overlay menu ontop of scrollview.
customscrollview.enable() customscrollview.disable()
and not forget remove scroll view scene before transitioning new one. 1 of pains when dealing uikit in spritekit.
scrollview?.removefromsuperview()
Comments
Post a Comment