Swift using variables from other files - ios

I have this file named FoodHandler.swift, and I'm trying to have it appear inside of a label, and I'm getting the error "fatal error: unexpectedly found nil while unwrapping an Optional value" This will open in a println() on the new page,
Here's my code inside of FoodHandler.swift
import Foundation
import UIKit
var FoodType = ""
class SwitchSegue
{
}
Here's my code on the new View Controller
#IBOutlet var lblChose: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func viewDidAppear(animated: Bool) {
println(FoodType) // Works
lblChose.text = FoodType // Throws a nil exception
}
Does anyone know why this is?

The error isn't about FoodType. You can tell because FoodType is not an optional value at all... but lblChose is. It's an "implicitly unwrapped optional", which you can read about here; it's indicated by the ! after its declaration.
Check to be sure that the lblChose outlet is connected properly in the interface.

Without seeing anymore of your code, I'd assume the issue is with the label not existing. You have declared it as an optional, but it may not be connected with a label on the storyboard. Usually when you connect them from storyboard they will be weak:
#IBOutlet weak var lblChose: UILabel!

You should try using (as far as I understood the println is displaying the correct value right?):
lblChose.text = FoodType!

Related

Setting a label to a value in Swift on XCode?

I understand it’s rather basic, but I’m only trying to get a grasp on basic functions.
I have produced some code by partially my own knowledge and partial bits from different guides.
I am not getting any errors, but the label is not displaying itself as “Text”. I believe it’s to do with the order/place my code is put.
Please help explain how I can fix this!
Please note as well:
I have just a single label called myLabel (named under the document section of my the identity inspector
It is has the text “Loaded” put into it already when I put it in.
I have no other code anywhere, only the default new project code.
I renamed the ViewController to ViewManager to avoid a class error.
First image: This is the image just so you know the location and other bits. I’ll attach the code too:
Second image: What I get, with no errors:
Third image: My main storyboard file:
And now it in code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myLabel: UILabel!
#IBAction func labelSet() {
myLabel.text = "Text"
}
}
Make sure that the IBAction is connected to Touch Up Inside in Interface Builder.
Change the signature of the IBAction to
#IBAction func labelSet(_ sender: UIButton) {
Your function func labelSet() isn't called anywhere. Neither in the Storyboard nor elsewhere.
You can call it in viewDidLoad() like this:
override func viewDidLoad() {
super.viewDidLoad()
labelSet()
}
Alternatively call it after the label has loaded.
#IBOutlet weak var myLabel: UILabel! {
didSet {
labelSet()
}
}

UIView to UIViewController communication via protocol not working

maybe I am missing something really fundamental here, but after staring at the code for an hour or so, my brain is going trough cycles and I would appreciate a fresh glance at this problem.
I have the following UIView:
import UIKit
protocol DetailViewWillShowUpDelegate {
func sendDetailOpened(_ openedBool: Bool)
}
class locationXIBController: UIView {
#IBOutlet weak var loationLabel: UILabel!
#IBOutlet weak var vsedniOteviraciDobaLabel: UILabel!
#IBOutlet weak var prijmajiKartyLabel: UILabel!
#IBOutlet weak var detailViewButtonOutlet: UIButton!
#IBOutlet weak var backgroundViewButton: UIButton!
let openedBool = true
var detailViewWillShowUpDelegate: DetailViewWillShowUpDelegate?
override func awakeFromNib() {
super.awakeFromNib()
}
#IBAction func vecerkaDetailButtonPressed(_ sender: UIButton) {
detailViewWillShowUpDelegate?.sendDetailOpened(openedBool)
print("pressed")
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if let result = detailViewButtonOutlet.hitTest(convert(point, to: detailViewButtonOutlet), with: event) {
return result
}
return backgroundViewButton.hitTest(convert(point, to: backgroundViewButton), with: event)
}
}
Now the problem is, that when I call/press the vecerkaDetailButtonPressed function I get "pressed" output in the console but the protocol for some reason doesn't go trough.
The other side looks like this (stripped for simplicity):
class MapViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
let locationXIB = locationXIBController()
let isVecerkaDetailOpened = false
override func viewDidLoad() {
locationXIB.detailViewWillShowUpDelegate = self
}
extension MapViewController: DetailViewWillShowUpDelegate {
func sendDetailOpened(_ openedBool: Bool) {
isVecerkaDetailOpened = openedBool
print("success")
}
}
I know the protocol value at the moment of execution is nil. As I said, any help is appreciated, thanks!
First, a couple of naming convention issues:
The name locationXIBController is a bad choice for a UIView object. It is a view object, not a controller object.
Second, class names in Swift should start with an upper-case letter. So LocationXIBView would be a much better name for that view class.
Next, your code
let locationXIB = locationXIBController()
...is wrong. That creates a brand-new instance of your locationXIBController class that you never install in your view hierarchy. You should make that line an IBOutlet:
#IBOutlet weak var locationXIB: locationXIBController!
And then you should control-drag from the locationXIBController in your StoryBoard onto the outlet in your view controller. That will cause Interface Builder to connect the outlet.
Now when you run your program the variable locationXIB will be connected to the locationXIBController view from your storyboard/XIB when it's loaded.
In addition to the answer of #Duncan C, you might check whether you need super.viewDidLoad() at the top of the viewDidLoad() method in the MapViewController class? Not doing that can lead to quirky things in your app.
I asked:
So does detailViewWillShowUpDelegate actually point at anything, or is it nil?
And you replied:
I just tried debugging and it is actually nil
So that's the problem... you need to set detailViewWillShowUpDelegate to point to a valid delegate object. This is often done in the .xib file or storyboard, and sometimes people forget to make that connection, so check there if it makes sense. Else you'll just need to get a reference to the delegate at some point before the code in question can run and set it up.
Answer to the credit of #Paulw11
I finally managed to get it working by communicating like so:
step 1) 1:1 communication via protocol between MKAnnotation and MKAnnotationView
step 2) 1:1 communication via protocol between MKAnnotationView and MapViewController passing the same data
Finally works like a charm, thanks!

