Array element checking in swift - ios

Currently implementing a favourite function to my application which is based on quotes. I would like to perform a check for if the user has already saved an element to an array. If they have, I would change a favour button to unfavour button.
import UIKit
class DreamViewController: UIViewController {
#IBOutlet var liketext: UIButton!
#IBOutlet var QuoteImage: UIImageView!
#IBOutlet weak var DreamLabel: UILabel!
var counter = 1
var factIndex = 0
let dreamFact = Dream()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
DreamLabel.text = dreamFact.dreamArray[factIndex]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func LeftSwipe() {
factIndex--
var number = dreamFact.dreamArray.count - 1
if (factIndex < 0){
self.factIndex = number
}
DreamLabel.text = dreamFact.dreamArray[factIndex]
if counter == 1 {
counter = 36
} else {
self.counter--
}
QuoteImage.image = UIImage(named: "frame\(counter).jpg")
}
#IBAction func RightSwipe() {
factIndex++
if factIndex >= dreamFact.dreamArray.count {
self.factIndex = 0
}
DreamLabel.text = dreamFact.dreamArray[factIndex]
if counter == 36 {
counter = 1
} else {
self.counter++
}
QuoteImage.image = UIImage(named: "frame\(counter).jpg")
}
struct Constants {
static let defaults = NSUserDefaults.standardUserDefaults()
static let fqKey = "FavoriteQuotes"
static let like = "Like"
static let unlike = "Unlike"
}
class DreamViewController {
var favouriteQuotesArray = Constants.defaults.objectForKey(Constants.fqKey) as? [String] ?? [String]() {
didSet {
Constants.defaults.setObject(favouriteQuotesArray, forKey: Constants.fqKey)
}
}
#IBOutlet weak var likeButton: UIButton! {
didSet {
let favourite = dreamArray[factIndex]
if let foundIndex = find(favouriteQuotesArray, favourite) {
likeButton.setTitle(Constants.unlike, forState: .Normal)
}
else {
likeButton.setTitle(Constants.like, forState: .Normal)
}
}
}
#IBAction func likeButtonClicked(sender: UIButton) {
}
}
}
The dependency on upon the text which is unreliable because if the user reopens the app, the element would still be saved instead of starting out with the default unlike. If the element is found in the array. How would I perform a search inside my favouriteQuotesArray if the element exists like:
if elementfound statement {
button.settitle(unlike)
removearrayatindex statement.
} else {
button.settitle(like)
makeQuoteFavourite()
}
How would the array checking statement look like?
P.S If you can please give tips on building the delete class?
Update:
var favouriteQuotesArray: [String] = NSUserDefaults.standardUserDefaults().objectForKey("thekey") as! [String]
func makeQuoteFavourite() {
if favouriteQuotesArray == nil {
favouriteQuotesArray = []
}
let currentQuote = dreamFact.dreamArray[factIndex]
favouriteQuotesArray.append(currentQuote)
NSUserDefaults.standardUserDefaults().setObject(favouriteQuotesArray, forKey: "thekey")
}
#IBAction func likeButton() {
if contains(favouriteQuotesArray, dreamFact.dreamArray[factIndex]) {
liketext.setTitle("Unlike", forState: UIControlState.Normal)
}

Do it this way; some cleaner coding techniques to cut through the rubble included.
The declaration of favouriteQuotesArray is a gold star one liner. Got it all?
import UIKit
struct Constants {
static let defaults = NSUserDefaults.standardUserDefaults()
static let fqKey = "FavoriteQuotes"
static let like = "Like"
static let unlike = "Unlike"
}
class Page2ViewController: UIViewController {
var dreamArray = [String]() // place holder so class compiles
var factIndex = 0 // place holder so class compiles
var favouriteQuotesArray = Constants.defaults.objectForKey(Constants.fqKey) as? [String] ?? [String]() {
didSet {
Constants.defaults.setObject(favouriteQuotesArray, forKey: Constants.fqKey)
}
}
#IBOutlet weak var likeButton: UIButton! {
didSet {
let favourite = dreamArray[factIndex]
if let foundIndex = find(favouriteQuotesArray, favourite) {
likeButton.setTitle(Constants.unlike, forState: .Normal)
}
else {
likeButton.setTitle(Constants.like, forState: .Normal)
}
}
}
#IBAction func likeButtonClicked(sender: UIButton) {
let favourite = dreamArray[factIndex]
if let foundIndex = find(favouriteQuotesArray, favourite) {
sender.setTitle(Constants.like, forState: .Normal)
favouriteQuotesArray.removeAtIndex(foundIndex)
}
else {
sender.setTitle(Constants.unlike, forState: .Normal)
favouriteQuotesArray.append(favourite)
}
}
}

