Wrong order in string array - arrays

I have this code that passes the entries from textfield and adds them to a string array in another view controller. The problem is, the order is not correct.
This is my code:
//Textfields
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var text3: UITextField!
#IBOutlet weak var text4: UITextField!
#IBOutlet weak var text5: UITextField!
#IBOutlet weak var text6: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Delegates each textfield
text1.delegate = self
text2.delegate = self
text3.delegate = self
text4.delegate = self
text5.delegate = self
text6.delegate = self
//Tags each textfield
text1.tag = 1
text2.tag = 2
text3.tag = 3
text4.tag = 4
text5.tag = 5
text6.tag = 6
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
let nextTag: NSInteger = textField.tag + 1;
if let nextResponder: UIResponder! = textField.superview!.viewWithTag(nextTag){
nextResponder.becomeFirstResponder()
}
else {
textField.resignFirstResponder()
}
return false
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destination = segue.destinationViewController as! secondView
if segue.identifier == segueID {
//Adds the textfield entries to the string array on the second view controller
destination.stringArray = view.subviews.flatMap { ($0 as? UITextField)?.text }
destination.delegate = self
}
}
But I have no idea what is wrong with my code, why would it send the incorrect order to my array. My array looks like this:
["q", "w", "e", "t", "y", "r"]
when it should be...
["q", "w", "e", "r", "t", "y"]
This is just random letters I chose, the entries could be anything really. But the order is important. Could someone check my code, see where did I go wrong? Thank you in advance.

You need to sort the UITextField(s) you are retrieving
So replace this
destination.stringArray = view.subviews.flatMap { ($0 as? UITextField)?.text }
with this
destination.stringArray = view
.subviews
.flatMap { $0 as? UITextField }
.sort { $0.0.tag < $0.1.tag }
.flatMap { $0.text }

Alternatively, go from the tag to the field instead of the field to the tag:
destination.stringArray = (1...6).flatMap({ (view.viewWithTag($0) as? UITextField).text})

Related

Random data transfer to button in Swift. (Array)

