I'm making a snap game were I'm trying to remove two images from an array so they don't reappear again when first random card and second random card match. Is there any way I can do this? Thanks
var cardNamesArray: [String] = ["sad", "sleepy","angry"]
var cardNamesArray2: [String] = ["triste", "cansado","enfadado"]
Generates a random card for the first Array
firstRandomNumber = Int (arc4random_uniform(3))
let firstCardString:String = self.cardNamesArray[firstRandomNumber]
self.FirstCardImageView.image = UIImage(named: firstCardString)
Generates a random card for the second Array
SecondRandomNumber = Int (arc4random_uniform(3))
let SecondCardString:String = self.cardNamesArray2[SecondRandomNumber]
self.SecondCardImageView.image = UIImage(named: SecondCardString)
If they match player score 1 point
#IBAction func SnapButtonTapped(sender: UIButton) {
if firstRandomNumber == SecondRandomNumber {
print("index match")
self.playerScore += 1
self.playerScoreLabel.text = String(self.playerScore
}
Why don't you try to remove images from an Array itself. Once the random number matches, you can do that!
if firstRandomNumber == SecondRandomNumber {
print("index match")
self.playerScore += 1
self.playerScoreLabel.text = String(self.playerScore
cardNamesArray.removeAtIndex(firstRandomNumber)
cardNamesArray2.removeAtIndex(SecondRandomNumber)
if cardNamesArray.count == 0 && cardNamesArray2.count == 0{
print("User Won")
}else{
print("Continue Playing")
}
}
Crash Update:
Replace the below two lines in your code with mine
firstRandomNumber = Int (arc4random_uniform(UInt32(cardNamesArray.count)))
SecondRandomNumber = Int(arc4random_uniform(UInt32(cardNamesArray2.count)))
You may use a dictionary object in the Array.
Instead of
var cardNamesArray: [String] = ["sad", "sleepy","angry"]
You may use
Class CardItem{
var name = ""
var isDisplayed:Boolean?
}
And now
var cardNamesArray: [CardItem] = [CardItem(name:"sad",isDisplayed:false), CardItem(name:"sleepy",isDisplayed:false),CardItem(name:"angry",isDisplayed:false)]
Here is your random chunk:
SecondRandomNumber = Int (arc4random_uniform(3))
var uniqueItem = self.cardNamesArray2[SecondRandomNumber]
let SecondCardString:String = uniqueItem.name
self.SecondCardImageView.image = UIImage(named: SecondCardString)
uniqueItem.isDisplayed = true
So when you next time generate random number just check item's isDisplayed property.
Related
I'm building swift quiz app I want to show random questions with no repeat.
var sorular: Array = ["soru1","soru2","soru3","soru4","soru5"]
var gorulensoru = [Int]()
var sayac: Int = 0
var sorularcevaplar = ["D","Y","D","Y","D"]
var cevaplar: Array<Any> = []
var dogru: Int = 0
var yanlis: Int = 0
func chooseRandom() -> String {
if gorulensoru.count == sorular.count { return "" }
let randomItem = Int(arc4random() % UInt32(sorular.count)) //get
if (gorulensoru.contains(randomItem)) {
return chooseRandom()
}
let requiredItem = sorular[randomItem]
gorulensoru.append(randomItem)
return requiredItem
}
override func viewDidLoad() {
super.viewDidLoad()
soruText.text = chooseRandom()
}
What is the problem in my code? I'm tried insert selected random item to inside gorulensoru array but it shows again selected item
if (gorulensoru.contains(randomItem)) {
return chooseRandom()
}
This statement doesn't run.
Your code only runs once.
Also, you shouldn't include potential infinite recursive calls because it can easily get to a level where it causes a hang or crash.
Use shuffle() and then iterate over the array.
Change this and it may work:
let requiredItem = sorular[randomItem]
gorulensoru.append(requiredItem)
I would like to access the values of my textfield array but confused as the array I created is with tags.
So anyone knows how to get the value of the list (array) I created?
I want to create a function where I :
Get the value of the textfields on a list
Sort them by tags
get the value of each individual textfield
concatenate them in a string
1.Your collection Outlet will be something like this
#IBOutlet var textFields: [UITextFields]!
2. Sort it by tag
textFields.sort { $0.tag < $1.tag}
3. Use for loop to get value from array and concatenate it
var string = ""
for item in textFields {
string += item.text
}
Let's say you have following array,
var txtArray:[UITextField] = [UITextField]()
for i in 0...4 {
let txtField = UITextField(frame: .zero)
txtField.text = "\(i)"
txtField.tag = i
txtArray.append(txtField)
}
To get values you have to do following,
let sorted = txtArray.sorted { $0.tag < $1.tag }
let values = sorted.map { return $0.text! }
let test = values.joined(separator: " ")
print(test)
Output will be
0 1 2 3 4
Create an outlet connection and connect all your textfields to the same.
An outlet connection looks like
#IBOutlet strong var labels: [UILabel]!
Then to get all textfield contents and to append the same.
var resultString = ""
for item in enumerate(self.labels) {
resultString = resultString + item.text
}
Assume that you have array of UITextField
let textfield1 = UITextField()
textfield1.tag = 1
textfield1.text = "1"
let textfield2 = UITextField()
textfield2.tag = 2
textfield2.text = "2"
let textfield3 = UITextField()
textfield3.tag = 3
textfield3.text = "3"
let arrayOfTextFields :[UITextField] = [textfield2,textfield1,textfield3]
let result = self.getInputsValue(arrayOfTextFields, seperatedby: "-")
print(result)
Method you want :
func getInputsValue(_ inputs:[UITextField], seperatedby value: String) -> String {
return inputs.sorted {$0.tag < $1.tag}.map {$0.text}.compactMap({$0}).joined(separator: value)
}
Result:
1-2-3
I have created some code which reads through an array and saves data for each index into variables which I then pass onto to a created label.
Below is the code:
example of data arr content :
["2,5","5,1"] two indexes inside array
for i in 0..<dataArr.count {
let element = dataArr[i]
let labelNum = UILabel()
label split = element.components(separatedBy: ",")
let num1 = split[0]
let num2 = split[1]
let num1Nnum2 = "number 1 :" + num1 + " number 2:" + num2
labelnum.text = num1Nnum2
labelnum.textAlignment = .center
labelnum.frame = CGRect( x:10, y:90, width:250, height: 80)
self.view.addSubview(labelnum)
}
how can I create it so that when the label is created the second time when it reads index[1] it creates a new label with same code but drop the label under the first label. I have tried to do :
labelnum[i] to attempt to create a new label using the value of index for example labelnum1 when i is = 1.
Any help will be Appreciated.
There is UIStackView in iOS which lets you add elements dynamically at the bottom or top of the existing views. You can always add a new label which automatically appears at the bottom of the view. You can also accomplish this with UITableView or UIScrollView.
Here is an example of UIStackView, dynamically appending new label below previous one. I hope you can infer this for your use case,
class ViewController: UIViewController {
var lastLabelCount = 0
var stackView: UIStackView!
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
let tap = UITapGestureRecognizer(target: self,
action: #selector(tapped))
view.addGestureRecognizer(tap)
createViews()
}
func createViews() {
stackView = UIStackView(frame: .zero)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.axis = .vertical
stackView.alignment = .top
view.addSubview(stackView)
NSLayoutConstraint.activate([
stackView.leftAnchor.constraint(equalTo: view.leftAnchor),
stackView.rightAnchor.constraint(equalTo: view.rightAnchor),
stackView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
])
}
#objc func tapped() {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = UIColor.black
label.text = "Hi I am label \(lastLabelCount)"
stackView.addArrangedSubview(label)
lastLabelCount += 1
}
}
Create a variable to hold Y Position of The Label. and in each iteration add the height of previous label in Y Position variable to drop new label to below previous one.
class ViewController: UIViewController {
let dataArr = ["2,5","5,1"]
override func viewDidLoad() {
super.viewDidLoad()
var yPos = 90
for i in 0..<dataArr.count {
let element = dataArr[i]
let labelNum = UILabel()
let split = element.components(separatedBy: ",")
let num1 = split[0]
let num2 = split[1]
let num1Nnum2 = "number 1 :" + num1 + " number 2:" + num2
labelNum.text = num1Nnum2
labelNum.textAlignment = .center
labelNum.frame = CGRect( x:10, y:yPos, width:250, height: 80)
yPos += 80
self.view.addSubview(labelNum)
}
}
Ok, so I have an app that is designed for roleplaying. I have a guide that guides the user to creating the character. So the first thing the user has to do is put the character number. So I want it to search all the records for the attribute I have called characternumber and see what the largest number is.
Example: Lets say I have 5 characters. with character numbers 1,2,3,4,5. I want to cycle through all the records and see that 5 is the biggest number than automatically place a 6 in the character number text field.
This is what I have so far:
#IBOutlet var societyNumberTxt: UITextField!
#IBOutlet var characterNumberTxt: UITextField!
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var characters: [NSManagedObject] = []
var societyNum: [NSManagedObject] = []
var charNum: [String] = []
override func viewDidLoad()
{
super.viewDidLoad()
//1
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
//2
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
//3
do {
societyNum = try managedContext.fetch(fetchRequest)
let entityDescription = NSEntityDescription.entity(forEntityName: "Characters", in: managedObjectContext)
let request: NSFetchRequest<Characters> = Characters.fetchRequest()
request.entity = entityDescription
var results = try managedObjectContext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)
if societyNum.count > 0
{
let match = results[0] as! NSManagedObject
societyNumberTxt.text = (match.value(forKey: "societynumber") as? String)!
print(match)
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
else
{
print("empty array")
characterNumberTxt.text = "1"
}
}
else
{
societyNumberTxt.placeholder = "Society # not set"
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
I am not sure how to cycle through every record and check the attribute and place in the array. I have tried something like this:
var i = 0
for i in results
{
var match = results[i] as? NSManagedObject
charNum[i] = match
}
I get the error:
cannot subscript a value of type '[Any]' with an index of type 'Any'
Now to test my code for the if statement:
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
It returned and error:
Could not cast value of type 'NSTaggedPointerString' (0x108578d10) to 'NSArray' (0x108578dd8).
Am I even on the right past?
Adjust your fetch request with a SortDescriptor instead of finding the highest characterNumber manually:
...
//2
// get all characters ...
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
// ... sorted by characternumber in acending order
let sortDescriptor = NSSortDescriptor(key: "characternumber", ascending: true)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//3
do {
let characters = try managedContext.fetch(fetchRequest) as! [Characters]
if let highestCharacterNumber = characters.last?.characternumber {
characterNumberTxt.text = String(highestCharacterNumber + 1) // assuming characternumber is of type Int
} else {
characterNumberTxt.text = "1"
}
} ...
I have set of images that need to be set as left icon in leftcalloutaccessoryview in MKAnnotation. I already done it using if else statement. My problem is, instead of using 'if else' statement, it will be great if I can code it in 'for' statement using loop of array. Can anybody help me on this?How can I code the 'leftcalloutaccessoryview' using for loop array using set of images and coordinate that have in my set of arrays? I have been face this code for a month :(...thank you guys
//Define nearby Place of Interest
let latArray = [24.469546, 24.469450]
let longArray = [39.609105, 39.613062]
let poiTitle = ["An-Nisa 1","An-Nisa 2"]
let poiSubTitle = ["Gate 1","Gate 2"]
// let imageName = ["Jons.png","Locus.png"]
for var i=0;i<poiSubTitle.count;i++
{
var latPoi: CLLocationDegrees = latArray[i]
var longPoi: CLLocationDegrees = longArray[i]
var locationPoiAnnot = MKPointAnnotation()
locationPoiAnnot.title = poiTitle[i]
locationPoiAnnot.subtitle = poiSubTitle[i]
var locationPoi : CLLocationCoordinate2D = CLLocationCoordinate2DMake(latPoi,longPoi)
locationPoiAnnot.coordinate = locationPoi
self.mapView.addAnnotation(locationPoiAnnot)
}
}
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
let arrowButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
arrowButton.frame.size.width = 44
arrowButton.frame.size.height = 44
arrowButton.setImage(UIImage(named: "arrow.jpeg"), forState: .Normal)
pinView!.rightCalloutAccessoryView = arrowButton
var imageview = UIImageView(frame: CGRectMake(0, 0, 45, 45))
if(annotation.subtitle == "I am here!")
{
imageview.image=UIImage(named: "Locus.png")
}
else if(annotation.subtitle == "Gate 1")
{
imageview.image=UIImage(named: "Jons.png")
}
else if(annotation.subtitle == "Gate 2")
{
imageview.image=UIImage(named: "Katara.png")
}
pinView!.leftCalloutAccessoryView = imageview
}
else {
pinView!.annotation = annotation
}
return pinView }
Wondering if this helps:
let poiSubTitle = ["Gate 1","Gate 2"]
let imageName = ["Jons.png","Locus.png"]
for(var i = 0 ; i < imageName.count ; i++)
{
if(annotation.subtitle == poiSubTitle[i])
{
imageview.image = UIImage(named: imageName[i])
}
}
pinView!.leftCalloutAccessoryView = imageview
So just add all the 30 POI title to poiSubTitle and image path to imageName without changing the for loops...