Application freezing when I press button - ios

So, my assignment for my class is to make an app for the 7th graders at my school to work on math.
In this particular view controller, I am making something that they can practice prime numbers with. I couldn't get everything to load using the override func viewDidLoad(){} so I implemented a button to activate the random number, modulus to check if it's prime, and insert it into the label.
This is ALL of my code that is inside of the Class:
#IBAction func primeBack(sender: UIButton) {
self.performSegueWithIdentifier("primeBack", sender: nil)
}
#IBOutlet var start: UIButton!
#IBOutlet var primeNum: UILabel!
var num = 1
var check = Double()
var temp2 = Double()
let lower : UInt32 = 1
let upper : UInt32 = 100
override func viewDidLoad() {
super.viewDidLoad()
primeNum.hidden = true
start.hidden = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func start(sender: UIButton) {
primeNum.hidden = false
let temp1 = (arc4random_uniform(upper - lower) + lower)
primeNum.text = String(temp1)
while num <= 12
{
check = Double(temp1) / Double(num)
temp2 = check % 1
if temp2 == 0
{
num++
}
else
{
num = 12
}
}
start.hidden = true
}
#IBAction func prime(sender: UIButton) {
if temp2 == 0
{
self.performSegueWithIdentifier("primeCorrect", sender: nil)
}
else
{
self.performSegueWithIdentifier("primeIncorrect", sender: nil)
}
}
#IBAction func notPrime(sender: UIButton) {
if temp2 == 0
{
self.performSegueWithIdentifier("primeIncorrect", sender: nil)
}
else
{
self.performSegueWithIdentifier("primeCorrect", sender: nil)
}
}

Debug and watch what happens to your value of temp2. I suspect it never becomes equal to zero, hence your while loop never ends

Related

Generating Random UIImages that don't repeat

In my app project I am displaying 107 of my images at random, I have set up a for loop that puts all of my images into an array. I then take that array and choose a random Index. That index correlates to a picture and then that picture appears on the screen when the user swipes to the left. My question is that can I make it so my code will not repeat the same index in the array until all of them (or the amount until closing the app) have been chosen at random. Here is my code
class ViewController: UIViewController {
var pictureArray: [String] = []
#IBOutlet weak var quoteImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...107{
pictureArray.append("quote\(i).jpg")
print(pictureArray)
}
// Do any additional setup after loading the view, typically from a nib.
let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: #selector (changeQuotes))
swipeRecognizer.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(swipeRecognizer)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var prefersStatusBarHidden: Bool{
return true
}
#objc func changeQuotes(){
let numberOfImages: UInt32 = 107
let randomIndex = Int(arc4random_uniform(UInt32(pictureArray.count)))
let imageName = "\(pictureArray[randomIndex])"
print(imageName)
quoteImage.image = UIImage(named: imageName)
}
}
Thanks for any help!
Flush your array randomly, then just get the "sorted" image one by one.
extension Sequence {
func randomSorted() -> [Element] {
var result = Array(self)
guard result.count > 1 else { return result }
for (i, k) in zip(result.indices, stride(from: result.count, to: 1, by: -1)) {
let newIndex = Int(arc4random_uniform(UInt32(k)))
if newIndex == i { continue }
result.swapAt(i, newIndex)
}
return result
}
}
You can generate unique random number by managing 2 arrays one contains images that are not yet displayed and one that are already displayed
Make following changes in your code
var pictureArray: [String] = []
var selectedPictureArray: [String] = []
static let TOTAL_IMAGES = 108
#IBOutlet weak var quoteImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
self.fillPictureArray()
let swipeRecognizer = UISwipeGestureRecognizer(target: self, action: #selector (changeQuotes))
swipeRecognizer.direction = UISwipeGestureRecognizerDirection.left
self.view.addGestureRecognizer(swipeRecognizer)
}
func fillPictureArray() {
self.selectedPictureArray.removeAll()
for i in 0..<ViewController.TOTAL_IMAGES {
pictureArray.append("quote\(i).jpg")
}
print(pictureArray)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override var prefersStatusBarHidden: Bool{
return true
}
func changeQuotes(){
if self.pictureArray.count == 0 {
self.fillPictureArray()
}
var randomIndex = 0
while true {
randomIndex = Int(arc4random_uniform(UInt32(ViewController.TOTAL_IMAGES)))
if self.selectedPictureArray.contains("quote\(randomIndex).jpg") {
continue
}else {
break
}
}
let imageName = "quote\(randomIndex).jpg"
self.selectedPictureArray.append(imageName)
print(imageName)
quoteImage.image = UIImage(named: imageName)
let index = self.pictureArray.index(of: imageName)
self.pictureArray.remove(at: index!)
}
Happy coding :)

Copy button from Label (IOS)

