I'm a newbie to swift and believe me I've searched and searched for an answer already. I want to create UISliders that get their values from an array of numbers in Swift. Its a camera app so the example array should be obvious.
#IBAction func isoValueChanged(sender: UISlider) {
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"] // available iPhone 6s ISO settings I believe
let currentValue = // What do I need?
isoText.text = "\(currentValue)"
}
Even harder would be representing shutter speeds from 1/1000 - 32!
From what I see out there this is not an easy one because there is no mathematical representation to calc from the array. Is it even possible?
I'm not quite sure I understand what you want this for but I'm guessing this is right.
// Global Variable or something like this (accessible from multiple functions)
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"] // available iPhone 6s ISO settings I believe
func functionThatCreatesTheSliderYo(...) {
slider.minimumValue = 0
slider.maximumValue = isoArray.count
slider.continuous = false
}
#IBAction func isoValueChanged(sender: UISlider) {
// instead of Int(val) you may want to round(val) for a better UI
let currentValue = isoArray[Int(sender.value)]
isoText.text = "\(currentValue)"
}
This works for me
#IBAction func isoValueChanged(sender: UISlider) {
let isoArray = ["24", "32", "50","64","80","100","125","160","200","250","320","400","500","640","720","800","1000","1250","1600","1800"]
let currentValue = isoArray[Int(sender.value)]
isoText.text = "\(currentValue)"
}
So simple as it should be in Swift. Many thanks to Ty. Be sure to see the chat though.
Related
So I'm practicing coding and I've set up an array of strings. What I want to happen is to have a function randomly select a string and if a certain string is selected, it would print out one message, and if any of the other strings are selected, it would print out a different one. I think setting up the messages could be done w/an if-else function, but I'm stuck on the earlier step of figuring out how to identify which string is called.
I did some searching and found this thread Get Random String from an Array and I copied the randomization code from it. I'm a bit overwhelmed with where to go from there.
What type of function/identifier etc would I need to set up so that the strings are uniquely identified?
class ViewController: UIViewController {
// Make collection of games and if Monsters is called, print "Take a break." If a diff string is called, print "Do your homework."
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
_ = games[randomNumber]
}
} // end of class
Your expectation is not very clear from your question, but I guess you are beginner and need a help with processing randomly selected string.
#IBAction func random(_ sender: UIButton) {
let games = ["Cards Against Humanity", "Mario Kart", "Halo", "Pixeljunk Monsters"]
let randomNumber = Int(arc4random_uniform(UInt32(games.count)))
let randomlyPickedString = games[randomNumber]
if randomlyPickedString == "Cards Against Humanity" {
print("Print anything you want about Cards Against Humanity")
}
else if randomlyPickedString == "Mario Kart" {
print("Print anything you want about Mario Kart")
}
else if randomlyPickedString == "Halo" {
print("Print anything you want about Halo")
}
else {
print("Print anything you want about Pixeljunk Monsters")
}
}
If its a finite set of values in array, you can even decide to use switch
I have two UITextFields that get the placeHolder.text randomly from an array. The part I am stuck on, is having an element in an array of answers, correspond to the placeHolder text.
Meaning: placeHolder.text is a question, user text input is the answer, and we check that the user answer is the same as the hard coded value.
sample code:
let questionArray = ["name of your cat?", "name of your other cat?"]
let questionArray2 = { more stupid questions ]
let answerArray = ["cat damen", "diabetes"]
let answerArray2 = [ more stupid answers ]
var answerContainer: String()
var answerContainer2: String()
uitextField1.placeHolder = questionArray.randomElement()
uitextField2.placeHolder = questionArray2.randomElement()
Heres where I get stupid :
func answerGenerator {
if UItextField1.placeHolder == questionArray[0] {
answerContainer = answerArray[0]
}
}
func submit(_ sender: UIButton) {
if uitextField.text == answerContainer && uitextField2.text == answerContainer2 {
do good stuff
}
}
I tried using a dictionary, but got stuck. I also thought about an Enum / Switch Case, but also got stuck as I have two textFields that need the placeHolder generated randomly.
so what happens is the actual answer that's supposed to be allocated to its question, maybe it happens, but I'm not grabbing it correctly to compare what the user will type in the textfield.
Its so easy, but I'm overthinking this.
I am trying to make a main menu for an Mac application as a beginning task to learn about Swift. Here is my code, which does not work.
In the AppDelegate
import Foundation
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate
{
#IBOutlet weak var window: NSWindow!
//private let mainWindow = NSWindow(frame: NSWindow.mainScreen().bounds)
//let mainWindow = NSWindow()
//let statusItem = NSStatusBar.systemStatusBar().statusItemWithLength(NSSquareStatusItemLength)
func applicationDidFinishLaunching(aNotification: NSNotification)
{
// Insert code here to initialize your application
let menuData = [getMainMenuItems]
//[makeMainMenu, menuData]
}
}
And then in a different project file, named Swift_FileManager
import Foundation
import Cocoa
class menuArrayObject
{
var title: String = ""
var subMenuTitles: [String] = []
}
func getMainMenuItems (menuData:Array<AnyObject>) -> AnyObject
{
//Make a new menu array
var menuData = [AnyObject]()
let arrayObject1 = menuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
return menuData
}
The code compiles but the function getMainMenuItems is never called.
Can somebody shed some light on the (probably very simple) issue here? Thanks in advance
let menuData = [getMainMenuItems]
This line (probably) isn't doing what you think it's doing. What it's doing is creating an array of [(Array<AnyObject>)->(AnyObject)] type (an array of functions that take an array of AnyObjects as input, and return an AnyObject) – and adding your getMainMenuItems function to it.
It's not calling your function at all.
In order to call a function, you need to use a pair of brackets (), containing the required input. In this case, your getMainMenuItems method expects an array of AnyObjects (although it never appears to actually use them).
For example:
let menuData = getMainMenuItems([/* Insert your objects here */])
Although that all being said, I'm not entirely sure that your getMainMenuItems function actually needs an input, as you never use it. I think you're looking for something like this:
func getMainMenuItems() -> [MenuArrayObject] {
// create an empty array of MenuArrayObjects
var menuData = [MenuArrayObject]()
let arrayObject1 = MenuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
return menuData
}
Note that the function no longer has an input, and I've replaced AnyObject with [MenuArrayObject]. It's best to be as type specific as you can in Swift (and pretty much every other OOP language), so you should really steer away from AnyObject unless you have good reason to use it.
Now you can just invoke your function like this:
let menuData = getMainMenuItems()
and it will return an array of MenuArrayObjects.
If you're trying to make the function so that it'll add an object to an already existing array, then you can use an inout parameter in your function. This will let you pass an array into your function, which it can modify.
For example:
func getMainMenuItems(inout menuData:[MenuArrayObject]) {
let arrayObject1 = MenuArrayObject()
arrayObject1.title = "Project"
arrayObject1.subMenuTitles = ["New Project","Open Project","Save Project", "Quit Project"]
menuData.append(arrayObject1)
}
You can then call it like so:
// an existing array of MenuArrayObjects
var menuDataArray = [MenuArrayObject]()
// call function with array – which it will append an element to
getMainMenuItems(&menuDataArray)
The code let menuData = [getMainMenuItems] is just creating an array containing the function. I'm guessing that you mean to call the function instead. That looks something like:
let menuData = getMainMenuItems([])
In applicationDidFinishLaunching you need to instantiate menuArrayObject:
let myMenuArray = menuArrayObject()
And then call it:
let menuData = myMenuArray.getMainMenuItems()
Your getMainMenuItems method, it seems looking at what you wrote in the method, should be defined as:
func getMainMenuItems() -> [AnyObject]
I'm trying to learn swift by creating different short games or apps. while trying to test my new gain knowledge on a game, I realized that I need to create a func that I didnt know how to create. I've looked around and none of the answers I've found really helped me understand what I have to do.
I'll summarize my game:
Its a single view app.
I've got five func.
I want to randomly pick a function to be executed.
After the function is executed the user will press a button that runs the random pick function again to randomly pick a func, but this time only out of the four other func that are left, and so on. At the same time once the five functions have been executed I want to restart the pick a random func all over again. so the game goes on and on for ever.
I'm not sure how to place the func In an array to make it work.
For example I've been using the following script in the game.
Func one generates a Label that shows a random string.
I've used the following script to create a random word generator for a label with out repeats and once it runs through all the words in the array it restarts again randomly. (It works perfectly)
struct randword {
var wordstring : String! }
var stentenceword = [randword]
var stentecenumber = Int
func wordsinsentence (){
sentenceword = [randoword(wordstring:"House"), randoword(wordstring:"Truck"), randoword(wordstring:"Ladder")]
}
func pickword(){
if sentenceword.count > 0 {
sentencenumber = random () % sentenceword.count
wordlabel.text = sentecneword[sentencenumber].wordstring
sentenceword.removeAtIndex(sentencenumber)
); if sentenceword.count <= 0{
wordsinsentence() }
Func two generates a random Image using the same script as before, just slightly modified for images.
Func three is a timer game with another script... and so on..etc etc.
Now I want all five func to randomly be picked and removed then once there aren't anymore left to restart, as on the example script I placed above.
I've tried using the same script and modifying it to replace the string! array with a function array, but with no positive result.
Can anyone help me with a solution or showing me another option of how I should do it?
Your question is a little difficult to follow, but let's focus on your most clear questions:
I'm not sure how to place the func In an array to make it work.
I want to randomly pick a function to be executed.
no repeats
First, to pick values randomly with no repeats you take a list and shuffle it into a random order. There's no need to keep track of previously selected items. Shuffling in Swift is explained very well by Nate Cook at How do I shuffle an array in Swift?
So that brings us to the second question, how do we create an array of functions? That's the simplest part. You just make an array of functions.
func first() { print("first") }
func second() { print("second") }
func third() { print("third") }
let fs = [first, second, third]
That's all there is to it. Now let's put them together and call them in a random order:
for f in fs.shuffle() {
f()
}
I tried to copy paste your code to a playground and try to fix it but its kinda unreadable. Indentation is really good habit especially if someone else has to look at your code. Anyway imagine if you could just say Int.radomOutOf(5) and it just returns some random number between 0 and 5. well you can do just that by adding extension to the class Int or CGFloat or Double as you wish. and have function to keep track of your the games life time and call those random functions. here is how to do it (I hope I didn't forget anything)
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var textLabel: UILabel!
var randomIndex = Int()
let NumberOfFunctions = 4
var chosenIndexes: [Int] = []{
didSet{
if chosenIndexes.count == NumberOfFunctions { chosenIndexes.removeAll() }
}
}
#IBAction func buttonPressed(sender: UIButton) {
functionSelector()
}
func functionSelector(){
repeat{
randomIndex = Int.randomOutOf(NumberOfFunctions)
print("selected: \(randomIndex) \(chosenIndexes)")
} while chosenIndexes.contains(randomIndex)
chosenIndexes.append(randomIndex)
switch randomIndex {
case 0: function1()
case 1: function2()
case 2: function3()
case 3: function4()
default: break
}
}
func function1(){
textLabel.text = "sentence 1"
}
func function2(){
textLabel.text = "sentence 2"
}
func function3(){
textLabel.text = "sentence 3"
}
func function4(){
textLabel.text = "sentence 4"
}
}
//your extension to pick random
private extension Int {
static func randomOutOf(max:Int) ->Int{
print("max: \(max)")
return Int(arc4random() % UInt32(max)) // returns 0 - max
}
}
This is just to show the first answer runs just fine
How come I'm getting the error "NSArray does not have a member named 'removeAtIndex'. How can I fix this? The error is on the fourth last line. Sorry if my question is stupid, I'm fairly new to programming. I appreciate all the help I get.
import Foundation
let userDefaults = NSUserDefaults.standardUserDefaults()
func isAppAlreadyLaunchedOnce()->Bool{
let defaults = NSUserDefaults.standardUserDefaults()
if let isAppAlreadyLaunchedOnce = defaults.stringForKey("isAppAlreadyLaunchedOnce"){
println("App already launched")
return true
}
else{
defaults.setBool(true, forKey: "isAppAlreadyLaunchedOnce")
println("App launched first time")
return false
}
}
struct newFactBook {
let factsArray = [
"Ants stretch when they wake up in the morning.",
"Ostriches can run faster than horses.",
"Olympic gold medals are actually made mostly of silver.",
"You are born with 300 bones; by the time you are an adult you will have 206.",
"It takes about 8 minutes for light from the Sun to reach Earth.",
"Some bamboo plants can grow almost a meter in just one day.",
"The state of Florida is bigger than England.",
"Some penguins can leap 2-3 meters out of the water.",
"On average, it takes 66 days to form a new habit.",
"Mammoths still walked the earth when the Great Pyramid was being built."]
}
var checkLaunch = isAppAlreadyLaunchedOnce()
var oldFunFactsArray = []
if(checkLaunch == false){
oldFunFactsArray = newFactBook().factsArray
}
else if (checkLaunch == true){
oldFunFactsArray = userDefaults.objectForKey("key") as! NSArray
}
func randomFacts1() -> (String, Int){
var unsignedArrayCount = UInt32(oldFunFactsArray.count)
var unsignedRandomNumber = arc4random_uniform(unsignedArrayCount)
var randomNumber = Int(unsignedRandomNumber)
return (oldFunFactsArray[randomNumber] as! String, randomNumber)
}
oldFunFactsArray.removeAtIndex[randomFacts1().1] //error here
userDefaults.setObject(oldFunFactsArray, forKey:"key")
userDefaults.synchronize()
println(oldFunFactsArray)
We have some problems here:
1 How to invoke a method
removeAtIndex is a method that accepts an Int as parameters. It cannot be invoked this way
removeAtIndex[randomFacts1().1]
instead you should write
removeAtIndex(randomFacts1().1)
2. The type of oldFunFactsArray is NSArray and it's wrong.
Intact when you write this:
var oldFunFactsArray = []
Swift does infer this:
var oldFunFactsArray : NSArray = []
But at this point you have an immutable NSArray so it does not have the removeAtIndex method.
Since you are using Swift I suggest you to declare the var oldFunFactsArray as follow:
var oldFunFactsArray : [String]
if checkLaunch == false {
oldFunFactsArray = newFactBook().factsArray
} else {
oldFunFactsArray = userDefaults.objectForKey("key") as! [String]
}
Please note that here I am declaring a Swift array of String(s). Since I use the var keyword this array will be mutable and we will be able to invoke removeAtIndex later on.
Also note that in the else branch I am force-casting the result of objectForKey to [String]. It will be fine since I see, below, you are writing the oldFunFactsArray in that slot.
Hope this helps.
You need to use NSMutableArray to use this method.
NSArray is not Mutable (can not change its content after it is intialized).