import UIKit
class ViewController: UIViewController {
var buttonArray = [String] ()
#IBOutlet weak var button3: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button1: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
buttonArray.append("answer1")
buttonArray.append("answer2")
buttonArray.append("answer3")
}
#IBAction func buttonClick(_ sender: UIButton) {
while true {
let randomArray = buttonArray[Int.random(in: 0...2)]
button1.titleLabel?.text = randomArray
break
}
}
}
I want to create a test. This test will have 3 answer choices and these answers will be randomly assigned to the buttons. I don't want an answer to be assigned to two choices. for this, I want to take the first assigned option into the array and remove it from the array after it is assigned. i don't understand how i can do this
You can remove an item at a random index. This item is returned from remove(at:
let randomElement = buttonArray.remove(at: Int.random(in: 0..<buttonArray.count)]
button1.titleLabel?.text = randomElement
Side note: Never hard-code array indices for a range.
To assign all three values randomly to the three buttons shuffle the array
let shuffledArray = buttonArray.shuffled()
button1.titleLabel?.text = shuffledArray[0]
button2.titleLabel?.text = shuffledArray[1]
button3.titleLabel?.text = shuffledArray[2]

Trying to append firebase string values to collection view

I am attempting to add Firebase string values to a collection view but it is giving me an error on the cell.statsLabel.text = statData[indexPath.row] -> Thread 1: EXC_BREAKPOINT (code=1, subcode=0x101ed3b50). My Firebase is correct (I've added values to a label) the problem is appending. It doesn't even go through the retrieveUserData function! The image link below is what my collection view should look like with the left labels being the statHeader array and the right labels being the statData array -> The collectionview image. Any Ideas?
class SceneTwoViewController: UIViewController, GADRewardBasedVideoAdDelegate, UIAlertViewDelegate, UICollectionViewDelegate, UICollectionViewDataSource {
var statHeaders:[String] = []
var statData:[String] = []
var ref: FIRDatabaseReference?
var databaseHandle: FIRDatabaseHandle?
var streakCheck = ""
#IBOutlet var statsCollectionView: UICollectionView!
#IBOutlet var entireView: UIView!
#IBOutlet var activityIndicator: UIActivityIndicatorView!
#IBOutlet var ovImage: UIImageView!
#IBOutlet var Watchbtn: UIButton!
#IBOutlet var StreakImage: UIImageView!
#IBOutlet var StatusLabel: UILabel!
#IBOutlet var TimeDisplay: UIImageView!
#IBOutlet var statusCheck: UILabel!
#IBOutlet var nameLabel: UILabel!
func retrieveUserData() {
let user = FIRAuth.auth()?.currentUser?.uid
ref?.child("users").child(user!).observeSingleEvent(of: .value, with: { snapshot in
print("Dan2")
let value = snapshot.value as? NSDictionary
let statret = value?["status"] as? String ?? ""
let streakret = value?["streakNumber"] as? String ?? ""
let placesret = value?["placesHelped"] as? String ?? ""
self.statData.append(statret)
self.statData.append(streakret)
self.statData.append(placesret)
})
}
override func viewDidLoad() {
super.viewDidLoad()
self.ref = FIRDatabase.database().reference()
let user = FIRAuth.auth()?.currentUser?.uid
print("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW")
retrieveUserData()
statHeaders.append("Status: ")
statHeaders.append("Streak: ")
statHeaders.append("Places Helped: ")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return statHeaders.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "statsCell", for: indexPath) as! statsCollectionViewCell //statsCollectionViewCell is name of external file with labels
print(statData.count) // prints 0
print(statHeaders.count) // prints 3
cell.headerLabel.text = statHeaders[indexPath.row]
cell.statsLabel.text = statData[indexPath.row]
return cell
}
}
You are using statHeaders array as a data source for your collection and in the method cellForItemAt you are trying to retrieve objects from that array and from the statData at the same indexPath while your statData is empty. That's why it cause that error.
If your collection mostly depends on statData not on statHeaders, then you should use statData as a datasource.
Also, in your case is very important to check that both arrays have same count of objects, or use optionals like if statHeaders is the main array and the collection should depend on its values, but the statDate is not important, then don't use statData if it doesn't has an object at current indexPath:
if statData.count > indexPath.row {
//use statData array only in this case
}
Also, I don't see that you are trying to reload your collection after retrieving the data.
I think that you should add that reload if your data retrieving works asynchronously:
ref?.child("users").child(user!).observeSingleEvent(of: .value, with: { snapshot in
print("Dan2")
let value = snapshot.value as? NSDictionary
let statret = value?["status"] as? String ?? ""
let streakret = value?["streakNumber"] as? String ?? ""
let placesret = value?["placesHelped"] as? String ?? ""
self.statData.append(statret)
self.statData.append(streakret)
self.statData.append(placesret)
self.statsCollectionView.reloadData()
})

unable to random pick a element for the array Swift

#IBOutlet weak var enterName: UITextField!
#IBOutlet weak var presentName: UITextView!
#IBOutlet weak var independceStatue: UITextField!
#IBOutlet weak var driverSelection: UITextField!
var entity : [Entity] = []
var nameList : [String] = []
var period1 = ""
var counting = 0
override func viewDidLoad() {
super.viewDidLoad()
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let request = NSFetchRequest(entityName: "Entity")
var results : [AnyObject]?
do{
results = try context.executeFetchRequest(request)
} catch {
results = nil
}
if results != nil {
self.entity = results as! [Entity]
}
if !entity.isEmpty{
presentName.text = entity.last?.period1Core
}
}
func setValues() {
nameList = [enterName.text!]
}
#IBAction func setName(sender: UIButton) {
setValues()
for item in nameList{
period1 += (item + " ")
}
presentName.text = period1
enterName.text = ""
}
#IBAction func start(sender: UIButton) {
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let entity = NSEntityDescription.insertNewObjectForEntityForName("Entity", inManagedObjectContext: context) as! Entity
entity.period1Core = presentName.text
do {
try context.save()
print("Item Saved")
} catch _ {
print("Saved Failed")
}
**Problem ->** let randomIndex = Int(arc4random_uniform(UInt32(nameList.count)))
driverSelection.text! = nameList[randomIndex]
print(randomIndex)
}
I was trying to randomly pick an element out from the array name nameList, but when I run the program and print the randomIndex, after first time I press the button it will always return last element in the array.
If I exit the simulator and run it again, when I press the button it will return me fatal error Array Index is out of range. Is there somethings wrong with my code, why am I not able to make it randomly select an element from my array?
Your setValues() function always replaces the entire array with the last name entered. That's why it seems to return the last value.
you probably meant to use nameList.append(enterName.text!) in it.
The crash upon starting may occur because nameList has not yet received a name and arc4random_uniform is being called with a parameter value of zero

