Make PanGesture becoming to slider - ios

I made a PanGuesture as a slider, Here blow is the responds func:
func respondsToPenGesture(sender: UIPanGestureRecognizer) {
if (sender.state == UIGestureRecognizerState.Began) {
if noFilterEffectButton.selected == false {
startPanLocation = sender.locationInView(self.newEffectView)
persentageNumber.text = String(startNumber)
persentageNumber.hidden = false
}
} else if (sender.state == UIGestureRecognizerState.Changed) {
let stopLocation = sender.locationInView(self.newEffectView)
let abscissaChange = stopLocation.x - startPanLocation!.x
if newEffectView.hidden == false {
if abs(abscissaChange) > 0 {
if noFilterEffectButton.selected == false{
if let effectCurrent = self.currentEffect {
effectCurrent.adjustParams(CGFloat(abscissaChange/6))
}
}
}
if noFilterEffectButton.selected == false {
var printChangingNumber = startNumber + Int(abscissaChange)
if printChangingNumber > 100 {
printChangingNumber = 100
} else if printChangingNumber < 0 {
printChangingNumber = 0
}
persentageNumber.text = String(printChangingNumber)
}
}
} else if (sender.state == UIGestureRecognizerState.Ended) {
let stopLocation = sender.locationInView(self.newEffectView)
let abscissaChange = stopLocation.x - startPanLocation!.x
startNumber = startNumber + Int(abscissaChange)
if startNumber > 100 {
startNumber = 100
} else if startNumber < 0 {
startNumber = 0
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.5*Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
self.persentageNumber.text = String(self.startNumber)
self.persentageNumber.hidden = true
}
}
}
percentageNumber is a label show the changes on the screen. And the adjustParams() function:
func adjustParams(value: CGFloat) {
newValue = value + newValue
self.adjust = newValue
print("AdjustNumber")
print(adjust)
}
And I override this function for exactly one effect:
override func adjustParams(value: CGFloat) {
super.adjustParams(value)
lastAutValueChange = lastAutValueChange + value/200
lastIntensityChange = lastIntensityChange + value/200
var currentAutValue = lastAutValueChange
var currentIntValue = lastIntensityChange
currentIntValue = currentIntValue < -1.0 ? -1.0 : currentIntValue
//value = value > 1.0 ? 1.0 : value
//autValue = value < -1.0 ? -1.0 : autValue
if (currentIntValue >= 0) {
currentIntValue = 1.0
} else {
currentIntValue += 1
}
if (currentAutValue <= 0) {
currentAutValue = 0
} else {
if currentAutValue > 1 {
currentAutValue = 1
}
}
print(currentIntValue)
print(currentAutValue)
self.autoTuneModule.setIntensity(Float(currentIntValue))
self.audioUnit.finalMix = Double(currentAutValue)
}
The test answer is not matchable for the exactly changes and the percentNumber shows on the screen. How could I change my functions to make them matchable for each others?
(By the way, I want to do something like the slider in Prisma, if there is something like it, please let me know about it).

Related

Get Index on UIslider