Try this:
let currentQuote = dreamFact.dreamArray[factIndex]
if find(favouriteQuotesArray!, currentQuote) != nil {
//Do something
}

The better and quick way to find out an element in an array is:
if contains(yourFavArray, stringStatement){
//Contains you can write your logic
}
Change your favouriteArray as below:
var favouriteQuotesArray: [String] = NSUserDefaults.standardUserDefaults().objectForKey("thekey") as! [String]
Edited:
if let foundIndex = find(favouriteQuotesArray, dreamFact.dreamArray[factIndex]) {
sender.setTitle(Constants.like, forState: .Normal)
favouriteQuotesArray.removeAtIndex(foundIndex)
}

Related

dropdown array becomes empty for few cells after adding cells in tableview and scroll up

Initially when I tap of hierarchy button and parentLocationLevelTwoBtnAction at that time parentLocationNameArr is not empty but after adding few more cells and I scroll up parentLocationNameArr is empty
import UIKit
import DropDown
import ObjectMapper
//Stock Btn Cell Delegate
protocol AddStorageLocationMasterBtnCellDelegate : AnyObject {
func didPressButton(_ tag: Int)
func didPressHierachyButton(_ tag: Int)
func didPressHierachytext(_ tag: Int,sender:String)
func didPressParenttext(_ tag: Int,sender:String, id:String)
func didPressParentTwotext(_ tag: Int,sender:String, id:String)
}
class AddStorageLocationMasterTVCell: UITableViewCell {
#IBOutlet var parentLTextLHeight: NSLayoutConstraint!
#IBOutlet weak var bgView: UIView!
#IBOutlet weak var deleteBtn: UIButton!
#IBOutlet weak var storageLocationNameView: UIView!
#IBOutlet var warnDescriptionbtn: UIButton!
#IBOutlet weak var storageLocationNameTF: UITextField!
#IBOutlet var warnNamebtn: UIButton!
#IBOutlet weak var descriptionView: UIView!
#IBOutlet weak var descriptionTextView: UITextView!
#IBOutlet weak var hierachyView: UIView!
#IBOutlet weak var hierachyTF: UITextField!
#IBOutlet weak var hierachyBtn: UIButton!
#IBOutlet weak var parentLocationView: UIView!
#IBOutlet weak var parentLocationTF: UITextField!
#IBOutlet weak var parentBgView: UIView!
#IBOutlet weak var parentHeightConstant: NSLayoutConstraint!
#IBOutlet weak var parentLocationLevelOneBtn: UIButton!
#IBOutlet weak var parentLocationLevelTwoView: UIView!
#IBOutlet weak var parentLocationLevelTwoTF: UITextField!
#IBOutlet weak var parentLocationTextLabel: UILabel!
#IBOutlet weak var stackView: UIStackView!
#IBOutlet weak var stackViewHeight: NSLayoutConstraint!
#IBOutlet weak var parentLcationLabel: UILabel!
var cellDelegate: AddStorageLocationMasterBtnCellDelegate?
let dropDown = DropDown() //2
var selectedId = 0
var accountID = ""
var storageLocationArr = NSMutableArray()
var storageLocationLevelThreeArr = NSMutableArray()
var serviceVC = ServiceController()
var parentLocationDict = [String]()
var parentLocationId = [String]()
var parentLocationArr = [NSArray]()
var parentLocationNameArr = [String]()
var parentLocationNameIdsArr = [String]()
var parentLocationDetailsDict = NSMutableArray()
var parentLocationNameLevethreeArr = [String]()
var parentLocationNameLevethreeIdsArr = [String]()
var parentLocationDetailsLevethreeDict = NSMutableArray()
var levelValue = 0
var idLevelThree = ""
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
self.parentBgView.isHidden = true
self.parentHeightConstant.constant = 0
storageLocationNameView.layer.borderColor = UIColor.gray.cgColor
storageLocationNameView.layer.borderWidth = 0.5
storageLocationNameView.layer.cornerRadius = 3
storageLocationNameView.clipsToBounds = true
descriptionView.layer.borderColor = UIColor.gray.cgColor
descriptionView.layer.borderWidth = 0.5
descriptionView.layer.cornerRadius = 3
descriptionView.clipsToBounds = true
hierachyView.layer.borderColor = UIColor.gray.cgColor
hierachyView.layer.borderWidth = 0.5
hierachyView.layer.cornerRadius = 3
hierachyView.clipsToBounds = true
parentLocationView.layer.borderColor = UIColor.gray.cgColor
parentLocationView.layer.borderWidth = 0.5
parentLocationView.layer.cornerRadius = 3
parentLocationView.clipsToBounds = true
parentLocationLevelTwoView.layer.borderColor = UIColor.gray.cgColor
parentLocationLevelTwoView.layer.borderWidth = 0.5
parentLocationLevelTwoView.layer.cornerRadius = 3
parentLocationLevelTwoView.clipsToBounds = true
bgView.backgroundColor = .white
bgView.layer.cornerRadius = 5.0
bgView.layer.shadowColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
bgView.layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
bgView.layer.shadowRadius = 6.0
bgView.layer.shadowOpacity = 0.7
hierachyTF.text = "Level 1"
selectedId = 1
}
#IBOutlet var parentButton: UIButton!
// override func setSelected(_ selected: Bool, animated: Bool) {
// super.setSelected(selected, animated: animated)
//
// // Configure the view for the selected state
// }
#IBAction func deleteBtnAction(_ sender: UIButton) {
cellDelegate?.didPressButton(sender.tag)
}
var tagVal=Int()
#IBAction func hierachyBtnAction(_ sender: UIButton) {
let selectedTagHierachy = sender.tag
cellDelegate?.didPressHierachyButton(selectedTagHierachy)
dropDown.dataSource = ["Level 1","Level 2","Level 3"]//4
dropDown.anchorView = sender //5
dropDown.bottomOffset = CGPoint(x: 0, y: sender.frame.size.height) //6
dropDown.show() //7
dropDown.selectionAction = { (index: Int, item: String) in //8
// guard let _ = self else { return }
// sender.setTitle(item, for: .normal) //9
self.selectedId = index
self.hierachyTF.text = item
self.cellDelegate?.didPressHierachytext(selectedTagHierachy, sender: item)
print(self.levelValue)
if index == 0 {
self.parentBgView.isHidden = true
self.parentHeightConstant.constant = 0
}
else if index == 1{
self.levelValue = index+1
self.get_StorageLocationMaster_API_Call(level: index+1, tag: selectedTagHierachy)
self.parentBgView.isHidden = false
self.parentHeightConstant.constant = 120
self.parentLcationLabel.text = "Parent Location L1"
self.parentLocationLevelTwoView.isHidden = true
}
else if index == 2{
self.levelValue = index+1
self.get_StorageLocationMaster_API_Call(level: index+1, tag: selectedTagHierachy)
self.parentBgView.isHidden = false
self.parentHeightConstant.constant = 120
self.parentLcationLabel.text = "Parent Location L2 and L1"
self.parentLocationLevelTwoView.isHidden = false
}
}
}
#IBAction func parentLocationBtnAction(_ sender: UIButton) {
let selectedTagParentLocation = sender.tag
// cellDelegate?.didPressParenttext(<#T##tag: Int##Int#>, sender: sender, id: <#T##String#>)
dropDown.dataSource = parentLocationNameLevethreeArr//4
dropDown.anchorView = sender //5
dropDown.bottomOffset = CGPoint(x: 0, y: sender.frame.size.height) //6
dropDown.show() //7
dropDown.selectionAction = { (index: Int, item: String) in //8
// guard let _ = self else { return }
// sender.setTitle(item, for: .normal) //9
self.parentLocationLevelTwoTF.text = item
self.cellDelegate?.didPressParentTwotext(selectedTagParentLocation, sender: item, id:self.parentLocationNameLevethreeIdsArr[index] )
}
}
#IBAction func parentLocationLevelTwoBtnAction(_ sender: UIButton)
{
let selectedTagParentLocation = sender.tag
dropDown.dataSource = parentLocationNameArr//4
dropDown.anchorView = sender //5
dropDown.bottomOffset = CGPoint(x: 0, y: sender.frame.size.height) //6
dropDown.show() //7
dropDown.selectionAction = { (index: Int, item: String) in //8
// guard let _ = self else { return }
// sender.setTitle(item, for: .normal) //9
// if self?.parentLocationNameLevethreeArr.count ?? 0>0
// {
// self?.parentLocationLevelTwoTF.text = self?.parentLocationNameLevethreeArr[0]
// self?.cellDelegate?.didPressParentTwotext(sender.tag, sender: self?.parentLocationNameLevethreeArr[0] ?? "", id: self?.parentLocationNameLevethreeIdsArr[0] ?? "")
// }
self.parentLocationTF.text = item
self.idLevelThree = self.parentLocationNameIdsArr[index]
self.cellDelegate?.didPressParenttext(selectedTagParentLocation, sender: item, id: self.parentLocationNameIdsArr[index] )
print(self.levelValue)
if self.levelValue==3
{
self.get_StorageLocationByParentLocation_API_Call(level: 2, tag: selectedTagParentLocation)
}
}
}
// MARK: Get Storage Location Master API Call
func get_StorageLocationByParentLocation_API_Call(level:Int,tag:Int) {
let defaults = UserDefaults.standard
accountID = (defaults.string(forKey: "accountId") ?? "")
// let newString = parentLocation.replacingOccurrences(of: " ", with: "%20")
if idLevelThree != ""
{
let urlStr = Constants.BaseUrl + getAllStorageLocationByParentUrl + "\(2)/" + "\(idLevelThree)/" + accountID
serviceVC.requestGETURL(strURL: urlStr, success: {(result) in
let respVo:GetStorageLocationMasterRespVo = Mapper().map(JSON: result as! [String : Any])!
DispatchQueue.main.async { [self] in
let status = respVo.STATUS_CODE
let message = respVo.STATUS_MSG
if status == 200 {
if message == "SUCCESS" {
if respVo.result != nil {
if respVo.result!.count > 0 {
let resultObj:[String:Any]=result as? [String:Any] ?? [String:Any]()
let resultArr:NSMutableArray=resultObj["result"]as? NSMutableArray ?? NSMutableArray()
self.storageLocationLevelThreeArr = NSMutableArray()
self.storageLocationLevelThreeArr = resultArr
self.parentLocationNameLevethreeArr.removeAll()
self.parentLocationNameLevethreeIdsArr.removeAll()
for obj in self.storageLocationLevelThreeArr {
let sDict=obj as? NSDictionary
let isCanEd:Bool = sDict?.value(forKey: "canEdit") as? Bool ?? false
// sDict(sDict?[i] as AnyObject).value(forKey: "canEdit") as? Bool
if isCanEd == true {
let slocName = sDict?.value(forKey: "slocName") as? String ?? ""
let idsStr = sDict?.value(forKey: "_id") as? String ?? ""
self.parentLocationNameLevethreeIdsArr.append(idsStr)
self.parentLocationNameLevethreeArr.append(slocName)
print("level 2 : \(parentLocationNameLevethreeArr)")
}
}
if self.parentLocationNameLevethreeArr.count > 0 {
self.parentLocationLevelTwoTF.text = self.parentLocationNameLevethreeArr[0]
self.cellDelegate?.didPressParentTwotext(tag, sender: self.parentLocationNameLevethreeArr[0], id: self.parentLocationNameLevethreeIdsArr[0])
}
// else{
// self.parentLocationLevelTwoTF.text = ""
// }
self.parentLTextLHeight.constant=0
self.parentLocationTextLabel.isHidden=true
self.parentLocationTextLabel.text=""
}
else {
self.parentLTextLHeight.constant=40
self.parentLocationTextLabel.isHidden=false
self.parentLocationTextLabel.text="No parent storage location is created currently. Pls create a parent storage location before creating the storage location when use creates a storage location without a custom parent storage location"
self.parentLocationTextLabel.numberOfLines = 0
self.parentLocationTextLabel.lineBreakMode = .byWordWrapping
self.parentLocationLevelTwoTF.text = ""
self.parentLocationNameLevethreeArr=[String]()
self.parentLocationNameLevethreeIdsArr=[String]()
}
}
}
}
else {
// self.view.makeToast(message)
}
}
}) { (error) in
// self.view.makeToast("app.SomethingWentToWrongAlert".localize())
print("Oops, your connection seems off... Please try again later")
}
}
else
{
self.parentLTextLHeight.constant=40
self.parentLocationTextLabel.isHidden=false
self.parentLocationTextLabel.text="No level 2 storage location exists currently. Pls create a level 2 storage location before creating levele 3 storage location"
}
}
// MARK: Get AddressBook API Call
func get_StorageLocationMaster_API_Call(level:Int,tag:Int) {
let defaults = UserDefaults.standard
accountID = (defaults.string(forKey: "accountId") ?? "")
let urlStr = Constants.BaseUrl + getAllStorageLocationByHierachyLevelUrl + "\(1)/" + accountID
serviceVC.requestGETURL(strURL: urlStr, success: {(result) in
let respVo:GetStorageLocationMasterRespVo = Mapper().map(JSON: result as! [String : Any])!
DispatchQueue.main.async {
let status = respVo.STATUS_CODE
let message = respVo.STATUS_MSG
if status == 200 {
if message == "SUCCESS" {
if respVo.result != nil {
if respVo.result!.count > 0 {
let resultObj:[String:Any]=result as? [String:Any] ?? [String:Any]()
let resultArr:NSMutableArray=resultObj["result"]as? NSMutableArray ?? NSMutableArray()
print(resultArr)
self.storageLocationArr = NSMutableArray()
self.storageLocationArr = resultArr
if self.storageLocationArr.count==0
{
self.parentLTextLHeight.constant=40
self.parentLocationTextLabel.isHidden=false
}
else
{
self.parentLTextLHeight.constant=0
self.parentLocationTextLabel.isHidden=true
let ddict=self.storageLocationArr[0] as? NSDictionary
self.parentLocationNameArr = [String]()
self.parentLocationNameIdsArr = [String]()
for obj in self.storageLocationArr {
let sDict=obj as? NSDictionary
let isCanEd:Bool = sDict?.value(forKey: "canEdit") as? Bool ?? false
// sDict(sDict?[i] as AnyObject).value(forKey: "canEdit") as? Bool
if isCanEd == true {
let slocName = sDict?.value(forKey: "slocName") as? String ?? ""
let idsStr = sDict?.value(forKey: "_id") as? String ?? ""
self.parentLocationNameIdsArr.append(idsStr)
self.parentLocationNameArr.append(slocName)
print(self.parentLocationNameArr)
self.parentLocationDetailsDict.addObjects(from: sDict?.value(forKey: "parentLocationDetails") as? NSMutableArray as! [Any])
}
}
let parentLocationDetails=ddict?.value(forKey: "parentLocationDetails")as? NSArray
print(self.levelValue)
if self.levelValue==3
{
if self.parentLocationNameArr.count>0
{
self.idLevelThree = self.parentLocationNameIdsArr[0] ?? ""
self.parentLocationTF.text = self.parentLocationNameArr[0]
self.cellDelegate?.didPressParenttext(tag, sender: self.parentLocationNameArr[0], id: self.parentLocationNameIdsArr[0])
}
else{
self.parentLTextLHeight.constant=40
self.parentLocationTextLabel.isHidden=false
self.parentLocationTextLabel.text="No level 2 storage location exists currently. Pls create a level 2 storage location before creating levele 3 storage location"
}
// if self.parentLocationDetailsDict.count > 0
// {
self.get_StorageLocationByParentLocation_API_Call(level: 2, tag:tag)
print("parent level 2 :\(self.parentLocationNameLevethreeArr)")
// }
}
else
{
if self.parentLocationNameArr.count>0
{
self.parentLocationTF.text = self.parentLocationNameArr[0]
self.cellDelegate?.didPressParenttext(tag, sender: self.parentLocationNameArr[0], id: self.parentLocationNameIdsArr[0])
}
else{
self.parentLTextLHeight.constant=40
self.parentLocationTextLabel.isHidden=false
self.parentLocationTextLabel.text="No level 1 storage location exists currently. Pls create a level 1 storage location before creating levele 3 storage location"
}
}
}
}
else {
}
}
}
}
else {
// self.view.makeToast(message)
}
}
}) { (error) in
// self.view.makeToast("app.SomethingWentToWrongAlert".localize())
print("Oops, your connection seems off... Please try again later")
}
}
}
Thanks in advance🙏

