for my homework assignment I have to convert the sentence the user has typed in 3 different ways.
Convert all letters to uppercase(completed)
Convert all letters to lowercase(completed)
Convert the uppercase letters to lowercase and vice versa(having trouble)
I believe my logic is correct but I don't know where I am wrong.
This is my code:
//
// ViewController.swift
// Lower Upper Converter
//
// Created by Mac User on 9/27/15.
// Copyright © 2015 Omid Nassir. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
private var input = ""
private var i = 0
var sentense = [String]()
//var sentenseChar: [Character] = []
//input fields
#IBOutlet weak var input1: UITextField!
#IBOutlet weak var input2: UITextField!
//caps button
#IBAction func capsBtn(sender: AnyObject)
{
if input1.text != nil
{
input = input1.text!.uppercaseString
input2.text = input
}
else
{
input2.text = ""
}
}
//lower case button
#IBAction func lowsBtn(sender: AnyObject)
{
if input1.text != nil
{
input = input1.text!.lowercaseString
input2.text = input
}
else
{
input2.text = ""
}
}
//word converter button
#IBAction func capsLowsBtn(sender: AnyObject)
{
if input1.text != nil
{
for i=0; i < count(input1.text); i++
{
input = advance(input1.startIndex, i)
str[input]
sentense[i] = advance(input.startIndex, i)
}
}
}//end of convert function
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.
}
}
I am getting an error message:
Cannot invoke 'count' with an argument list of type '(String?)'
for this statement: for i=0; i < count(input1.text); i++
Note! With Swift 2 you have to use a new syntax:
Change your code to:
for var i = 0; i < input1.text!.characters.count; i++
{
...
}
A better way of doing this will be: (Tested in Swift 3.x)
for i in 0 ..< input1.text!.characters.count
{
...
}
Related
My game starts with 8 cards or 4 pairs. Where should I insert the function and write it down correctly so that a new game starts if the win and + 2 pairs are added.
import UIKit
class ViewController: UIViewController,UICollectionViewDelegate,UICollectionViewDataSource {
#IBOutlet weak var timeLabel: UILabel!
#IBOutlet weak var collectionView: UICollectionView!
var firstFlippedCardIndex:IndexPath?
var model = CardModel()
var cardArray = [Card]()
var timer : Timer?
var milliseconds: Float = 60 * 1000 // 30 sec
override func viewDidLoad() {
super.viewDidLoad()
cardArray = model.getCard()
collectionView.delegate = self
collectionView.dataSource = self
timer = Timer.scheduledTimer(timeInterval: 0.001, target: self, selector: #selector(timerElapsed), userInfo: nil, repeats: true)
RunLoop.main.add(timer!, forMode: .common)
}
#objc func timerElapsed(){
milliseconds -= 1
//Conver to seconds
let seconds = String(format:"%.2f", milliseconds/1000)
//set Label
timeLabel.text = "time Remaining: \(seconds)"
//When the timer has reached 0 will stop it
if milliseconds <= 0 {
//Stop the timer
timer?.invalidate()
timeLabel.textColor = UIColor.red
//Check if theere are any cards unmatched
ckeckGameEnded()
}
}
func setupNewGame() {
cardArray = model.getCard()
let addCard = Card()
cardArray.append(addCard)
let indexPath = IndexPath(row: cardArray.count - 22, section: 0)
collectionView.insertItems(at: [indexPath])
collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return cardArray.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CardCollectionViewCell
let card = cardArray[indexPath.row]
// Set that card for the cell
cell.setCard(card)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if milliseconds <= 0 {
return
} // Get the cell that the user selected
let cell = collectionView.cellForItem(at: indexPath) as! CardCollectionViewCell
// Get the card that the user selected
let card = cardArray[indexPath.row]
if card.isFlipped == false && card.isMatched == false {
// Flip the card
cell.flip()
// Set the status of the card
card.isFlipped = true
// Determine if it's the first card or second card that's flipped over
if firstFlippedCardIndex == nil {
// This is the first card being flipped
firstFlippedCardIndex = indexPath
}
else {
// This is the second card being flipped
// Perform the matching logic
checkForMatches(indexPath)
}
}
} // End the didSelectItemAt method
// MARK: - Game Logic Methods
func checkForMatches(_ secondFlippedCardIndex:IndexPath) {
// Get the cells for the two cards that were revealed
let cardOneCell = collectionView.cellForItem(at: firstFlippedCardIndex!) as? CardCollectionViewCell
let cardTwoCell = collectionView.cellForItem(at: secondFlippedCardIndex) as? CardCollectionViewCell
// Get the cards for the two cards that were revealed
let cardOne = cardArray[firstFlippedCardIndex!.row]
let cardTwo = cardArray[secondFlippedCardIndex.row]
// Compare the two cards
if cardOne.imageName == cardTwo.imageName {
// It's a match
// Set the statuses of the cards
cardOne.isMatched = true
cardTwo.isMatched = true
// Remove the cards from the grid
cardOneCell?.remove()
cardTwoCell?.remove()
ckeckGameEnded()
}
else {
// It's not a match
// Set the statuses of the cards
cardOne.isFlipped = false
cardTwo.isFlipped = false
// Flip both cards back
cardOneCell?.flipBack()
cardTwoCell?.flipBack()
}
// Tell the collectionview to reload the cell of the first card if it is nil
if cardOneCell == nil {
collectionView.reloadItems(at: [firstFlippedCardIndex!])
}
// Reset the property that tracks the first card flipped
firstFlippedCardIndex = nil
}
func ckeckGameEnded() {
//Determine if there are any cards unmatched
var isWon = true
for card in cardArray {
if card.isMatched == false {
isWon = false
break
}
}
//Messing variables
var title = ""
var message = ""
//If not, then user has won, stop the timer
if isWon == true {
if milliseconds > 0{
timer?.invalidate()
}
title = "BRAVO !"
message = "You`ve Won"
} else {
//If there are unmatched cards, check if there`s any time left
if milliseconds > 0 {
return
}
title = "Game Over"
message = "You`ve Lost"
}
//Show won/lost messaging
showAlert(title, message)
}
func showAlert(_ title : String, _ message : String){
//Show won/lost messaging
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
let alertAction = UIAlertAction(title: "Ok", style: .default, handler: nil)
alert.addAction(alertAction)
present(alert, animated: true, completion: nil)
}
} // Endging of veiwController class
Here I am creating 4 pairs for the game and then removing the cards if they match.Tell me how to write down the order correctly, maybe rewrite the code somewhere. And can you show an example?
import Foundation
class CardModel {
func getCard() -> [Card] {
//decare an array to store numbers we`ve already generated
var generatedNumbersArray = [Int]()
//randomly generate pairs of cards
var generatedCardArray = [Card]()
while generatedNumbersArray.count < 4 {
//get a random number
let randomNumber = arc4random_uniform(8) + 1
//Ensure that the random number isn`t one we already have
if generatedNumbersArray.contains(Int(randomNumber)) == false {
//log the number
print(randomNumber)
//Store the number into the generatedCardArray
generatedNumbersArray.append(Int(randomNumber))
//create the first card object
let cardOne = Card()
cardOne.imageName = "card\(randomNumber)"
generatedCardArray.append(cardOne)
//create the second card object
let cardTwo = Card()
cardTwo.imageName = "card\(randomNumber)"
generatedCardArray.append(cardTwo)
// make it so we only have unqiu pairs of cards
} else {
}
}
//Randomize the array
for i in 0...generatedCardArray.count-1{
// find a random index to swap with
let randomNumber = Int (arc4random_uniform(UInt32(generatedCardArray.count)))
// swap the two cards
let temporaryStorage = generatedCardArray[i]
generatedCardArray[i] = generatedCardArray[randomNumber]
generatedCardArray[randomNumber] = temporaryStorage
}
//return
return generatedCardArray
}
}
I'm sure this is very simple, but I'm using a button to go to the next item in an array and display it in a label. That much works just fine, however once the end of the array is reached the app crashes since there are no items left to display. How do I get it to go back to the first item? I've tried an If statement but had no luck.
import UIKit
class ViewController: UIViewController {
var firstQuote = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBOutlet weak var quotesLabel: UILabel!
var quotes = ["","Quote 1", "Quote 2", "Quote 3"]
#IBAction func nextButton(_ sender: UIButton) {
firstQuote = firstQuote + 1
quotesLabel.text = quotes[firstQuote]
}
}
This is the If Statement I tried
#IBAction func nextButton(_ sender: UIButton) {
if firstQuote < quotes.count{
firstQuote = firstQuote + 1
quotesLabel.text = quotes[firstQuote]
}
if firstQuote == quotes.count{
firstQuote = 0
quotesLabel.text = quotes[firstQuote]
}
}
A common solution is to use % (the remainder operator) to wrap firstQuote back to 0 when it is equal to quotes.count:
firstQuote = (firstQuote + 1) % quotes.count
This works for me😁
class ViewController: UIViewController {
var quotes = ["Quote 0","Quote 1", "Quote 2", "Quote 3"]
var quotesNum = 0
#IBOutlet weak var result: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
result.text = quotes[quotesNum]
}
#IBAction func incrementButton(_ sender: Any) {
if quotesNum < quotes.count {
quotesNum += 1
if quotesNum == quotes.count {
quotesNum = 0
}
result.text = quotes[quotesNum]
}
}
With This Code Beside Fixing Your Problem, You Can Understand How property observer Can Work
class ViewController: UIViewController {
var quotes = ["Quote 0","Quote 1", "Quote 2", "Quote 3"]
var quotesNum: Int = 0 {
didSet {
result.text = quotes[quotesNum]
}
}
#IBOutlet weak var result: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
result.text = quotes[quotesNum]
}
#IBAction func incrementButton(_ sender: Any) {
if quotesNum < quotes.count - 1 {
if quotesNum == quotes.count - 1 {
quotesNum = 0
} else {
quotesNum += 1
}
} else {
quotesNum = 0
}
}
Greetings dear fans and programmers of the Swift language. I have tried to formulate an algorithm number of times an element shows up within an array with a for loop, but it doesn't seem to be working.
My code is as follows:
else if indexPath.section == 1 {
cell = tableView.dequeueReusableCellWithIdentifier("GreenCell", forIndexPath: indexPath)
for item in theModel.userAnswer {
numOfCoincidences[item] = (numOfCoincidences[item] ?? 0) + 1
}
for (numLangs, value) in numOfCoincidences {
txtSummary = "#languages spoken: \(numLangs)"
txtSummary2 = "# of People: \(value)"
}
cell.textLabel?.text = txtSummary
cell.detailTextLabel?.text = txtSummary2
I am trying to display this information in a table Cell but it is not working. I thought that my algorithm was spot on. Any suggestions?
I'm getting the following output: I have a navigation controller in effect where I input data on one screen and it outputs the data on a table. It's a bit of a survey where I prompt the user to enter their name and the number of languages spoken. I'm using an MVC programming methodology.
so in the model, here is the code:
import Foundation
class Model {
var userName = [String]()
var userAnswer = [String]()
var userInfo = [String]()
var name:String
var answer:String
init(){
self.name = ""
self.answer = ""
}
func addUserInfo(name:String, answer:String) -> Void {
userName.append(name)
userAnswer.append(answer)
}
}
In the input screen, I have 2 text boxes that prompt for username and number of languages spoken. So on the output screen, if 2 people speak 4 languages, the output should reflect that, but it's not. If 1 person speaks 3 languages, it should display that and so on. The output is coming out completely incorrectly. Here is the for the data entry code:
import UIKit
class ViewController: UIViewController {
var model = Model()
#IBOutlet var txtName: UITextField!
#IBOutlet var lblStatus: UILabel!
#IBOutlet var txtAnswer: UITextField!
#IBAction func btnAnswer(sender: UIButton) {
model.answer = txtAnswer.text!
model.name = txtName.text!
if ((txtName.text)! == "" || (txtAnswer.text)! == "") {
lblStatus.text = "Name and answer are both required"
}else if model.userName.contains(model.name) {
lblStatus.text = "Answer already recorded for \(model.name)"
} else {
model.addUserInfo(model.name, answer: model.answer)
lblStatus.text = "Ok, \(model.name) answered \(model.answer)"
}
txtAnswer.text = ""
txtName.text = ""
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toReesultsController" {
let vc = segue.destinationViewController as! TableViewController
vc.theModel = self.model
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
The code for the table to display the data inputted from the data entry screen is presented in a table as shown below:
import UIKit
class TableViewController: UITableViewController {
var theModel = Model()
var numOfCoincidences:[String:Int] = [:]
var txtSummary:String = ""
var txtSummary2:String = ""
var greatest:Int = 0
/* override func viewDidLoad() {
for index in 0..<theModel.userName.count {
}
}*/
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 3
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return theModel.userAnswer.count
} else if section == 1 {
return theModel.userAnswer.count
} else if section == 2{
return theModel.userAnswer.count
} else {
return 0
}
}
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "Answer Log"
} else if section == 1 {
return "Summary"
} else if section == 2 {
return "Top Answers"
} else {
return nil
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell! = nil
if indexPath.section == 0 {
cell = tableView.dequeueReusableCellWithIdentifier("BlueCell", forIndexPath: indexPath)
cell.textLabel?.text = "\(theModel.userName[indexPath.row]):\(theModel.userAnswer[indexPath.row])"
} else if indexPath.section == 1 {
cell = tableView.dequeueReusableCellWithIdentifier("GreenCell", forIndexPath: indexPath)
for item in theModel.userAnswer {
numOfCoincidences[item] = (numOfCoincidences[item] ?? 0) + 1
}
for (numLangs, value) in numOfCoincidences {
txtSummary = "#languages spoken: \(numLangs)"
txtSummary2 = "# of People: \(value)"
}
cell.textLabel?.text = txtSummary
cell.detailTextLabel?.text = txtSummary2
} else if indexPath.section == 2 {
cell = tableView.dequeueReusableCellWithIdentifier("OrangeCell", forIndexPath: indexPath)
greatest = 0
for index in 0..<theModel.userAnswer.count {
if Int(theModel.userAnswer[index])! > greatest {
greatest = Int(theModel.userAnswer[index])!
}
}
cell.textLabel?.text = "Answer with most votes is \(greatest) languages spoken."
}
return cell
}
}
Based on what you have shared, and making some assumptions on your input this seems to do what you want.
If each item is a dictionary with the keys shown below. Then you would walk through the array and get the number of languages spoken by the person. I chose to define that as a number(Int) since that is what it really is.
This is almost the same as your original code so I have to conclude that your idea was correct, but your implementation was missing something.
Assuming this is your input:
let a = [["name":"carla", "langs" : 3], ["name":"scott", "langs" : 3], ["name":"brad", "langs" : 1], ["name":"cynthia", "langs":2]]
var numOfCoincidences = [Int: Int]()
for item in a {
let numLangs = item["langs"] as! Int
numOfCoincidences[numLangs] = (numOfCoincidences[numLangs] ?? 0) + 1
}
var txtSummary = ""
var txtSummary2 = ""
for (numLangs, value) in numOfCoincidences {
// You should also note that you are overwriting values here.
txtSummary = "#languages spoken: \(numLangs)"
txtSummary2 = "# of People: \(value)"
print(txtSummary)
print(txtSummary2)
}
numOfCoincidences
Output:
// key := number of languages spoken
// value := number of people who speak that many languages
[2: 1, 3: 2, 1: 1]
You do have a problem in your cellForRowAtIndexPath.
After you loop through all the data, you do this:
cell.textLabel?.text = txtSummary
cell.detailTextLabel?.text = txtSummary2
Therefore, every cell is going to have the last values from the loop.
I have a tableview in which the first cell is different from all the others (I have two custom cells in the table dequeued With different Identifiers). The codes are as below:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if indexPath.row == 0 {
let cell = tableView.dequeueReusableCellWithIdentifier("profileCell") as! SbProfileViewCell
//cell.textArea.text = bio[indexPath.row]
//pictureFile[indexPath.row].getDataInBackgroundWithBlock { (fileData, error) -> Void in
if let pic = UIImage(data: fileData!) {
cell.imageView.image = pic
}
}
return cell
} else {
let cell = tableView.dequeueReusableCellWithIdentifier("postCell") as! SbPostsTableViewCell
cell.date.text = dateFormatter.stringFromDate(dates[indexPath.row - 1])
pictureFileOne[indexPath.row - 1].getDataInBackgroundWithBlock { (fileOneData, error) -> Void in
if let downloadedImageOne = UIImage(data: fileOneData!) {
cell.imageArea.image = downloadedImageOne
}
}
cell.textArea.text = text[indexPath.row - 1]
return cell
}
}
i'm getting the array out of index error for the commented lines and i'm also uncertain about whether using [indexPath.row - 1] would yield the effect I want (I want the second cell of the tableview to display the first object in the array), hope i explained everything ok, please help! thanks
EDIT
var dates = [NSDate]()
var autoBio = [String]()
func getPosts() {
let getPostsQuery = PFQuery(className: "allPosts")
getPostsQuery.whereKey("userId", equalTo: userNumber)
getPostsQuery.limit = 15
getPostsQuery.orderByDescending("createdAt")
getPostsQuery.findObjectsInBackgroundWithBlock { (posts, error) -> Void in
if let posts = posts {
self.dates.removeAll(keepCapacity: true)
for post in posts {
self.dates.append(post.createdAt as NSDate!)
}
}
print(self.dates.count)
}
}
func getBio() {
let bioQuery = PFQuery(className: "bios")
bioQuery.whereKey("userId", equalTo: userNumber)
bioQuery.limit = 1
bioQuery.findObjectsInBackgroundWithBlock { (bios, error) -> Void in
if let bios = bios {
self.bio.removeAll(keepCapacity: false)
for bio in bios {
self.bio.append(bio["about"] as! String)
}
}
}
print(self.bio.count)
}
i put getPosts() and getBio() in viewDidLoad. And I tried printing the bio and dates count as the end of these func and they do return a number > 0 so the arrays should be filled. Any idea what's wrong?
You should try using the first cell as Section Header cell...
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let cell = tableView.dequeueReusableCellWithIdentifier("profileCell") as! SbPostsTableViewCell
return cell
}
I got a fatal error: Array index out of range. The error comes from let profilePicture = tempProductPictureArray[count] when tempProductPictureArray[count] is nil. I am wondering do I set something wrong on imageArray?
var imageArray = [[PFFile]]()
........
.......
.......
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
let cell:MarketTableViewCell = tableView.dequeueReusableCellWithIdentifier("MarketCell") as! MarketTableViewCell
let tempProductPictureArray = imageArray[indexPath.row]
// tempProductPictureArray.count is something like [nil / PFFile(image), nil / PFFile(image) .....]
if tempProductPictureArray.count != 0 {
var hasImage = false
var count = 0
while hasImage == false {
let profilePicture = tempProductPictureArray[count]
if profilePicture != nil {
profilePicture!.getDataInBackgroundWithBlock { data, error in
if error != nil {
self.appDelegate.displayMyAlertMessage((error?.localizedDescription)!, userVI: self)
} else {
cell.productImage.image = UIImage(data: data!)
}
}
hasImage = true
} else if count == tempProductPictureArray.count {
cell.productImage.image = UIImage(named: "Profile Picture")
} else {
count += 1
}
}
} else {
cell.productImage.image = UIImage(named: "Profile Picture")
}
data source
func refreshResults(){
...
...
...
sameObjectInQuery.findObjectsInBackgroundWithBlock{ (sameObjects: [PFObject]?, error: NSError?) -> Void in
for var i = 0; i <= tempUniqueTitle.count - 1; i++ {
tempProductImage = [PFFile]()
for sameobject in sameObjects! {
if sameobject.objectForKey("detailsImage") != nil {
tempProductImage.append(sameobject.objectForKey("detailsImage") as? PFFile)
} else {
tempProductImage.append(nil)
}
imageArray.append(tempProductImage)
}
....
Trace through your code, assuming that tempProductPictureArray contains one item. tempProductPictureArray.count will be 1 and that item is at offset 0. Presumably, it's a nil optional and you want to skip over it.
Since count is not equal to tempProductPictureArray.count, you add one to count and try to fetch something from the array at that location (offset 1). However, we've said the only element in the array is at offset 0, so...crash.
You need to make sure that count is always less than tempProductPictureArray.count.