I have radar chart with data.I want to give index for slider Based on data count.If i am moving slider the graph value should move.If suppose i am at bellow of middle value slider thumb should go to near index.
for _ in 0..<3 {
let mind = arc4random_uniform(mult) + min
let bre = arc4random_uniform(mult) + min
let rel = arc4random_uniform(mult) + min
dataPoints.append(GraphDataPoints(mindfulness: Double(mind), breathing: Double(bre), relaxation: Double(rel)))
}
self.setChartData(mindfulness: dataPoints[0].mindfulness, breathing: dataPoints[0].breathing, relaxation: dataPoints[0].relaxation)
numberofPointsOnSlider = Float(100 / (dataPoints.count - 1))
numberofPointsOnSlider is percent to move.In lastSliderValue i am storing the slider value.pointIndex have index.
#objc func sliderTouchEvents(slider:UISlider,event: UIEvent){
slider.isContinuous = true
if let touchEvent = event.allTouches?.first{
switch touchEvent.phase{
case .began:
lastSliderValue = slider.value
break
case .moved:
if slider.value.truncatingRemainder(dividingBy: numberofPointsOnSlider) == 0{
if lastSliderValue < slider.value || lastSliderValue > slider.value{
pointIndex = Int(slider.value / numberofPointsOnSlider)
self.isIncrement = false
}
lastSliderValue = slider.value
}
if !animation {
if pointIndex >= 0 && pointIndex < dataPoints.count {
var percentToMove:Float = 0
if lastSliderValue > slider.value && pointIndex > 0 {
percentToMove = (100 * (numberofPointsOnSlider - (slider.value.truncatingRemainder(dividingBy: numberofPointsOnSlider) ))) / numberofPointsOnSlider
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - dataPoints[pointIndex - 1].mindfulness)
relaxationDiff = Float(dataPoints[pointIndex].relaxation - dataPoints[pointIndex - 1].relaxation)
breathingDiff = Float(dataPoints[pointIndex].breathing - dataPoints[pointIndex - 1].breathing)
}else if lastSliderValue < slider.value && pointIndex < dataPoints.count - 1 {
percentToMove = (100 * (slider.value.truncatingRemainder(dividingBy: numberofPointsOnSlider) )) / numberofPointsOnSlider
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - dataPoints[pointIndex + 1].mindfulness)
relaxationDiff = Float(dataPoints[pointIndex].relaxation - dataPoints[pointIndex + 1].relaxation)
breathingDiff = Float(dataPoints[pointIndex].breathing - dataPoints[pointIndex + 1].breathing)
}
mp = Float(dataPoints[pointIndex].mindfulness) - (mindfulDiff / 100 ) * percentToMove
rp = Float(dataPoints[pointIndex].relaxation) - (relaxationDiff / 100 ) * percentToMove
bp = Float(dataPoints[pointIndex].breathing) - (breathingDiff / 100) * percentToMove
UIView.animate(withDuration: 10, animations: {
self.setChartData(mindfulness: Double(self.mp) , breathing: Double(self.bp) , relaxation: Double(self.rp) )
})
}
else {
if (pointIndex < 0) {
pointIndex = 0
}
}
}
break
case .ended:
let progDiff = lastSliderValue - slider.value
print("End movie, \(pointIndex) , \(slider.value) ,progDiff: \(progDiff)")
if progDiff < 0{
if (progDiff * -1) >= numberofPointsOnSlider / 2 {
animation = true
UIView.animate(withDuration: 10, animations: {
slider.value += self.numberofPointsOnSlider + progDiff
})
pointIndex = Int(slider.value / numberofPointsOnSlider)+1
// if isIncrement {
// pointIndex += pointIndex
// }else {
// isIncrement = true
//
// }
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - Double(mp))
relaxationDiff = Float(dataPoints[pointIndex].relaxation - Double(rp))
breathingDiff = Float(dataPoints[pointIndex].breathing - Double(bp))
doGraphAnimate()
}else {
animation = true
UIView.animate(withDuration: 10, animations: {
slider.value = self.lastSliderValue
})
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - Double(mp))
relaxationDiff = Float(dataPoints[pointIndex].relaxation - Double(rp))
breathingDiff = Float(dataPoints[pointIndex].breathing - Double(bp))
doGraphAnimate()
}
}else if progDiff > 0{
if progDiff >= numberofPointsOnSlider / 2 {
animation = true
// if isIncrement {
// print("pointIndex : \(pointIndex)")
// pointIndex += pointIndex
// print("pointIndex Incremented : \(pointIndex)")
// }else{
// isIncrement = true
// }
pointIndex = Int(slider.value / numberofPointsOnSlider)
UIView.animate(withDuration: 10, animations: {
slider.value -= self.numberofPointsOnSlider - (self.lastSliderValue - slider.value)
})
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - Double(mp))
relaxationDiff = Float(dataPoints[pointIndex].relaxation - Double(rp))
breathingDiff = Float(dataPoints[pointIndex].breathing - Double(bp))
doGraphAnimate()
}
else {
animation = true
UIView.animate(withDuration: 10, animations: {
slider.value = self.lastSliderValue
})
mindfulDiff = Float(dataPoints[pointIndex].mindfulness - Double(mp))
relaxationDiff = Float(dataPoints[pointIndex].relaxation - Double(rp))
breathingDiff = Float(dataPoints[pointIndex].breathing - Double(bp))
doGraphAnimate()
}
}
default :
break
}
}
}
Help me, Thankyou .
DO you mean you want slider to move only at certain discrete positions when you move it ? But your spec is not totally clear.
If so, this is how I, so that if slider moves from 0 to 14 it will show 14, from 15 to 85, it will show 85. I let you adapt to get the exact working you want.
I use this IBAction for the slider
#IBAction fileprivate func changeRowSlider(_ sender: NSSlider) {
let movedPosition = Int(sender.doubleValue)
if movedPosition == 0 {
sender.integerValue = 0
return
}
if movedPosition <= 14 {
sender.integerValue = 14
return
}
if movedPosition <= 85 {
sender.integerValue = 85
return
}
sender.integerValue = 100 // last case: move to maxValue
}