How to put an array in alphabetical order for UIPickerView in Swift

So I have an array made of strings, and when the user presses on my textfield, it shows a PickerView using the array.
I would like the PickerView to show the contents of the array in alphabetical order. But I have no idea how to do this, and cannot find anywhere online how to do it in Swift. Can someone please help?
Thanks in advance!
MY CODE:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, UIPickerViewDataSource, UIPickerViewDelegate {
#IBOutlet var questionLabel: UILabel!
#IBOutlet var buttonLabel: UIButton!
#IBOutlet var myBackgroundView: UIImageView!
#IBOutlet var questionTextField: UITextField!
let questions = ["Where are you going?", "Which city?", "When do you go?"]
var currentQuestionIndex = 0
let placeholder = ["Country", "City", "Date"]
var currentPlaceholderIndex = 0
#IBAction func nextButton(sender: AnyObject) {
// Initial setup on button press
questionTextField.hidden = false
barImage.hidden = false
// Reset text field to have no text
questionTextField.text = ""
// Displays the questions in array and displays the placeholder text in the textfield
if currentQuestionIndex <= questions.count && currentPlaceholderIndex <= placeholder.count {
questionLabel.text = questions[currentQuestionIndex]
questionTextField.placeholder = placeholder[currentPlaceholderIndex]
currentQuestionIndex++
currentPlaceholderIndex++
buttonLabel.setTitle("Next", forState: UIControlState.Normal)
// Animate text for questionLabel
UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.5, options: nil, animations: {
self.questionLabel.center = CGPoint(x: -110 , y: 305 + 20)
}, completion: nil)
} else {
performSegueWithIdentifier("countdownSegue", sender: self)
//Add some logic here to run whenever the user has answered all the questions.
}
}
var countryPicker = ["France", "Germany", "Spain", "Northern Ireland", "Austria"]
var sortedArray = sorted(countryPicker)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
// Hides the text field
questionTextField.hidden = true
questionTextField.delegate = self
// Sets the button text
buttonLabel.setTitle("Get started", forState: UIControlState.Normal)
// Sets the question text to be blank
questionLabel.text = ""
// Sets placeholder text in the text field
questionTextField.placeholder = ""
var pickerView = UIPickerView()
pickerView.delegate = self
questionTextField.inputView = pickerView
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return countryPicker.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
return countryPicker[row]
}
func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
questionTextField.text = countryPicker[row]
}
// resigns the keyboard when user presses the return/next key on keyboard
func textFieldShouldReturn(textField: UITextField) -> Bool {
questionTextField.resignFirstResponder()
return true
}
// Resigns the keyboard if the user presses anywhere on the screen
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
self.view.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Sort the array, or create a sorted version of the array, and then use that sorted array as the source for your picker view.
let array = ["orange", "grape", "apple", "pear", "mango"]
let sortedArray = sorted(array)
you would then use sortedArray in the data source for your picker view.
I managed to get was i was looking for with this:
countryPicker.sort(){$0 < $1}
It sorted the array from A-Z, and was the only way it worked for me.

SWIFT - UIimagepicker to assign image into an array

