Fluidity
Fluidity

Reputation: 3995

Converting CGPoints between UIKit and SpriteKit woes: UIViews next to SKNodes

There are many posts on this but for whatever reason I can't seem to get the correct sequence of conversions correct. I'm trying to get the UISliders to go directly below the SKLabels.

As you can see in the pictures, one of the sliders doesn't show at all, and the other one is in the completely wrong place (the volume slider is near the seek label):

enter image description here

Here is my current attempt at getting this right, though I've tried a few other configurations that got me nowhere:

class GameScene: SKScene {

  let seekSlider = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))
  let volSlider  = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))

  override func didMove(to view: SKView) {
    removeAllChildren() // Delete this in your actual project.

    // Add some labels:
    let seekLabel = SKLabelNode(text: "Seek")
    seekLabel.setScale(3)
    seekLabel.verticalAlignmentMode = .center
    seekLabel.position = CGPoint(x: frame.minX + seekLabel.frame.width/2,
                                 y: frame.maxY - seekLabel.frame.height)

    let volLabel  = SKLabelNode(text: "Volume")
    volLabel.setScale(3)
    volLabel.verticalAlignmentMode = .center
    volLabel.position = CGPoint(x: frame.minX + volLabel.frame.width/2,
                                y: frame.minY + volLabel.frame.height + volSlider.frame.height)

    /*  CONVERSION WOES BELOW: */

    // Configure sliders:
    let seekOrigin = convertPoint(toView: convert(seekLabel.position, from: self))
    seekSlider.frame = CGRect(origin: seekOrigin, size: CGSize(width: 200, height: 15))
    seekSlider.value = 1

    let volOrigin = convertPoint(fromView: CGPoint(x: volLabel.frame.minX, y: volLabel.frame.minY))
    seekSlider.frame = CGRect(origin: volOrigin, size: CGSize(width: 200, height: 15))
    seekSlider.value = 0

    // Scene stuff:
    view.addSubview(seekSlider)
    view.addSubview(volSlider)
    addChild(seekLabel)
    addChild(volLabel)
  }
}

Upvotes: 2

Views: 327

Answers (1)

nathangitter
nathangitter

Reputation: 9777

You're very close! There are two minor issues in your code:

Issue #1

You modify the seekSlider's frame twice instead of modifying the seekSlider then the volSlider.

let volOrigin = convertPoint(fromView: CGPoint(x: volLabel.frame.minX, y: volLabel.frame.minY))
seekSlider.frame = CGRect(origin: volOrigin, size: CGSize(width: 200, height: 15))
seekSlider.value = 0

should be

let volOrigin = convertPoint(fromView: CGPoint(x: volLabel.frame.minX, y: volLabel.frame.minY))
volSlider.frame = CGRect(origin: volOrigin, size: CGSize(width: 200, height: 15))
volSlider.value = 0

Issue #2

The conversion code is not correct.

Using the convertPoint(toView method with the node's position should do the trick:

let seekOrigin = convertPoint(toView: seekLabel.position)

Final Code:

class GameScene: SKScene {

    let seekSlider = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))
    let volSlider  = UISlider(frame: CGRect(x: 0, y: 0, width: 200, height: 15))

    override func didMove(to view: SKView) {
        removeAllChildren() // Delete this in your actual project.

        // Add some labels:
        let seekLabel = SKLabelNode(text: "Seek")
        seekLabel.setScale(3)
        seekLabel.verticalAlignmentMode = .center
        seekLabel.position = CGPoint(x: frame.minX + seekLabel.frame.width/2,
                                     y: frame.maxY - seekLabel.frame.height)

        let volLabel  = SKLabelNode(text: "Volume")
        volLabel.setScale(3)
        volLabel.verticalAlignmentMode = .center
        volLabel.position = CGPoint(x: frame.minX + volLabel.frame.width/2,
                                    y: frame.minY + volLabel.frame.height + volSlider.frame.height)

        // Configure sliders:
        let seekOrigin = convertPoint(toView: seekLabel.position)
        let offsetSeekOrigin = CGPoint(x: seekOrigin.x, y: seekOrigin.y + 50)
        seekSlider.frame = CGRect(origin: offsetSeekOrigin, size: CGSize(width: 200, height: 15))
        seekSlider.value = 1

        let volOrigin = convertPoint(toView: volLabel.position)
        let offsetVolOrigin = CGPoint(x: volOrigin.x, y: volOrigin.y - 50)
        volSlider.frame = CGRect(origin: offsetVolOrigin, size: CGSize(width: 200, height: 15))
        volSlider.value = 0

        // Scene stuff:
        view.addSubview(seekSlider)
        view.addSubview(volSlider)
        addChild(seekLabel)
        addChild(volLabel)
    }
}

Final Result:

screenshot of sliders

Upvotes: 3

Related Questions