How do I run a function inside an action in Sprite Kit?

I have the following code for a game I am making. In one of the parts, I have
let spawn = SKAction.run {
self.createCars()
}
but for some reason I keep getting an error saying "Value of type '(NSObject -> () -> GameScene' has no member 'createCars' even though createCars is a function defined lower in my code. Why is this happening and what can I do to fix this?
import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var lanecounter:CGFloat = 0
var score:Int = 0
var player:SKSpriteNode?
let scoreLabel = SKLabelNode()
let highScoreLabel = SKLabelNode()
var direction:Int?
let noCategory:UInt32 = 0
let carCategory:UInt32 = 0b1
let playerCategory:UInt32 = 0b1 << 1
let pointCategory:UInt32 = 0b1 << 2
var died:Bool?
var restartBTN = SKSpriteNode()
let moveLeft:SKAction = SKAction.moveBy(x: -100, y: 0, duration: 0.065)
let moveRight:SKAction = SKAction.moveBy(x: 100, y: 0, duration: 0.065)
let moveDown:SKAction = SKAction.moveTo(y: -800, duration: 1.1)
let spawn = SKAction.run {
self.createCars()
}
let delay = SKAction.wait(forDuration: 4)
func createCars(){
let middlePoints = SKSpriteNode()
var openLane:CGFloat = 0
middlePoints.size = CGSize(width: 100, height: 10)
middlePoints.physicsBody = SKPhysicsBody(rectangleOf: middlePoints.size)
//middlePoints.color = SKColor.purple
middlePoints.physicsBody?.categoryBitMask = pointCategory
middlePoints.physicsBody?.collisionBitMask = playerCategory
middlePoints.physicsBody?.contactTestBitMask = playerCategory
var randInt:Int = 0
randInt = Int(arc4random_uniform(3))
if lanecounter == -2 {
if randInt == 0 || randInt == 1 {
openLane = -1
}
if randInt == 2 {
openLane = -2
}
}
if lanecounter == 2 {
if randInt == 0 || randInt == 1 {
openLane = 1
}
if randInt == 2 {
openLane = 2
}
}
if lanecounter == -1 || lanecounter == 0 || lanecounter == 1 {
if randInt == 0 {
openLane = lanecounter - 1
}
if randInt == 1 {
openLane = lanecounter
}
if randInt == 2 {
openLane = lanecounter + 1
}
}
//print("lanecounter is", lanecounter)
//print("open lane is", openLane)
if openLane != -2 {
spawnCar(xCord: -2)
}
if openLane != -1 {
spawnCar(xCord: -1)
}
if openLane != 0 {
spawnCar(xCord: 0)
}
if openLane != 1 {
spawnCar(xCord: 1)
}
if openLane != 2 {
spawnCar(xCord: 2)
}
middlePoints.position = CGPoint(x: (openLane*100), y: self.frame.height)
self.addChild(middlePoints)
middlePoints.run(moveDown)
}
}
Minimal, Complete, and Verifiable
First of all, we need a Minimal, Complete, and Verifiable example like this:
class GameScene: SKScene {
let spawn = SKAction.run {
self.createCars()
}
func createCars() { }
}
error: value of type '(NSObject) -> () -> GameScene' has no member 'createCars'
Problem
The problem happens because you can't populate a property on the same line it is defined using self (infact self doesn't exist yet).
Solution
However you can use a lazy property wich will be evaluated only when called (and at that time self will be available).
class GameScene: SKScene {
lazy var spawn: SKAction = {
SKAction.run { self.createCars() }
}()
func createCars() { }
}

How to wait for user to click UILabel?