Basically I would like my Imagepicker to be able to assign the captured a image to a new row in tableview each time the user input a name and select a image for this name. I encounter at least 2 types of errors for below codes:
1) 'UIImageView' is not a subtype of 'NSString' error being displayed besides "cell.itemImage.image = UIImage(named: selectedImageArray[indexPath.row])"
2) a problem of how to access for example '.contentMode' and '.clipsToBounds' properties of the assigned image (being each in the array to be assigned to the tableview)
Appreciate anyone's help on these~~
Tableview Controller:
import UIKit
class AddPostItemTableViewController: UITableViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate, UITableViewDelegate {
#IBOutlet var titleName: UILabel!
#IBOutlet var tapCamera: UIImageView!
#IBOutlet var tapLibrary: UIImageView!
#IBOutlet weak var itemNameField:UITextField!
#IBOutlet weak var AddPostTableView:UITableView!
var selectedImageArray:[UIImageView!] = []
var selectedItemNameArray:[String!] = []
let tapCameraRec = UITapGestureRecognizer()
let tapLibraryRec = UITapGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
tapCameraRec.addTarget(self, action: "tappedCamera")
tapLibraryRec.addTarget(self, action: "tappedLibrary")
tapCamera.addGestureRecognizer(tapCameraRec)
tapLibrary.addGestureRecognizer(tapLibraryRec)
tapLibrary.userInteractionEnabled = true
tapCamera.userInteractionEnabled = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
// Dismiss keyboard on touch
}
func tappedLibrary(){
if itemNameField.text == "" {
let alertController = UIAlertController(title: "Oops", message: "Please key in the name of item first", preferredStyle: .Alert)
let doneAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(doneAction)
self.presentViewController(alertController, animated: true, completion: nil)
return
}
else if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.sourceType = .PhotoLibrary
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func tappedCamera(){
if itemNameField.text == "" {
let alertController = UIAlertController(title: "Oops", message: "Please key in the name of item first", preferredStyle: .Alert)
let doneAction = UIAlertAction(title: "OK", style: .Default, handler: nil)
alertController.addAction(doneAction)
self.presentViewController(alertController, animated: true, completion: nil)
return
}
else if UIImagePickerController.isSourceTypeAvailable(.PhotoLibrary) {
let imagePicker = UIImagePickerController()
imagePicker.allowsEditing = true
imagePicker.delegate = self
imagePicker.sourceType = .Camera
self.presentViewController(imagePicker, animated: true, completion: nil)
}
}
func imagePickerController(picker: UIImagePickerController!, didFinishPickingImage image:UIImageView!, editingInfo: [NSObject : AnyObject]!) {
selectedImageArray.append(image)
selectedImageArray.contentMode = UIViewContentMode.ScaleAspectFill
selectedImageArray.clipsToBounds = true
selectedItemNameArray.append(itemNameField!.text)
dismissViewControllerAnimated(true, completion: nil)
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
// Return the number of rows in the section.
return self.selectedItemNameArray.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath:
NSIndexPath) -> UITableViewCell {
let cellIdentifier = "ItemCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath:
indexPath) as AddPostTableViewCell
// Configure the cell...
cell.itemName.text = selectedItemNameArray[indexPath.row]
cell.itemImage.image = UIImage(named: selectedImageArray[indexPath.row])
return cell
}
Tableview Cell:
import UIKit
class AddPostTableViewCell: UITableViewCell {
#IBOutlet weak var itemName:UILabel!
#IBOutlet weak var itemImage:UIImageView!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
The first error suggests that your array contains UIImageViews, not names of images. The UIImage(imageNamed: ) accepts name of image as a string. You probably need something like
cell.itemImage.image = selectedImageArray[indexPath.row].image
or if you want to use the UIImage(imageNamed:), use your name array instead.
With regards to the second issue, you can put a dot after the [indexPath.row] to access properties of the stored object at the given index like I did above. Or you can do it in a more readable way:
var myImage = selectedImageArray[indexPath.row]
myImage.someProperty

Resources