Copy button from Label.
I have code for the calculator but I can not figure out how to do it so that when I click on the button, the number with the Label is copied.
Or how can I make it so that when I press long it appears to copy:
"
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var displayResultLabel: UILabel!
var stillTyping = false
var dotIsPlaced = false
var firstOperand: Double = 0
var secondOperand: Double = 0
var operationSign: String = ""
var currentInput: Double {
get {
return Double (displayResultLabel.text!)!
}
set {
let value = "\(newValue)"
let ValueArray = (value.components(separatedBy:"."))
if ValueArray[1] == "0" {
displayResultLabel.text = "\(ValueArray[0])"
} else {
displayResultLabel.text = "\(newValue)"
}
stillTyping = false
}
}
#IBAction func numberPressed(_ sender: UIButton) {
let number = sender.currentTitle!
if stillTyping {
if (displayResultLabel.text?.characters.count)! < 20 {
displayResultLabel.text = displayResultLabel.text! + number
}
} else {
displayResultLabel.text = number
stillTyping = true
}
}
#IBAction func twoOperandsSignPressed(sender: UIButton) {
operationSign = sender.currentTitle!
firstOperand = currentInput
stillTyping = false
dotIsPlaced = false
}
func operateWithTwoOperands(operation: (Double, Double) -> Double) {
currentInput = operation(firstOperand, secondOperand)
stillTyping = false
}
#IBAction func equalitySignPressed(sender: UIButton) {
if stillTyping {
secondOperand = currentInput
}
dotIsPlaced = false
switch operationSign {
case "+":
operateWithTwoOperands{$0 + $1}
case "-":
operateWithTwoOperands{$0 - $1}
case "×":
operateWithTwoOperands{$0 * $1}
case "÷":
operateWithTwoOperands{$0 / $1}
default: break
}
}
#IBAction func dotButtonPressed(_ sender: UIButton) {
if stillTyping && !dotIsPlaced {
displayResultLabel.text = displayResultLabel.text! + "."
dotIsPlaced = true
} else if !stillTyping && !dotIsPlaced {
displayResultLabel.text = "0."
}
}
}
I will answer both of your questions.
The first question: How to press a button that can copy the text that is being displayed on the UILabel?
Answer:
#IBAction func yourButtonAction(_ sender: UIButton) {
UIPasteboard.general.string = yourLabel.text
}
The second question: How to long-press on the UILabel that shows the "Copy" action?
Answer:
To make UILabel copyable we need to create a custom class that is a subclass of UILabel. Temporarily called CopyableLabel:
import UIKit
class CopyableLabel: UILabel {
override var canBecomeFirstResponder: Bool { return true }
override init(frame: CGRect) {
super.init(frame: frame)
sharedInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
sharedInit()
}
override func copy(_ sender: Any?) {
UIPasteboard.general.string = text
UIMenuController.shared.setMenuVisible(false, animated: true)
}
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
return action == #selector(copy(_:))
}
}
// MARK: Actions methods
extension CopyableLabel {
func longPressGestureActionHandler(_ sender: UILongPressGestureRecognizer) {
becomeFirstResponder()
let menu = UIMenuController.shared
if !menu.isMenuVisible {
menu.setTargetRect(bounds, in: self)
menu.setMenuVisible(true, animated: true)
}
}
}
// MARK: Helper methods
extension CopyableLabel {
func sharedInit() {
isUserInteractionEnabled = true
addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(longPressGestureActionHandler(_:))))
}
}
And use a CopyableLabel instead of a pure UILabel:
let yourLabel: CopyableLabel = CopyableLabel()
If you use the Interface Builder, make sure you've defined the base class of your Label:
You can implement copy and paste with UIPasteboard. You can read and write values over it's property string, e.g.:
displayResultLabel.text = UIPasteboard.general.string
pastes the current value from the pasteboard into your label, and
UIPasteboard.general.string = displayResultLabel.text
copies the value from label to the pasteboard.

Swift timer label recurring 9

I have created a simple timer in swift 3.
For some reason though, even though it works the label display too many numbers :S it displays a crazy amount of 9's. Is this to do with rounding?
Thanks, code below :)
var swiftTimer : Timer?
var swiftCounter: Double = 0.00
#IBOutlet weak var displayTimeLBL: UILabel!
#IBAction func start(_ sender: Any) {
swiftTimer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(ViewController.updateCounter), userInfo: nil, repeats: true)
}
#IBAction func stop(_ sender: Any) {
if swiftTimer != nil{
swiftTimer?.invalidate()
swiftCounter = 0.00
updateLabel()
swiftTimer = nil
}
}
func updateLabel(){
displayTimeLBL.text = String(swiftCounter)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func updateCounter(){
swiftCounter+=0.01
round(swiftCounter)
updateLabel()
}
enter image description here
Simplest Solution:
func updateCounter(){
swiftCounter+=0.01
round(swiftCounter)
swiftCounter = Double(round(100*swiftCounter)/100)
updateLabel()
}
If you want two fractions then you can use swiftCounter.round(2) instead of round(swiftCounter)
to update the text use:
displayTimeLBL.text = "\(swiftCounter.round(2))"
Here is the Double extension used:
extension Double {
func round(_ places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}

Counting up/down numbers animation

I have an UIPageViewController with a number in the center of each VC in it.
I want that when I swipe from view to view, the number will begin at 0 and count up until it gets to the correct number (or if the number is negative - count down) like in this gif:
https://d13yacurqjgara.cloudfront.net/users/345970/screenshots/2126044/shot.gif
How can I do that?
Thank you!
You can use NSTimer to achieve this.
Here is example project I created for you.
Create layout like this:
Then in your ViewController do like so:
import UIKit
class ViewController: UIViewController {
#IBOutlet var countingLabel: UILabel!
var number = 0
var destinationNumber = 30
var timer: NSTimer!
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.
}
#IBAction func startButtonTapped(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "countUp", userInfo: nil, repeats: true)
}
func countUp() {
if number < destinationNumber {
number += 1
countingLabel.text = "\(number)"
} else {
timer.invalidate()
}
}
}
It will work.
Do not overcomplicate with timers and invalidations, etc.
extension UILabel {
func countAnimation(upto: Double) {
let from: Double = text?.replace(string: ",", replacement: ".").components(separatedBy: CharacterSet.init(charactersIn: "-0123456789.").inverted).first.flatMap { Double($0) } ?? 0.0
let steps: Int = 20
let duration = 0.350
let delay = duration / Double(steps)
let diff = upto - from
for i in 0...steps {
DispatchQueue.main.asyncAfter(deadline: .now() + delay * Double(i)) {
self.text = "\(from + diff * (Double(i) / Double(delay)))"
}
}
}
}