I want to make a while loop wait until a user clicks on a UILabel in a Swift Playground on Xcode. How can I do this?
Here's my loop
func gameLoop() {
while(score >= 0) {
let n = arc4random_uniform(3)
if(n == 0) {
opt1.text = rightStatements.randomElement()
opt2.text = wrongStatements.randomElement()
opt3.text = wrongStatements.randomElement()
} else if(n == 1) {
opt1.text = wrongStatements.randomElement()
opt2.text = rightStatements.randomElement()
opt3.text = wrongStatements.randomElement()
} else if(n == 2) {
opt1.text = wrongStatements.randomElement()
opt2.text = wrongStatements.randomElement()
opt3.text = rightStatements.randomElement()
}
}
}
For example, I want to wait until the user either clicks opt1, opt2, or opt3 Then do something based on what the user clicks.
Use Buttons instead of Labels and assign tag = 1, 2, and 3 for buttons. Create an IBAction function for the buttons and connect all the buttons to the same function.
Make variable 'n' as global.
var n = Int()
func nextAttempt() {
if(score >= 0) {
n = arc4random_uniform(3)
if(n == 0) {
opt1.text = rightStatements.randomElement()
opt2.text = wrongStatements.randomElement()
opt3.text = wrongStatements.randomElement()
} else if(n == 1) {
opt1.text = wrongStatements.randomElement()
opt2.text = rightStatements.randomElement()
opt3.text = wrongStatements.randomElement()
} else if(n == 2) {
opt1.text = wrongStatements.randomElement()
opt2.text = wrongStatements.randomElement()
opt3.text = rightStatements.randomElement()
}
}
else
{
//Score < 0
//Game Over
}
}
#IBAction func onButtonClick(_ sender: Any)
{
switch(sender.tag)
{
case 1:
if (n==0)
{
//Right button tapped
//Update score if you want
}
else
{
self.nextAttempt()
}
case 2:
if (n==1)
{
//Right button tapped
//Update score if you want
}
else
{
self.nextAttempt()
}
case 3:
if (n==2)
{
//Right button tapped
//Update score if you want
}
else
{
self.nextAttempt()
}
}
}
Hope this helps you!!

Maths formula of cleaner way for bounding box logic?

Below I have written some bounding box logic which is a bit verbose. Is there a way to make it more readable, so the check looks cleaner and more concise?
func validatePosition(position:SCNVector3, forNode node:SCNNode) -> SCNVector3 {
var newPosition = position
var maxVector = SCNVector3Zero
var minVector = SCNVector3Zero
let success = self.actionDelegate?.getBoundingBox(&minVector, max: &maxVector)
guard success == true else {
return newPosition
}
if newPosition.x < minVector.x && newPosition.x < 0 {
newPosition.x = minVector.x
}
if newPosition.y < minVector.y && newPosition.y < 0 {
newPosition.y = minVector.y
}
if newPosition.z < minVector.z && newPosition.z < 0 {
newPosition.z = minVector.z
}
if newPosition.x > maxVector.x && newPosition.x > 0 {
newPosition.x = maxVector.x
}
if newPosition.y > maxVector.y && newPosition.y > 0 {
newPosition.y = maxVector.y
}
if newPosition.z > maxVector.z && newPosition.z > 0 {
newPosition.z = maxVector.z
}
return newPosition
}
Try this:
extension ClosedInterval {
func clamp(value : Bound) -> Bound {
return self.start > value ? self.start
: self.end < value ? self.end
: value
}
}
extension SCNVector3 {
func clamp(min min:SCNVector3, max: SCNVector3) -> SCNVector3 {
let x = (min.x...max.x).clamp(self.x)
let y = (min.y...max.y).clamp(self.y)
let z = (min.z...max.z).clamp(self.z)
return SCNVector3(x, y, z)
}
}
func validatePosition(position:SCNVector3, forNode node:SCNNode) -> SCNVector3 {
var newPosition = position
var maxVector = SCNVector3Zero
var minVector = SCNVector3Zero
let success = self.actionDelegate?.getBoundingBox(&minVector, max: &maxVector)
guard success == true else {
return newPosition
}
newPosition = position.clamp(min: minVector, max: maxVector)
return newPosition
}

Integrating audio and accelerometer for Swift 2.0? (Using coremotion)