iOS label not start from the top

My controller allows me to show a text from a song inside a label but I don't know why the gravity of the text is focused at the end. When I want to see the text I always see the song like it's already scrolled. I want to start the song from the top and then scroll it or zoom it.
Every time I want to see a song that is longer than the page I see like it's already scrolled, but if I want to see a song that is shorter than the page it works correctly. How can I fix it??
Here is my code:
import UIKit
class DettaglioCanti: UIViewController {
var dettaglioCanzone: VociMontagna? {
didSet {
configureView()
}
}
var valoriPassati: VociMontagna?
#IBOutlet weak var tv_titolo: UILabel!
#IBOutlet weak var tv_artista: UILabel!
#IBOutlet weak var tv_testoCanzone: UITextView!
#IBAction func btt_note(_ sender: Any) {
startPopUp()
}
#IBOutlet weak var btt_note_2: UIButton!
var pinchGesture = UIPinchGestureRecognizer()
override func viewDidLoad() {
super.viewDidLoad()
configureView()
pinchGesture = UIPinchGestureRecognizer(target: self, action:#selector(pinchText(sender:)))
tv_testoCanzone.addGestureRecognizer(pinchGesture)
let range = NSMakeRange(tv_testoCanzone.text.count - 1, 0)
tv_testoCanzone.scrollRangeToVisible(range)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#objc func pinchText(sender: UIPinchGestureRecognizer) {
var pointSize = tv_testoCanzone.font?.pointSize
pointSize = ((sender.velocity > 0) ? 1 : -1) * 1 + pointSize!;
//Definisco i limiti dello zoom per il testo
if (pointSize! < 13) {pointSize = 13}
if (pointSize! > 42) {pointSize = 42}
tv_testoCanzone.font = UIFont( name: "arial", size: (pointSize)!)
}
func configureView() {
if let dettaglioCanzone = dettaglioCanzone {
if let tv_titolo = tv_titolo, let tv_testoCanzone = tv_testoCanzone, let tv_artista = tv_artista {
tv_titolo.text = dettaglioCanzone.titolo
tv_artista.text = dettaglioCanzone.artista
tv_testoCanzone.text = loadFile(file: dettaglioCanzone.nomeTesto)
if (dettaglioCanzone.nomeNota == "0") {btt_note_2.isHidden = true}
}
}
}
func loadFile(file name:String) -> String {
if let path = Bundle.main.path(forResource: name, ofType: "txt") {
if let contents = try? String(contentsOfFile: path) {
return contents
} else {
print("Error! - This file doesn't contain any text.")
}
} else {
print("Error! - This file doesn't exist.")
}
return ""
}
}