Issue when passing data through segue in swift2 [duplicate]

This is a Tip Calculator Project and It must have a settings view where I select the default tip rate. I have some issues with passing data, when I select a default tip percentage it doesn't change in the View Controller, also I want to make the app remember the default rate when I close the app and reopened. I will really appreciate that some one corrects my code and test it. This is for entering a Computer Science Program in college, I don't have previous experience with any programming language before.
100
TipPercentageLabel.text = "(tipDisplay)%"
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setupContainer() {
tipSlider.minimumValue = 0
tipSlider.maximumValue = 100
tipSlider.value = 20
tipSlider.addTarget(self, action: "sliderTipChanged:", forControlEvents: .ValueChanged)
personsStepper.minimumValue = 1
personsStepper.maximumValue = 30
personsStepper.value = 1
personsStepper.addTarget(self, action: "sliderPersonChanged:", forControlEvents: .ValueChanged)
amountTextField.text = ""
refreshCalculation()
}
#IBAction func OnEditingFieldBill(sender: AnyObject) {
refreshCalculation()
}
func refreshCalculation() {
numberFormatter.numberStyle = NSNumberFormatterStyle.DecimalStyle
if let amount = numberFormatter.numberFromString(amountTextField.text!) as? Double {
let tipAmount = amount * tipPercentage
let totalBill = amount + tipAmount
let billPerPerson = totalBill / Double(numberOfPerson)
numberFormatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
tipAmountLabel.text = numberFormatter.stringFromNumber(tipAmount)
totalBillLabel.text = numberFormatter.stringFromNumber(totalBill)
billPerPersonLabel.text = numberFormatter.stringFromNumber(billPerPerson)
} else {
tipAmountLabel.text = "-"
totalBillLabel.text = "-"
billPerPersonLabel.text = "-"
}
numberFormatter.numberStyle = NSNumberFormatterStyle.PercentStyle
numberFormatter.minimumFractionDigits = 1
numberFormatter.maximumFractionDigits = 1
TipPercentageLabel.text = self.numberFormatter.stringFromNumber(tipPercentage)
numberOfPersonLabel.text = "\(numberOfPerson)"
}
#IBAction func sliderTipChanged(sender: AnyObject) {
tipPercentage = Double(round(tipSlider.value)) / 100
refreshCalculation()
}
#IBAction func StepperPersonChanged(sender: AnyObject) {
numberOfPerson = Int(round(personsStepper.value))
refreshCalculation()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if let id = segue.identifier {
if id == "show settings" {
if let SettingsViewController = segue.destinationViewController as? SettingsViewController {
}
}
}
}
}
SETTINGS VIEW CONTROLLER
import UIKit
class SettingsViewController: UIViewController {
#IBOutlet weak var tipControl: UISegmentedControl!
var tipRates:Double?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func DefaultRate(sender: AnyObject) {
va
if let tip = tipRates {
ViewController.tipPercentage = tip/100
Replace you DefaultRate IBAction with this:
#IBAction func changevalue(sender: UISegmentedControl) {
var tipRate = [5, 10, 15, 20, 25, 30]
tipRates = Double(tipRate[tipControl.selectedSegmentIndex])
delegate?.tipPercentageChanged(tipRates!) print("(tipRates)")
NSUserDefaults.standardUserDefaults().setDouble(tipRates!, forKey: "DefaultTipRate")
NSUserDefaults.standardUserDefaults().synchronize()
}
And set the event as "Value Changed" as shown in the image below
I strongly recommend you go through a few introductory iOS & Swift tutorials online. SO is not the place to get beginner level understanding of programming topics. Some recommended tutorials:
Swift 2 Tutorial
Apple swift tutorials

Resources