import CoreMotion
var ButtonAudio4URL = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Swing", ofType: "wav")!)
var ButtonAudioPlayer4 = AVAudioPlayer()
do {
try ButtonAudioPlayer4 = AVAudioPlayer(contentsOfURL: ButtonAudio4URL)
ButtonAudioPlayer4.prepareToPlay()
} catch {
print("audioPlayer failure")
}
func play() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.play()
}
func play2() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.play()
}
func play3() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.play()
}
func stop() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.stop()
}
func stop2() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.stop()
}
func stop3() {
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.stop()
}
lastDirection = 0 //Idle accel
threshold = 1.0 //Minimum positive(right) accel
nthreshold = -1.0 //Minimum negative(left) accel
if motionManager.accelerometerAvailable {
let queue = NSOperationQueue()
motionManager.startAccelerometerUpdatesToQueue(queue, withHandler: {
data, error in
guard let data = data else{
return
}
// Get the acceleration
let xAccel = data.acceleration.x //X accel
let yAccel = data.acceleration.y //Y accel
let zAccel = data.acceleration.z //Z accel
let xPositive = xAccel > 0 //Positive(right) x accel
let xNegative = xAccel < 0 //Negative(left) x accel
let yPositive = yAccel > 0 //Positive(up) y accel
let yNegative = yAccel < 0 //Negative(down) y accel
let zPositive = zAccel > 0 //Positive(front) z accel
let zNegative = zAccel < 0 //Negative(back) z accel
// Run if the acceleration is higher than theshold
if abs(xAccel) > self.threshold {
//If moved right
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && xPositive {
self.lastDirection = 1
print("Up")
self.play()
} else if self.lastDirection != -1 && !xPositive {
self.lastDirection = -1
print("Down")
self.play()
}
}
}
// Run if the acceleration is higher than ntheshold
if abs(xAccel) < self.nthreshold {
//If moved left
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && xNegative {
self.lastDirection = 1
print("Up")
self.play2()
} else if self.lastDirection != -1 && !xNegative {
self.lastDirection = -1
print("Down")
self.play2()
}
}
}
// Run if the acceleration is higher than theshold
if abs(yAccel) > self.threshold {
//If moved up
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && yPositive {
self.lastDirection = 1
print("Up")
self.play()
} else if self.lastDirection != -1 && !yPositive {
self.lastDirection = -1
print("Down")
self.play()
}
}
}
// Run if the acceleration is higher than ntheshold
if abs(yAccel) < self.nthreshold {
//If moved left
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && yNegative {
self.lastDirection = 1
print("Up")
self.play2()
} else if self.lastDirection != -1 && !yNegative {
self.lastDirection = -1
print("Down")
self.play2()
}
}
}
// Run if the acceleration is higher than theshold
if abs(zAccel) > self.threshold {
//If moved front
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && zPositive {
self.lastDirection = 1
print("Up")
self.play()
} else if self.lastDirection != -1 && !zPositive {
self.lastDirection = -1
print("Down")
self.play()
}
}
}
// Run if the acceleration is higher than theshold
if abs(zAccel) < self.nthreshold {
//If moved back
dispatch_async(dispatch_get_main_queue()) {
if self.lastDirection != 1 && zNegative {
self.lastDirection = 1
print("Up")
self.play2()
} else if self.lastDirection != -1 && !zNegative {
self.lastDirection = -1
print("Down")
self.play2()
}
}
}
})
}
Hello,
I have built an iOS app with Xcode 7.2, Swift 2.0, for i0S 9.2
I would like to add a feature where when the user waves their device in the air, a sound will be played. My problem is that, although the sound plays, it suddenly stops, and is replayed when moved again in the process of playing the sound. I would like the sound to just be played once, without any overlapping or stopping. I have included all the code related to CoreMotion, and excluded all others.
Thank you.
If I do understand your purpose, you probably would like to have a boolean barrier to prevent duplicated playing.
Ex:
var isPlaying1 = false
func play() {
if self.isPlaying1 == true {
return
}
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.play()
self.isPlaying1 = true
}
func stop() {
if self.isPlaying1 == false {
return
}
ButtonAudioPlayer4.currentTime = 0
ButtonAudioPlayer4.stop()
self.isPlaying1 = false
}

Resources