Swift 4 - Quiz App Random Questions

I'm a beginner to Swift and generally Xcode. Thank you in advance for your time and help :)
I am doing a Quiz App, and I try to have random questions... I have a function to generate random numbers that I tried to apply in viewDidLoad()... unfortunately I can not guess how to use that information in his variable "var currentQuestion = 0"
This is the code:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
generateRandomNumber(0, 9, 10)
}
override func viewDidAppear(_ animated: Bool) {
newQuestion()
}
// Quiz//
let questions = ["Q1","Q2","Q3","Q4","Q5"]
let answers = [["A","2","3"],["B","2","3"],["C","2","3"],["D","2","3"],["E","2","3"]]
//Variables
var currentQuestion = 0
var rightAnswerPlacement:UInt32 = 0
//Generate Random Numbers
func generateRandomNumber(_ from:Int, _ to:Int, _ qut:Int?) -> [Int] {
var myRandomNumbers = [Int]() //All our generated numbers
var numberOfNumbers = qut //How many numbers to generate
let lower = UInt32(from) //Generate from this number..
let higher = UInt32(to+1) //To this one
if numberOfNumbers == nil || numberOfNumbers! > (to-from) + 1 {
numberOfNumbers = (to-from) + 1
}
while myRandomNumbers.count != numberOfNumbers {
let myNumber = arc4random_uniform(higher - lower) + lower
if !myRandomNumbers.contains(Int(myNumber)) {
myRandomNumbers.append(Int(myNumber))
}
}
return myRandomNumbers
}
//Label
#IBOutlet weak var lbl: UILabel!
//Button
#IBAction func action(_ sender: AnyObject) {
if (sender.tag == Int(rightAnswerPlacement)) {
print ("RIGHT!")
} else {
print ("WRONG!!!!!!")
}
if (currentQuestion != questions.count) {
newQuestion()
} else {
}
}
//Function that displays new question
func newQuestion() {
lbl.text = questions[currentQuestion]
rightAnswerPlacement = arc4random_uniform(3)+1
//Create a button
var button:UIButton = UIButton()
var x = 1
for i in 1...3 {
//Create a button
button = view.viewWithTag(i) as! UIButton
if (i == Int(rightAnswerPlacement)) {
button.setTitle(answers[currentQuestion][0], for: .normal)
} else {
button.setTitle(answers[currentQuestion][x], for: .normal)
x = 2
}
}
currentQuestion += 1
}
Any idea that how will be possible to resolve?
First you need to store the array of random questions that you generate (side note you appear to try to generate 10 random numbers but have only 5 questions).
Then instead of using the currentQuestion directly you use that to access the question in the array.
So change it to this:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
questionArray = generateRandomNumber(0, 9, 10)
}
override func viewDidAppear(_ animated: Bool) {
newQuestion()
}
// Quiz//
let questions = ["Q1","Q2","Q3","Q4","Q5"]
let answers = [["A","2","3"],["B","2","3"],["C","2","3"],["D","2","3"],["E","2","3"]]
//Variables
var currentQuestion = 0
var rightAnswerPlacement:UInt32 = 0
var questionArray: [Int] = [] // Just an initial value
//Generate Random Numbers
func generateRandomNumber(_ from:Int, _ to:Int, _ qut:Int?) -> [Int] {
var myRandomNumbers = [Int]() //All our generated numbers
var numberOfNumbers = qut //How many numbers to generate
let lower = UInt32(from) //Generate from this number..
let higher = UInt32(to+1) //To this one
if numberOfNumbers == nil || numberOfNumbers! > (to-from) + 1 {
numberOfNumbers = (to-from) + 1
}
while myRandomNumbers.count != numberOfNumbers {
let myNumber = arc4random_uniform(higher - lower) + lower
if !myRandomNumbers.contains(Int(myNumber)) {
myRandomNumbers.append(Int(myNumber))
}
}
return myRandomNumbers
}
//Label
#IBOutlet weak var lbl: UILabel!
//Button
#IBAction func action(_ sender: AnyObject) {
if (sender.tag == Int(rightAnswerPlacement)) {
print ("RIGHT!")
} else {
print ("WRONG!!!!!!")
}
if (currentQuestion != questions.count) {
newQuestion()
} else {
}
}
//Function that displays new question
func newQuestion() {
lbl.text = questions[questionArray[currentQuestion]]
rightAnswerPlacement = arc4random_uniform(3)+1
//Create a button
var button:UIButton = UIButton()
var x = 1
for i in 1...3 {
//Create a button
button = view.viewWithTag(i) as! UIButton
if (i == Int(rightAnswerPlacement)) {
button.setTitle(answers[questionArray[currentQuestion]][0], for: .normal)
} else {
button.setTitle(answers[questionArray[currentQuestion]][x], for: .normal)
x = 2
}
}
currentQuestion += 1
}
(I think the code is correct but I'm currently running some tests in Xcode so can't check. If there is a problem leave a comment.)

