When I try to instantiate my ViewController with the code below (in the viewDidLoad part) I get a Thread 1: EXC_BAD_ACCESS when running the app on the self.present line. (I'm a beginner to coding)
EDIT: So I provide my entire code here to see where it goes wrong. I shifted the code to viewDidLoad of my Second View Controller now. Now the app starts up, however when I press the "enter" Button, I get a "Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" error..
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var progressBarView: ProgressBarView!
#IBOutlet weak var progressBarView1: ProgressBarView1!
override func viewDidLoad() {
super.viewDidLoad()
// updaten van de progressbar
progressBarView.progress = CGFloat(percProgress())
progressBarView1.progress = CGFloat(0.5)
// een constante maken die de daystogocalc Int van de berekening verderop in een String cast
let daysToGoCalcString = String(daysToGoCalc())
// updaten van het label daysToGo
daysToGo.text = "Still \(daysToGoCalcString) days to go"
// updaten van het label textPercentage
let textPercentage = NSString(format: "%.0f", (percProgress() * 100))
percentageDays.text = String(textPercentage) + "%"
}
#IBOutlet weak var daysToGo: UILabel!
#IBOutlet weak var percentageDays: UILabel!
#IBOutlet weak var firstGoalLabel: UILabel!
#IBAction func unwindToGoals(unwindSegue: UIStoryboardSegue) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// Automatische datumberekening
let today = Date()
let calendar = Calendar.current
// Dagnummer van het jaar
var todayNumber: Int {
get {
return calendar.ordinality(of: .day, in: .year, for: today)!
}
}
// FLOAT MAKER: onderstaande maakt een Float van het dagnummer (nodig voor de Progress Bar uiteindelijk)
var todayFloat: Float {
get {
return Float(todayNumber)
}
}
// KWARTAAL PROGRESSIE: deze functie checkt eerst in welk kwartaal je zit, en vervolgens de voortgang in dat kwartaal in een float
func percProgress() -> Float {
if todayNumber < 91 {
return todayFloat / 90
}
else if todayNumber < 182 {
return (todayFloat - 90) / 91
}
else if todayNumber < 274 {
return (todayFloat - 181) / 92
}
else {
return (todayFloat - 273) / 92
}
}
// Bereken aantal dagen te gaan in kwartaal
func daysToGoCalc() -> Int {
if todayNumber < 91 {
return 90 - todayNumber
}
else if todayNumber < 182 {
return 181 - todayNumber
}
else if todayNumber < 274 {
return 273 - todayNumber
}
else {
return 365 - todayNumber
}
}
}
// SECOND VIEW CONTROLLER
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
firstGoaltext.delegate = self
firstGoalStart.delegate = self
firstGoalEnd.delegate = self
secondGoaltext.delegate = self
secondGoalStart.delegate = self
secondGoalEnd.delegate = self
thirdGoaltext.delegate = self
thirdGoalStart.delegate = self
thirdGoalEnd.delegate = self
fourthGoaltext.delegate = self
fourthGoalStart.delegate = self
fourthGoalEnd.delegate = self
fifthGoaltext.delegate = self
fifthGoalStart.delegate = self
fifthGoalEnd.delegate = self
// INSTANTIATE VIEWCONTROLLER
let storyboard1 = UIStoryboard(name: "Main", bundle: nil)
var firstController: UIViewController {
get {
return storyboard1.instantiateViewController(withIdentifier: "myViewControllerIdentifier")
}
}
self.present(firstController, animated: true, completion: nil)
}
#IBOutlet weak var firstGoaltext: UITextField!
#IBOutlet weak var firstGoalStart: UITextField!
#IBOutlet weak var firstGoalEnd: UITextField!
#IBOutlet weak var secondGoaltext: UITextField!
#IBOutlet weak var secondGoalStart: UITextField!
#IBOutlet weak var secondGoalEnd: UITextField!
#IBOutlet weak var thirdGoaltext: UITextField!
#IBOutlet weak var thirdGoalStart: UITextField!
#IBOutlet weak var thirdGoalEnd: UITextField!
#IBOutlet weak var fourthGoaltext: UITextField!
#IBOutlet weak var fourthGoalStart: UITextField!
#IBOutlet weak var fourthGoalEnd: UITextField!
#IBOutlet weak var fifthGoaltext: UITextField!
#IBOutlet weak var fifthGoalStart: UITextField!
#IBOutlet weak var fifthGoalEnd: UITextField!
#IBAction func enter(_ sender: Any!) {
let vc1 = ViewController()
vc1.firstGoalLabel.text = firstGoaltext.text
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
firstGoalStart.resignFirstResponder()
}
}
extension SecondViewController : UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
What I am doing wrong here?
Try running the code snippet in “viewDidAppear” instead of “viewDidLoad”
Related
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var triviaLabel: UILabel!
#IBOutlet weak var trueButton: UIButton!
#IBOutlet weak var falseButton: UIButton!
#IBOutlet weak var progressBar: UIProgressView!
var quiz = [Question(text: "Blah blah", answer: "True"),
Question(text: "Ha ha", answer: "True"),Question(text: "Bruh bruh", answer: "False")]
var questionNumber = 0
override func viewDidLoad() {
super.viewDidLoad()
updateQuestion()
}
#IBAction func answerButtonPressed(_ sender: UIButton) {
let userAnswer = sender.currentTitle
let actualAnswer = quiz[questionNumber].answer
if userAnswer == actualAnswer {
} else {
}
if questionNumber < quiz.count-1 {
questionNumber += 1
}else {
questionNumber = 0
}
updateQuestion()
}
func updateQuestion() {
triviaLabel.text = quiz[questionNumber].text // Get the error here
updateQuestion()
}
}
The build succeeds and the app launches but there comes a blank screen and the error occurs. I tried mapping the label again with the storyboard. I speculate that there is some problem with the label declaration or connection.
On every pressed touch I want UILabel to count number down one by one from 10 to 0.
Also when pressed I want to show UIImageView: "MyRocketWith", and when release the pressed touch I want to show UIImageView: "MyRocket".
class ViewController: UIViewController {
#IBOutlet weak var MyRocket: UIImageView!
#IBOutlet weak var MyRocketWith: UIImageView!
#IBOutlet weak var Countdown: UILabel!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch: UITouch? = touches.first
if touch?.view != self.MyRocket {
self.MyRocketWith.isHidden = true
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
The below code shows and hides the UIImageView on click of UILabel
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var MyRocketWith: UIImageView!
#IBOutlet weak var CountDownLabel: UILabel!
#IBOutlet weak var MyRocket: UIImageView!
var count = 10
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapFunction))
CountDownLabel.isUserInteractionEnabled = true
CountDownLabel.addGestureRecognizer(tap)
MyRocket.isHidden = false
MyRocketWith.isHidden = true
MyRocketWith.tag=0
}
#IBAction func tapFunction(sender: UITapGestureRecognizer) {
print("tap working")
count = count-1
CountDownLabel.text = String(count)
if MyRocketWith.tag == 0
{
MyRocket.isHidden = true
MyRocketWith.isHidden = false
MyRocketWith.tag=1
}
else
{
MyRocket.isHidden = false
MyRocketWith.isHidden = true
MyRocketWith.tag=0
}
}
}
Im trying to make this calculator for various math formulas and I'm stuck at this point. I was following this tutorial
Here's my code:
import UIKit
class pythagorasViewController: UIViewController {
#IBOutlet weak var aLabel: UILabel!
#IBOutlet weak var bLabel: UILabel!
#IBOutlet weak var aField: UITextField!
#IBOutlet weak var bField: UITextField!
#IBOutlet weak var answerLabel: UILabel!
#IBAction func calculateButton(_ sender: UIButton) {
var a = (aField.text as NSString).floatValue
var b = (bField.text as NSString).floatValue
var answer = sqrt(a*a + b*b)
answerLabel.text = "\(answer)"
}
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.
}
}
The part where I'm getting the error is at:
var a = (aField.text as NSString).floatValue
var b = (bField.text as NSString).floatValue
Prefer let to var when possible. You do not need to use NSString. You can cast String to Float?. You need to unwrap both the text property which is a String? (if you have a question about the type of a variable option click and it will show you) and the Float? conversion:
func calculateButton(_ sender: UIButton) {
guard let aText = aField.text,
let bText = bField.text,
let a = Float(aText),
let b = Float(bText) else {
return
}
let answer = sqrt(a*a + b*b)
answerLabel.text = "\(answer)"
}
i'm quite new to using swift and i'm currently working on a small school project. However, one function i cant seem to work out is how to make an NSTimer change the text in a UILabel after a certain amount of time. I want to apply this function to a UILabel (cannotbuy) that was blank, and had just been changed to text displaying a message("you dont have enough points"), and i want this message to be removed and the UILabel to be blank again after a second or so. Can anyone help me? Thanks.
class Upgrades: UIViewController{
#IBOutlet weak var shprogresslabel: UILabel!
#IBOutlet weak var fsprogresslabel: UILabel!
#IBOutlet weak var shprogress: UIProgressView!
#IBOutlet weak var fsprogress: UIProgressView!
#IBOutlet weak var shbutton: UIButton!
#IBOutlet weak var fsbutton: UIButton!
#IBOutlet weak var storepoints: UILabel!
#IBOutlet weak var cannotbuy: UILabel!
#IBOutlet weak var label2: UILabel!
#IBOutlet weak var label1: UILabel!
var fsprice = Int()
var shprice = Int()
let defaults = NSUserDefaults.standardUserDefaults()
func updateProgress1(){
fsprogress.progress += 0.1
let fsprogressvalue = self.fsprogress.progress
fsprogresslabel.text = "\(fsprogressvalue * 100)%"
}
func updateProgress2(){
shprogress.progress += 0.2
let shprogressvalue = self.shprogress.progress
shprogresslabel.text = "\(shprogressvalue * 100)%"
}
#IBAction func button2(sender: AnyObject) {
if shprice <= 90{
if SharingManager.sharedInstance.totalscore >= shprice{
SharingManager.sharedInstance.shiphealth = SharingManager.sharedInstance.shiphealth + 1
SharingManager.sharedInstance.totalscore = SharingManager.sharedInstance.totalscore - fsprice
storepoints.text = String(SharingManager.sharedInstance.totalscore)
shprice = shprice + 20
print(shprice)
label2.text = ("\(shprice)")
defaults.setInteger(SharingManager.sharedInstance.shiphealth, forKey: "SharingManager.sharedInstance.shiphealth")
updateProgress2()
}else{
cannotbuy.text = "You dont have enough points"
}
}else{
cannotbuy.text = "You have purchased all the available upgrades for this"
}
}
#IBAction func button1(sender: AnyObject) {
if fsprice <= 100{
if SharingManager.sharedInstance.totalscore >= fsprice{
SharingManager.sharedInstance.bulletspeed = SharingManager.sharedInstance.bulletspeed - 0.15
SharingManager.sharedInstance.totalscore = SharingManager.sharedInstance.totalscore - fsprice
storepoints.text = String(SharingManager.sharedInstance.totalscore)
fsprice = fsprice + 10
print(fsprice)
label1.text = ("\(fsprice)")
defaults.setDouble(SharingManager.sharedInstance.bulletspeed, forKey: "SharingManager.sharedInstance.bulletspeed")
updateProgress1()
}else{
cannotbuy.text = "You dont have enough points"
}
}else{
cannotbuy.text = "You have purchased all the available upgrades for this"
}
}
override func viewDidLoad() {
if fsprice == 0{
fsprice = 10
}
if shprice == 0{
shprice = 10
}
if fsprice == 180{
fsbutton.enabled = false
}
if shprice == 100{
shbutton.enabled = false
}
storepoints.text = String(SharingManager.sharedInstance.totalscore)
label1.text = ("\(fsprice)")
label2.text = ("\(shprice)")
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.
}
}
There are two ways for you to do this:
Using NSTimer:
#IBAction func button2(sender: AnyObject) {
...
cannotbuy.text = "You don't have enough points"
NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: #selector(ViewController.resetCannotBuy), userInfo: nil, repeats: false)
}
func resetCannotBuy() {
cannotbuy.text = ""
}
Using dispatch_after:
#IBAction func button2(sender: AnyObject) {
...
cannotbuy.text = "You don't have enough points"
let fiveSecondLater = dispatch_time(DISPATCH_TIME_NOW, 5 * Int64(NSEC_PER_SEC))
dispatch_after(fiveSecondLater, dispatch_get_main_queue()) {
self.cannotbuy.text = ""
}
}
NSEC_PER_SEC is the constant for nanosecond per second, which is equal to 1 billion.
ProgressBar only shows the progress when the loop ends.
How do in this example for the bar to be updated in real time?
#IBAction func btnStart(sender: AnyObject) {
for var xx:Float = 0 ; xx<=1.0; xx=xx+0.00001 {
progressView.setProgress(xx, animated: false)
}
}
#IBOutlet weak var progressLabel: UILabel!
#IBOutlet weak var progressView: UIProgressView!
UI only updates in the main loop and at the end of the current scope,
so try this
#IBAction func btnStart(sender: AnyObject) {
NSThread.detachNewThreadSelector("process", toTarget: self, withObject: nil)
}
func process() {
for var xx:Float = 0 ; xx<=1.0; xx=xx+0.00001 {
dispatch_async(dispatch_get_main_queue(), {
progressView.setProgress(xx, animated: false)
})
}
}
#IBOutlet weak var progressLabel: UILabel!
#IBOutlet weak var progressView: UIProgressView!