Why would a UIAlert cause one of my other variables to be nil?

I'm trying to make a UIAlert pop up, but whenever the code calls the function that should do that, a value totally unrelated in the process caused an error saying that it returned nil when it expected to have a value. I solved the issue, but I have no idea why my solution worked.
The original:
var fullFreqHeard: [Double] = []
#IBOutlet weak var fullFreqLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
fullFreqLabel.text = "\(fullFreqHeard)"
}
The solution:
var fullFreqHeard: [Double] = []
#IBOutlet weak var fullFreqLabel: UILabel?
override func viewDidLoad() {
super.viewDidLoad()
fullFreqLabel?.text = "\(fullFreqHeard)"
}
The difference is in the original I force unwrapped the label, whereas in the solution I used a '?'. What is going on here? I was also wondering if it might have anything to do with the alert.
I don't think it has anything to do with the alert. The reason force unwrapping fixes the error is because fullFreqLabel is initially nil. You have to initialize it before setting it's value. For instance, var fullFreqLabel = UILabel(frame: CGRect.zero)

WKInterfaceTable & setNumberOfRows get crash "unexpectedly found nil while unwrapping an Optional value"

I'm working with WatchKit, I have a simple interface with only a table but I get an error with just a few lines of code, maybe I forgot something really basic.
My interface:
the row inside the table has the identifier:
and the custom class:
The controller is implemented by this code:
import WatchKit
import Foundation
class ActiveListController: WKInterfaceController
{
#IBOutlet weak var tableView: WKInterfaceTable!
override func awakeWithContext(context: AnyObject?)
{
super.awakeWithContext(context)
loadData()
}
override func willActivate()
{
// This method is called when watch view controller is about to be visible to user
super.willActivate()
}
override func didDeactivate()
{
// This method is called when watch view controller is no longer visible
super.didDeactivate()
}
func loadData()
{
tableView.setNumberOfRows(10, withRowType: "ItemRow") // GET ERROR
for index in 0...9
{
let row = tableView.rowControllerAtIndex(index) as! ItemRow
row.nameLabel.setText("test")
}
}
}
and obviously I have my custom class for the single row
import Foundation
import WatchKit
class ItemRow : NSObject
{
#IBOutlet weak var checkImage: WKInterfaceImage!
#IBOutlet weak var nameLabel: WKInterfaceLabel!
}
So when I run the app I get error when I try to set the number of rows but really I can't understand what is nil:
fatal error: unexpectedly found nil while unwrapping an Optional value
Maybe it's a simple mistake, maybe not but please help me :\
The for loop in your code is going from 1...10 and it should be 0...9 because the rows are 0 based
finally I found my mistake.
I forgot to set my only one interface for Apple Watch as Initial Controller.
Yep, unbelievable and embarrassing but that's it. The error that provides Xcode it's not the best , it would be better something like "initial controller missing".
I hope my question & answer can help someone one day :)

UIScrollView and UITextView

I'm new to Swift (and programming in general). I'm having some issues getting a Text View to scroll.
I've created outlets for the scroll view and the text view already.
I've found a boat load of people asking the same question on Stack Overflow/Reddit but I am still unable to fix the issue due to just not really knowing what I'm doing.
Here is a screenshot of my view controller so you can see the text I am referring to:
And here is the code I have in my viewcontroller.swift file:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var scrollView: UIScrollView!
#IBOutlet weak var descriptionTextView: UITextView!
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.scrollView.layoutIfNeeded()
self.scrollView.contentSize = self.descriptionTextView.bounds.size
}
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'm getting the following green error message when I build:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
I would love some help from anyone if you are feeling kind or have the time to chime in.
Call me crazy, but would it be silly to believe that it is just overwhelmingly difficult to achieve such a simple thing as scrollable text? I feel like I'm missing something.
Thanks to anyone who may be able to lend a hand.

Resources