Fatal Error creating Array

This is the code I have. Basically when the user first chooses the quality of the dinning whether it is fine (20%), casual (15%), or a bar (11%). From there the user will then be asked on a 1-5 scale about the food quality, service, etc. Depending what number they choose, for example if the fine dinning was a 5/5 then it will ad 4% to the already 20 percent (each number will have a selected value to add to the tip). Can anyone figure out what's going on? Or if there is a better way about doing it.
import UIKit
#IBDesignable
class ViewController: UIViewController {
#IBOutlet weak var billTotal: UITextField!
var diningValue: Double = 0.0
#IBAction func toggleFineDining(sender: UIButton) {
sender.highlighted = sender.selected
if sender.selected == true{
diningValue = 0.20
}
}
#IBAction func toggleCasualDining(sender: UIButton) {
sender.highlighted = sender.selected
if sender.selected == true{
diningValue = 0.15
}
}
#IBAction func toggleBartender(sender: UIButton) {
sender.highlighted = sender.selected
if sender.selected == true{
diningValue = 0.11
}
}
#IBOutlet weak var service: UITextField!
#IBOutlet weak var friendliness: UITextField!
#IBOutlet weak var foodQuality: UITextField!
#IBOutlet weak var atmosphere: UITextField!
#IBOutlet weak var overall: UITextField!
#IBOutlet weak var recommend: UISwitch!
#IBOutlet weak var total: UILabel!
func totalBill(inputArray: [Double], value: Double, recommend: Bool)->Double{
var array: [Double] = []
let total = inputArray[0]
for var i = 1; i < inputArray.count; ++i {
array.append(inputArray[i] * 0.01)
}
let sum = array.reduce(0, combine: +)
var totalTip = Double()
if recommend == true{
totalTip = sum + value
} else {
if sum < 0.15 {
totalTip = 0.15
} else {
totalTip = sum + value
}
}
let tipValue = totalTip * total
return total + tipValue
}
#IBAction func calcTotal(sender: AnyObject) {
var valueList = [String(service.text), String(friendliness.text), String(foodQuality.text), String(atmosphere.text), String(overall.text)]
let list = doubleArray(valueList)
print(list)
let initialTotal = Double(billTotal.text!)
let total_bill = totalBill(list, value: diningValue, recommend: recommend.selected)
print("Total: ", total_bill)
print(String(format: "%.3f", Double(total_bill)))
total.text = "$" + String(format: "%.2f", Double(total_bill))
//diningValue = diningValue
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
func doubleArray(list: [String])->[Double]{
var doubledList: [Double] = []
for element in 0...list.count{
let doubledElement = Double(list[element])
doubledList.append(doubledElement!)
}
return doubledList
}
Your issue is in the last function:
func doubleArray(list: [String])->[Double]{
var doubledList: [Double] = []
for element in 0...list.count{
let doubledElement = Double(list[element])
doubledList.append(doubledElement!)
}
return doubledList
}
Your loop is looping from 0 to list.count and it crashes at list[element] when element is list.count (Out of Index)
You need to change from 0...list.count to 0..<list.count:
func doubleArray(list: [String])->[Double]{
var doubledList: [Double] = []
for element in 0..<list.count{
let doubledElement = Double(list[element])
doubledList.append(doubledElement!)
}
return doubledList
}
I would recommend you to do it in swifty way:
func doubleArray(list: [String])->[Double]{
var doubledList: [Double] = []
for element in list {
doubledList.append(Double(element) ?? 0.0)
}
return doubledList
}
A shorter version using map function:
func doubleArray(list: [String])->[Double]{
return list.map( { Double($0) ?? 0.0 })
}

