I'm new to Swift, but I'm not new to coding. I thought I would try my hand at making a little game. It's something I like to do when learning.
Here's what I'm doing. I start of by calling a method that initialized my "object templates"
internal func initializeObjectTemplates(){
objectTemplates.append(GameObject(passed_x: 0,
passed_y: 0,
passed_max: 25,
passed_min: 25,
passed_points: 100,
passed_img: "BeerGlass1",
passedLengthOfTimeOnScreen: 5,
passedBottomChance: 1,
passedTopChance: 50,
passedId: 0))
objectTemplates.append(GameObject(passed_x: 0,
passed_y: 0,
passed_max: 25,
passed_min: 25,
passed_points: 300,
passed_img: "BeerGlass2",
passedLengthOfTimeOnScreen: 2,
passedBottomChance: 51,
passedTopChance: 100,
passedId: 0))
}
I have a timer that runs a func named "update" every second. The "update" func randomly selects one of the two templates, adds some other information to the template object, does some other logic, and appends the object to an array I have. Everything up to the append seems to be working. I have added various breakpoints and the GameObject object seems to be getting populated correctly.
When I append the object it is overwriting other items in the objects array. I can't figure it out. I've googled it as much as possible, and can't really seem to find anything that fits my issue. Here's the rest of my code related to this.
This is the top of the ViewController and the viewDidLoad
internal var step = 0
internal var objects = [GameObject]()
#IBOutlet weak var points: UILabel!
internal var objectTemplates = [GameObject]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.backgroundColor = UIColor.blackColor()
initializeObjectTemplates()
let timer = NSTimer(timeInterval: 1, target: self, selector: #selector(ViewController.update), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(timer, forMode: NSRunLoopCommonModes)
//var i = 1
//while i <= 100{
// update()
// i += 1
//}
}
Update Func - the commented out/hard coded append works, but obviously not what I want
internal func update(){
step += 1
//removeExpiredButtons()
objects.append(populateObjectTemplate(selectObjectTemplate(), step: step))
//objects.append(GameObject(passed_x: 0,
// passed_y: 0,
// passed_max: 25,
// passed_min: 25,
// passed_points: 300,
// passed_img: "BeerGlass2",
// passedLengthOfTimeOnScreen: 2,
// passedBottomChance: 51,
// passedTopChance: 100,
// passedId: step))
print("There are \(objects.count) items and the first item has an id of \(objects[0].id)")
}
These are the methods that update calls
selectObjectTemplate
func selectObjectTemplate() -> GameObject {
let rand = Random.within(1...100)
return objectTemplates.filter(){
let isAbove = $0.bottomChance <= rand
let isBelow = $0.topChance >= rand
return isAbove && isBelow
}[0]
}
populateObjectTemplate
func populateObjectTemplate(obj: GameObject, step: Int) -> GameObject {
let widthBoundary = Float(self.view.frame.width - 20)
let heightBoundary = Float(self.view.frame.height - 20)
let placex = CGFloat(Random.within(20.0...widthBoundary))
obj.x = placex
let placey = CGFloat(Random.within(50.0...heightBoundary))
obj.y = placey
obj.expiration = obj.lengthOfTimeOnScreen + step
obj.id = step
obj.button = populateObjectButton(obj)
return obj
}
populateObjectButton
func populateObjectButton(obj: GameObject) -> UIButton {
let button = UIButton(type: UIButtonType.Custom)
let image = UIImage(named: obj.img)
button.setBackgroundImage(image, forState: UIControlState.Normal)
button.frame = CGRectMake(obj.x, obj.y, obj.minSize, obj.minSize)
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.layer.masksToBounds = true
button.addTarget(self, action: #selector(ViewController.objectTapped(_:)), forControlEvents: .TouchUpInside)
button.tag = obj.id
self.view.addSubview(button)
return button
}
Sorry for such a lengthy post. I just wanted to include as much information as possible. I don't usually post to places like this, because I try as hard as possible to find the solution myself. The swift file is also on Git.
https://github.com/JoeBrewing/TapGlassMasterChallenge/blob/master/Glass%20Tap%20Master%20Challenge/ViewController.swift
Your objectTemplates array stores references to two GameObject instances that were created in initializeObjectTemplates. When your timer fires you select one of these 'template' objects, modify it and add it to the array. However, the array is merely storing references to the objects you add to it, and you only have two objects, even though you are adding those objects to the array multiple times.
When you call populateObjectTemplate you modify one of the two object templates, which means that all other entries in the array that refer to that particular template will reflect those modifications. You need populateObjectTemplate to return a new GameObject, using the information in the template;
func populateObjectTemplate(obj: GameObject, step: Int) -> GameObject {
let newGameObject=GameObject(passed_x: 0,
passed_y: obj.passed_y,
passed_max: obj.passed_max,
passed_min: obj.passed_min,
passed_points: obj.passed_points,
passed_img: obj.passed_img,
passedLengthOfTimeOnScreen: obj.passedLengthOfTimeOnScreen,
passedBottomChance: obj.passedBottomChance,
passedTopChance: obj.passedTopChance,
passedId: obj.passedId)
let widthBoundary = Float(self.view.frame.width - 20)
let heightBoundary = Float(self.view.frame.height - 20)
let placex = CGFloat(Random.within(20.0...widthBoundary))
newGameObject.x = placex
let placey = CGFloat(Random.within(50.0...heightBoundary))
newGameObject.y = placey
newGameObject.expiration = obj.lengthOfTimeOnScreen + step
newGameObject.id = step
newGameObject.button = populateObjectButton(obj)
return newGameObject
}
Related
I'm a bit stumped on this :
Context
I have a 'workout session' which is in a tableView inside a UIViewController. Each cell has an exercise name, number of reps and a swap button. The swap button generates a new exercise from the exercise bank (i.e. if it says "bench press" but you don't have a bench press then you can swap it for something else).
Problem
My swap button code works and a new exercise populates the cell. However, when I press "Play" on my workout timer, it resets to what it was before!
Code - swap button
func swapButtonTapped(cell: WorkoutCell) {
let realmExercisePool = realm.objects(ExerciseGeneratorObject.self)
let index = Int(arc4random_uniform(UInt32(realmExercisePool.count)))
let newExercise = realmExercisePool[index].generateExercise()
cell.exerciseName.text = newExercise.name
cell.repsNumber.text = String(newExercise.reps)
}
Code - Timer
#IBAction func timerControlTapped(_ sender: UIButton) {
if isTimerRunning == false {
sender.setImage(#imageLiteral(resourceName: "timerPause"), for: UIControlState.normal)
runTimer()
isTimerRunning = true
swapButtonEnabled = false
workoutTableView.reloadData()
} else {
sender.setImage(#imageLiteral(resourceName: "timerPlay"), for: UIControlState.normal)
workoutTimerObject.invalidate()
isTimerRunning = false
}
}
Code - Run Timer
func runTimer() {
workoutTimerObject = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(WorkoutViewController.workoutTimer), userInfo: nil, repeats: true)
isTimerRunning = true
}
The original group of exercises are passed in an array of workoutExercises from the previous VC (a 'workout set up screen')
Thanks everyone!
For anyone else who has a similar problem, I managed to work this out.
This was happening because I was simply changing the 'content' of the cell in my swapButtonTapped and not the actual data source.
When I then called "reloadData()" in timerControlTapped, it was reloading the original data.
What I needed to do was replace the actual data by replacing the exercise at the selected index with a new one in the "selectedWorkoutExerciseArray".
I used this code :
func swapButtonTapped(cell: WorkoutCell) {
let myIndexPath = workoutTableView.indexPath(for: cell)
let realmExercisePool = realm.objects(ExerciseGeneratorObject.self)
let index = Int(arc4random_uniform(UInt32(realmExercisePool.count)))
let newExercise = realmExercisePool[index].generateExercise()
selectedWorkoutExerciseArray[(myIndexPath?.row)!] = newExercise
cell.exerciseName.text = newExercise.name
cell.repsNumber.text = String(newExercise.reps)
}
I am working on an application in Swift. At the beginning I provide number of inputs that I would like to add. In next view I create as many UITextFields as I defined in first view.I have a problem with storing of all this values from TextFields after pressing the button. It seems to me that the most effective solution is to create an array of UITextFields and add every value of TextField into array and then in action for button adding values which are in all TextFields into array. Unfortunately, it doesn't work. Any suggestions? Thanks in advance.
override func viewDidLoad() {
super.viewDidLoad()
var counter = 0
for i in 1...mainInstance.numberOfInputs
{
super.viewDidLoad()
array.insert(UITextField(frame: CGRect(x: 0, y: 50, width: 60, height: 20)), at: i)
array[i].center = CGPoint(x: 200,y: 50 + counter)
array[i].textAlignment = NSTextAlignment.center
array[i].layer.borderWidth = 1
array[i].layer.borderColor = UIColor.black.cgColor
self.outletScrollView.addSubview(array[i])
counter += 50
}
super.viewDidLoad()
let button = UIButton(type: .system) // let preferred over var here
button.frame = CGRect(x: 200, y: 50 + counter, width: 100, height: 20)
button.setTitle("Recalculate", for: UIControlState.normal)
button.addTarget(self, action: "actionRecalculate:", for: UIControlEvents.touchUpInside)
self.outletScrollView.addSubview(button)
outletScrollView.contentInset = UIEdgeInsetsMake(0, 0, CGFloat(counter+100), 0)
}
You could create easily with:
let textFields = [UITextField]()
You should consider using an UIScrollView, (like in your example) or (better idea in my opinon) a UITableView to add your UITextfields. So you have multiple Rows, and every row has one UITextField. The number of rows / Textfield can u easily customize (and get it from your FirstViewController for example).
Just create a custom UITableViewCell - add an UITextField and connect the IBOutlet. To get the values from every UITextField you could iterate through all cells, and read out the values. Just ask, if you need more help about doing that.
Creating array of UITextfield could be done this way
// Create an empty array of type UITextField
var listOfTextFields : [UITextField] = []
// In viewDidLoad, create a textfield and add it to the array
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...mainInstance.numberOfInputs-1 {
let textField = UITextField((frame: CGRect(x: X, y: Y*i, width: yourWidth, height: yourHeight)))
textField.delegate = self
listOfTextFields.append(textField)
}
}
In this UITextField setup, I didn't account for any formatting to shorten the answer.
Though this might not be for the exact use case, it could help others with similar use cases (particularly programmatically created textfields or custom uicell).
txtfield.tag = indexPath.row // or other int
Then you implement textfield didEndEditing after array has been initialized and delegating
#IBAction func endedEditing(_ sender: UITextField) {
arr[sender.tag] = sender.text
}
I'm trying to make a Wack-a-Mole game. The way I am doing so is by having one button randomly appear and disappear around the screen after someone has tapped it. If they do not tap the button within one second after it reappears, then it will disappear and find a new position, then reappear and wait one second and repeat the above steps. However, whenever I run this code, it doesn't do that. It moves positions only if I get rid of the 'while' statement and the 'if else' statement. Why won't it loop, disappear, reappear, etc?
Delay is this: https://stackoverflow.com/a/24318861/5799228
#IBAction func moveButton(button: UIButton) {
while self.WaffleButton.hidden == true || false {
if self.WaffleButton.hidden == false {
self.WaffleButton.hidden = true
delay(3) {
// Find the button's width and height
let buttonWidth = button.frame.width
let buttonHeight = button.frame.height
// Find the width and height of the enclosing view
let viewWidth = button.superview!.bounds.width
let viewHeight = button.superview!.bounds.height
// Compute width and height of the area to contain the button's center
let xwidth = viewWidth - buttonWidth
let yheight = viewHeight - buttonHeight
// Generate a random x and y offset
let xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
let yoffset = CGFloat(arc4random_uniform(UInt32(yheight)))
// Offset the button's center by the random offsets.
button.center.x = xoffset + buttonWidth / 2
button.center.y = yoffset + buttonHeight / 2
self.WaffleButton.hidden = false
self.delay(1) {
self.WaffleButton.hidden = true
}
}
} else { delay(3) {
// Find the button's width and height
let buttonWidth = button.frame.width
let buttonHeight = button.frame.height
// Find the width and height of the enclosing view
let viewWidth = button.superview!.bounds.width
let viewHeight = button.superview!.bounds.height
// Compute width and height of the area to contain the button's center
let xwidth = viewWidth - buttonWidth
let yheight = viewHeight - buttonHeight
// Generate a random x and y offset
let xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
let yoffset = CGFloat(arc4random_uniform(UInt32(yheight)))
// Offset the button's center by the random offsets.
button.center.x = xoffset + buttonWidth / 2
button.center.y = yoffset + buttonHeight / 2
self.WaffleButton.hidden = false
self.delay(1) {
self.WaffleButton.hidden = true
}
}
}
}
}
You are using while in a way it is not meant to be used.
This is how you should use while :
var someCondition = true
while someCondition {
// this will loop as fast as possible untill someConditionIsTrue is no longer true
// inside the while statement you will do stuff x number of times
// then when ready you set someCondition to false
someCondition = false // stop
}
This is how you are using while :
let someConditionThatIsAlwaysTrue = true
while someConditionThatIsAlwaysTrue {
// condition is always true, so inifinite loop...
// this creates a function that is executed 3 seconds after the current looping pass of the while loop.
// while does not wait for it to be finished.
// while just keeps going.
// a fraction of a second later it will create another function that will execute 3 seconds later.
// so after 3 seconds an infite amount of functions will execute with a fraction of a second between them.
// except they won't, since the main thread is still busy with your infinite while loop.
delay(3) {
// stuff
}
}
How to do it the right way :
don't ever use while or repeat to "plan" delayed code execution.
Split up the problem in smaller problems:
Issue 1 : Creating a loop
A loop is created by have two functions that trigger each other.
I will call them execute and executeAgain.
So execute triggers executeAgain and executeAgain triggers execute and then it starts all over again -> Loop!
Instead of calling execute and executeAgain directly, you also create a start function. This is not needed but it is a good place to setup conditions for your looping function. start will call execute and start the loop.
To stop the loop you create a stop function that changes some condition.
execute and executeAgain will check for this condition and only keep on looping if the check is successful. stop makes this check fail.
var mustLoop : Bool = false
func startLoop() {
mustLoop = true
execute()
}
func execute() {
if mustLoop {
executeAgain()
}
}
func executeAgain() {
if mustLoop {
execute()
}
}
func stop() {
mustLoop = false
}
Issue 2: Delayed Execution
If you need a delay inside a subclass of NSObject the most obvious choice is NSTimer. Most UI classes (like UIButton and UIViewController) are subclasses of NSObject.
NSTimer can also be set to repeat. This would also create a loop that executes every x seconds. But since you actually have 2 alternating actions it makes more sense to adopt the more verbose looping pattern.
An NSTimer executes a function (passed as Selector("nameOfFunction")) after x amount of time.
var timer : NSTimer?
func planSomething() {
timer = NSTimer.scheduledTimerWithTimeInterval(3, target: self, selector: Selector("doSomething"), userInfo: nil, repeats: false)
}
func doSomething() {
// stuff
}
If you need a delay in another class/struct (or you don't like NSTimer) you can use the delay function that matt posted.
It will execute whatever you enter in the closure after x amount of time.
func planSomething() {
delay(3) {
doSomething()
}
}
func doSomething() {
// stuff
}
Combining the two solutions:
By using the loop pattern above you now have distinct functions. Instead of calling them directly to keep the loop going. You insert the delay method of your choice and pass the next function to it.
So NSTimer will have a Selector pointing to execute or executeAgain and with delay you place them in the closure
How to implement it elegantly:
I would subclass UIButton to implement all this. Then you can keep your UIViewController a lot cleaner. Just choose the subclass in IB and connect the IBOutlet as usual.
This subclass has a timer attribute that will replace your delay.
The button action wacked() is also set in the init method.
From your UIViewController you call the start() func of the button. This will start the timer.
The timer will trigger appear() or disappear.
wacked() will stop the timer and make the button hide.
class WackingButton : UIButton {
var timer : NSTimer?
var hiddenTime : NSTimeInterval = 3
var popUpTime : NSTimeInterval = 1
override init(frame: CGRect) {
super.init(frame: frame)
self.addTarget(self, action: "wacked", forControlEvents: UIControlEvents.TouchUpInside)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.addTarget(self, action: "wacked", forControlEvents: UIControlEvents.TouchUpInside)
}
func start() {
timer = NSTimer.scheduledTimerWithTimeInterval(hiddenTime, target: self, selector: Selector("appear"), userInfo: nil, repeats: false)
}
func appear() {
self.center = randomPosition()
self.hidden = false
timer?.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(popUpTime, target: self, selector: Selector("dissappear"), userInfo: nil, repeats: false)
}
func dissappear() {
self.hidden = true
timer?.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(hiddenTime, target: self, selector: Selector("appear"), userInfo: nil, repeats: false)
}
func wacked() {
self.hidden = true
timer?.invalidate()
}
func randomPosition() -> CGPoint {
// Find the width and height of the enclosing view
let viewWidth = self.superview?.bounds.width ?? 0 // not really correct, but only fails when there is no superview and then it doesn't matter anyway. Won't crash...
let viewHeight = self.superview?.bounds.height ?? 0
// Compute width and height of the area to contain the button's center
let xwidth = viewWidth - frame.width
let yheight = viewHeight - frame.height
// Generate a random x and y offset
let xoffset = CGFloat(arc4random_uniform(UInt32(xwidth)))
let yoffset = CGFloat(arc4random_uniform(UInt32(yheight)))
// Offset the button's center by the random offsets.
let x = xoffset + frame.width / 2
let y = yoffset + frame.height / 2
return CGPoint(x: x, y: y)
}
}
Your UIViewController :
class ViewController: UIViewController {
#IBOutlet weak var button1: WackingButton!
override func viewDidAppear(animated: Bool) {
button1.start()
}
}
I am building an app that has a UICollectionView with three items. Each item takes up the complete width of the screen and shows a timer that counts down to the next departure times for our busses in each location.
Each item contains 1) the departure address, 2) a string "Next shuttle leaves at time", and 3) a timer that counts down to the next departure time in 00:00:00 format.
Item 1 and 2 display as expected, but when I get to item 3 the departure address and string are correct, but the timer shows the time for cell 1 instead of cell 3.
I am setting the UICollectionView up like:
func setupCollectionView() {
let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
layout.itemSize = frame.size
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = UICollectionViewScrollDirection.Horizontal
let collFrame:CGRect = CGRectMake(0, 0, self.frame.width, self.frame.height)
collectionView = UICollectionView(frame: collFrame, collectionViewLayout: layout)
collectionView!.dataSource = self
collectionView!.delegate = self
collectionView!.registerClass(NextShuttleCell.self, forCellWithReuseIdentifier: "cell")
collectionView!.backgroundColor = UIColor.whiteColor()
collectionView!.pagingEnabled = true
collectionView!.scrollIndicatorInsets = UIEdgeInsetsZero
collectionView!.layer.borderWidth = 0
collectionView!.layer.borderColor = UIColor.clearColor().CGColor
self.addSubview(collectionView!)
}
And creating the items using:
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell:NextShuttleCell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! NextShuttleCell
switch(indexPath.row) {
case 0:
cell.setCellColor(help.darkAccent1())
cell.setLocationLabel("Auckland, Victoria Street")
cell.schedule = getScheduleFor("Victoria Street")
case 1:
cell.setCellColor(help.darkAccent2())
cell.setLocationLabel("Wellington, Airedale Street")
cell.schedule = getScheduleFor("Airedale Street")
case 2:
cell.setCellColor(help.darkAccent3())
cell.setLocationLabel("Airport, Auckland")
cell.schedule = getScheduleFor("Auckland Airport")
default: break
}
return cell
}
When this view is instantiated it retrieves the schedule from Parse.com. The getScheduleFor function then iterates through this schedule and returns the relevant locations schedule object to the custom cell.
I know that the getScheduleFor function is working correctly as it pulls the right information for the first two items, and if I change the order of the items (e.g. swap the item 3 code with item 1, then the correct data shows in item 1 but item 3 is incorrect.
Also note that it is only the timer that is incorrect on item 3, the remaining information is correct and this is pulled from the schedule object as well - so I know it's pulling the right data.
I also moved this into a UITableView and it showed the correct data so it seems to be something to do with the way the UICollectionView manages it's items.
EDIT:
I am using a custom UICollectionViewCell and initialising it using:
override init(frame: CGRect) {
super.init(frame: frame)
initTimer()
}
This gets the next shuttle time and initialises a timer to update the count down label.
func initTimer() {
nextShuttleTime = getNextShuttleTime()
timeTillNextShuttle = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
Then, it gets the time using the following:
func updateTime() {
let nextShuttleAt:NSTimeInterval = NSTimeInterval(nextShuttleTime.timeIntervalSinceNow)
let currentTime:NSTimeInterval = NSTimeInterval(NSDate().timeIntervalSinceNow)
let timeLeft:NSTimeInterval = nextShuttleAt - currentTime
if timeLeft >= 0 {
let seconds = timeLeft
timeLabel.text = "\(stringFromTimeInterval(seconds))"
self.updateNextShuttleLabel()
} else {
timeTillNextShuttle.invalidate()
initTimer()
}
}
WORKING SOLUTION:
As per the comments, I stopped getNextShuttleTime() from being assigned to a variable and instead called this in the updateTimer() function. Updated as per below:
func initTimer() {
timeTillNextShuttle = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "updateTime", userInfo: nil, repeats: true)
}
func updateTime() {
let nextShuttleAt:NSTimeInterval = NSTimeInterval(getNextShuttleTime().timeIntervalSinceNow)
let currentTime:NSTimeInterval = NSTimeInterval(NSDate().timeIntervalSinceNow)
let timeLeft:NSTimeInterval = nextShuttleAt - currentTime
if timeLeft >= 0 {
let seconds = timeLeft
timeLabel.text = "\(stringFromTimeInterval(seconds))"
self.updateNextShuttleLabel()
} else {
timeTillNextShuttle.invalidate()
initTimer()
}
}
Your NextShuttleCell objects will be re-used, so you need to make sure that everything is updated when the cell is assigned - you can't rely on init() as this will only be called the first time that a cell is assigned.
Rather than storing the nextShuttleTime variable in initTimer() you can call getNextShuttleTime() in updateTime - this way you will always get the correct time.
I create UISlider Programmatically. I try to customise UISlider value as 4.1, 4.2, 4.3, 4.4, 4.5, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 6.0, ... Anybody give me the solution
sliderDemo = UISlider(frame:CGRectMake(0, 0, 200,20))
var numberOfSteps : NSInteger = numbers.count - 1
sliderDemo.minimumValue = 6.5
sliderDemo.maximumValue = 4.1
sliderDemo.continuous = true
sliderDemo.value = 4.0
sliderDemo.addTarget(self, action: "sliderValueDidChange:", forControlEvents: .ValueChanged)
self.view.addSubview(sliderDemo)
func sliderValueDidChange(sender:UISlider!)
{
println("number:\(sender.value)")
}
I just create an example of a custom slider for you, in this case I am creating and adding it myself to the form but you can easily adapt to use the one from storyboard, all you need to do is to add your values to the numbers array, the result will be in the variable number in the valueChanged function, you can use observer, notifications or protocol to retrieve the value as it change, or simply call a function from there.
class ViewController: UIViewController {
var slider:UISlider?
// These number values represent each slider position
var numbers = [1, 2, 3, 4, 5, 6, 7] //Add your values here
var oldIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
slider = UISlider(frame: self.view.bounds)
self.view.addSubview(slider!)
// slider values go from 0 to the number of values in your numbers array
var numberOfSteps = Float(numbers.count - 1)
slider!.maximumValue = numberOfSteps;
slider!.minimumValue = 0;
// As the slider moves it will continously call the -valueChanged:
slider!.continuous = true; // false makes it call only once you let go
slider!.addTarget(self, action: "valueChanged:", forControlEvents: .ValueChanged)
}
func valueChanged(sender: UISlider) {
// round the slider position to the nearest index of the numbers array
var index = (Int)(slider!.value + 0.5);
slider?.setValue(Float(index), animated: false)
var number = numbers[index]; // <-- This numeric value you want
if oldIndex != index{
println("sliderIndex:\(index)")
println("number: \(number)")
oldIndex = index
}
}
}
I hope that helps you!