swift accessing variable from another file

I am a newbie swift programmer, and I have been asked to write an app that allows you to type in a word, and then generates a random Haiku
This is a tabbed application, with two ViewControllers.
(poem) based on that word. So in the FirstViewController I have the data, and I want to display that data in a nice way, in the SecondViewController.
I have all the poem lines and all in the FirstViewController, but I would like to access these variables in the SecondViewController. I have tried creating a function, that does nothing but returning them, and then in the SecondViewController calling that function, but without any result, since the function simply returned nil. Would be pleased if any of you could help
Thank you!
Here is the FirstViewController:
import UIKit
import Foundation
class FirstViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var keyWordTextField: UITextField!
#IBOutlet weak var syllableSlider: UISlider!
#IBOutlet weak var syllableSliderLabel: UILabel!
var syllableSliderValue = 1
#IBOutlet weak var lineOneTextField: UITextField!
#IBOutlet weak var lineTwoTextField: UITextField!
#IBOutlet weak var lineThreeTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
lineOneTextField.text = "Rad 1"
lineTwoTextField.text = "Rad 2"
lineThreeTextField.text = "Rad 3"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func syllableValueChanged(sender: UISlider) {
syllableSliderValue = Int((sender.value))
syllableSliderLabel.text = "Ordet har: \(syllableSliderValue) stavelser"
}
#IBAction func getNewHaiku() {
if keyWordTextField.text != "" {
let keyWord = keyWordTextField.text
let lineOne = generateLine(keyWord: keyWord, syllables: syllableSliderValue, lineSyllableLenght: 5)
let lineTwo = generateLine(keyWord: keyWord, syllables: syllableSliderValue, lineSyllableLenght: 7)
let lineThree = generateLine(keyWord: keyWord, syllables: syllableSliderValue, lineSyllableLenght: 5)
lineOneTextField.text! = lineOne
lineTwoTextField.text! = lineTwo
lineThreeTextField.text! = lineThree
}
}
func generateLine(#keyWord: String, syllables : Int, lineSyllableLenght : Int) -> String {
let oneSyllables = Dict().oneSyllables
let twoSyllables = Dict().twoSyllables
let threeSyllables = Dict().threeSyllables
let fourSyllables = Dict().fourSyllables
let randomOneSyllableWordNumber = Int(arc4random_uniform(UInt32(oneSyllables.count)))
let randomTwoSyllableWordNumber = Int(arc4random_uniform(UInt32(twoSyllables.count)))
let randomThreeSyllableWordNumber = Int(arc4random_uniform(UInt32(threeSyllables.count)))
let randomFourSyllableWordNumber = Int(arc4random_uniform(UInt32(fourSyllables.count)))
var lineArray : [String] = []
var line = ""
lineArray.append(keyWord)
if syllables == 1 {
let randomWordMethod = Int(arc4random_uniform(2))
if randomWordMethod == 0 {
lineArray.append(fourSyllables[randomFourSyllableWordNumber])
} else if randomWordMethod == 1 {
lineArray.append(threeSyllables[randomThreeSyllableWordNumber])
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
} else if randomWordMethod == 2 {
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
lineArray.append(twoSyllables[randomOneSyllableWordNumber])
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
}
} else if syllables == 2 {
let randomWordMethod = Int(arc4random_uniform(2))
if randomWordMethod == 0 {
lineArray.append(twoSyllables[randomOneSyllableWordNumber])
lineArray.append(oneSyllables[randomTwoSyllableWordNumber])
} else if randomWordMethod == 1 {
lineArray.append(threeSyllables[randomThreeSyllableWordNumber])
} else if randomWordMethod == 2 {
lineArray.append(twoSyllables[randomTwoSyllableWordNumber])
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
}
} else if syllables == 3 {
let randomWordMethod = Int(arc4random_uniform(1))
if randomWordMethod == 0 {
lineArray.append(twoSyllables[randomTwoSyllableWordNumber])
} else if randomWordMethod == 1 {
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
}
} else if syllables == 4 {
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
}
if lineSyllableLenght == 7 {
let randomWordMethod = Int(arc4random_uniform(1))
if randomWordMethod == 0 {
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
lineArray.append(oneSyllables[randomOneSyllableWordNumber])
} else if randomWordMethod == 1 {
lineArray.append(twoSyllables[randomTwoSyllableWordNumber])
}
}
for word in lineArray {
line += " \(word)"
}
line += ","
return line
}
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
self.view.endEditing(true)
}
func getData() -> (line2: String, line3: String) {
return (lineTwoTextField.text, lineThreeTextField.text)
}
}
Ps, the "Dict" is another file, but only containing words.
The second view controller is just blank.
Or you could make it a global variable so any file can access it.
struct structname {
static var yourvariable = value
}
When calling it, you enter
filename.structname.yourvariable
You need to pass the instances like this in second view controller:
var firstViewController: FirstViewController?
Then in the master instance which knows both:
secondViewController.firstViewController = firstViewController
(e.g. in awakeFromNib) assuming that they are known in the master instance like
let firstViewController = FirstViewController()
let secondViewController = SecondViewController()
Finally in SecondViewController you can access the first:
firstViewController?.generateLine....

Resources