I am using xcode 8.2 and swift to make a simple application.
I have added a UIButton to my View using the Interface Builder.
I have added the appropriate outlets for the button:
#IBOutlet weak var myBtn: UIButton!
I want this button to be hidden on start so in viewDidLoad I am setting is to Hidden. Like this:
override func viewDidLoad() {
super.viewDidLoad()
...
myBtn.isHidden = true
...
mqttConfig = MQTTConfig(clientId: "iphone7", host: "192.xx.xx.150", port: 18xx, keepAlive: 60)
mqttConfig.onMessageCallback = { mqttMessage in
if ( mqttMessage.topic == "status" ) {
if ( mqttMessage.payloadString?.localizedStandardContains("show") )! {
self.showButton = true
} else if ( mqttMessage.payloadString?.localizedStandardContains("hide") )! {
self.showButton = false
}
self.showHideSeatButtons()
} else {
// something to do in case of other topics
}
}
Later in the code I have a function to show/hide this button.
func showHideButton(){
if ( self.showButton ) {
print("button enabled!")
myBtn.isHidden = false
} else {
print("button disabled!")
myBtn.isHidden = true
}
}
When I call this function (by receiving a certain message using MQTT) I get the print outs but I don't see the button.
If I press where I know the button is, then the button gets shown.
Any idea what could be going on here? I have spent and hour googling this now! Please don't suggest object-c way of solving this issue, as I don't know object-c.
In onMessageCallback block
Replace following line
self.showHideSeatButtons()
with
DispatchQueue.main.async {
self.showHideSeatButtons()
}
Note: UI related changes/updates must be handled by main queue (thread).
Since you're calling a service it's possible you're not working in the same thread. Try this:
func showHideButton(){
DispatchQueue.main.async {
if (self.showButton ) {
print("button enabled!")
self.myBtn.isHidden = false
} else {
print("button disabled!")
self.myBtn.isHidden = true
}
}
}
try this
myBtn.isHidden = true
myBtn.alpha = 0
This question already has answers here:
"Thread 1: stopped at breakpoint" error when initializing an NSURL object
(3 answers)
Closed 6 years ago.
I get an "lldb" error in my Debug Area when I try to run this app but I don't know why, because I didn't change anything. The screenshot up top shows what happens when the app gets automatically closed.
import UIKit
class ViewController: UIViewController {
#IBOutlet var ScoreLabel: UILabel!
var taps = 0{
didSet {
if taps == 330 {
print("You have reaches 5 taps !!")
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let defaults = NSUserDefaults.standardUserDefaults()
if let storedTaps = defaults.objectForKey("key") as? Int {
self.taps = storedTaps
setLabel(storedTaps)
}
}
#IBAction func ScoreButton(sender: UIButton) {
taps += 1
setLabel(taps)
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setInteger(taps, forKey: "key")
}
func setLabel(taps:Int) {
ScoreLabel.text = "Taps: \(taps)"
}
}
You have set a breakpoint in your code most probably unintentionally. Just hold and drag it out till you see an 'X' to remove that breakpoint or right click on it and delete/disable breakpoint.
I am trying to implement UITapGestureRecognizer, Idea is that on tap of label I will get a pop up displaying the number to make call and it should come up with pop up alert saying call or cancel!!
Code I've written worked for me in 3 to 4 places but I am stuck at one point
In this screen I have a tableview with prototype cells grouped type here, please check this Image:
Link For Image
Third Cell
Now If I am Tapping 065668982 I have canOpenURL: failed for URL: "telprompt://065668982" - error: "This app is not allowed to query for scheme telprompt" which actually works on iPhone not on simulator and it pulls to call which is working fine.
Second Cell
If I am Tapping 065454858 I have canOpenURL: failed for URL: "telprompt://065668982" - error: "This app is not allowed to query for scheme telprompt" which actually works on iPhone not on simulator and it pulls to call which is working fine.
first Cell
But for first one it never works and end up with fatal error: unexpectedly found nil while unwrapping an Optional value
NOTE : I am Getting phone Number from an API and append the data in view controller to UITableViewCell.
I Hope I make sense, Thanks in advance for any help also if I am not clear please comment below
Here is my code:
import UIKit
import Foundation
class XyzTableViewCell: UITableViewCell
{
#IBOutlet weak var phoneNumber: UILabel!
var touchContact : String = ""
var myCell: MyCellData! {
didSet {
self.updateUI()
}
}
func updateUI()
{
touchContact = vicarCell.phone_no
//Tap Gesture
tapGestureAddonView()
}
//MARK:- Tap to Call and Open Email
func tapGestureAddonView(){
let contacttap = UITapGestureRecognizer(target: self, action:("contactTapped"))
contacttap.numberOfTapsRequired = 1
phoneNumber!.userInteractionEnabled = true
phoneNumber!.addGestureRecognizer(contacttap)
}
func contactTapped() {
// do something cool here
print("contactTapped")
print(touchContact)
dispatch_async(dispatch_get_main_queue())
{
if UIApplication.sharedApplication().canOpenURL(NSURL(string: "telprompt://\(self.touchContact)")!){
UIApplication.sharedApplication().openURL(NSURL(string: "telprompt://\(self.touchContact)")!)
}
else{
//showAlert("Info",message: "Your device could not called" ,owner: self)
}
}
}
The issues: 1) you should add gesture only once 2) you should check NSURL for nil. Let me assume that you use storyboard and improve your code a bit
class XyzTableViewCell: UITableViewCell
{
#IBOutlet weak var phoneNumber: UILabel!
var touchContact : String = ""
var myCell: MyCellData! {didSet {self.updateUI()}}
func updateUI() {
touchContact = myCell.phone_no // did you mean myCell instead vicarCell?
}
override func awakeFromNib() {
super.awakeFromNib()
tapGestureAddonView()
}
func tapGestureAddonView(){
let contacttap = UITapGestureRecognizer(target: self, action: #selector(contactTapped))
contacttap.numberOfTapsRequired = 1
phoneNumber!.userInteractionEnabled = true
phoneNumber!.addGestureRecognizer(contacttap)
}
func contactTapped() {
print("contactTapped")
print(touchContact)
if touchContact.isEmpty {return}
guard let url = NSURL(string: "telprompt://\(touchContact)") else {
print("url string invalid")
return
}
dispatch_async(dispatch_get_main_queue())
{
if UIApplication.sharedApplication().canOpenURL(url){
UIApplication.sharedApplication().openURL(url)
} else{
//showAlert("Info",message: "Your device could not called" ,owner: self)
}
}
}
}
I'm finishing up a simple iOS8 app written in SWIFT which involves numbers being entered in at times. Sometimes the numbers need to be decimals and I noticed that unless I enter a 0 first before the decimal point, the decimal button won't work and nothing will be inputted into the text box.
I was thinking about just making the textbox start with 0, that way the user can just start typing in a decimal without have to enter in 0 by themselves first. I'm hoping there is a simple function that I can just use to solve this problem.
Thanks
Following works:
extension String {
func toDouble() -> Double? {
let fmt = NSNumberFormatter()
return fmt.numberFromString(self)?.doubleValue
}
}
and then in your view controller:
#IBOutlet weak var textField: UITextField!
#IBAction func convert(sender: AnyObject) {
if let d = textField.text.toDouble() {
println("Got a double \(d)")
} else {
println("Not a double \(textField.text)")
}
}
If it doesn't work for you, post more code, the problem is elsewhere.
This question already has answers here:
What does "Fatal error: Unexpectedly found nil while unwrapping an Optional value" mean?
(16 answers)
Closed 2 years ago.
I am trying to run this code but I keep on getting this error:
fatal error: unexpectedly found nil while unwrapping an Optional value
I don't understand what it means or why I'm getting it. Any hint?
import UIKit
class ViewController: UIViewController {
var lastNumber: String = ""
#IBOutlet var answerField: UILabel
#IBOutlet var operaterLabel: UILabel
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 buttonTapped(theButton: UIButton) {
if answerField.text == "0"
{
answerField.text = theButton.titleLabel.text
}
else
{
answerField.text = answerField.text + theButton.titleLabel.text
}
}
#IBAction func plusTapped(theButton: UIButton) {
// error is talking about the next line
if operaterLabel.text == ""
{
operaterLabel.text = "+"
lastNumber = answerField.text
answerField.text = "0"
}
else
{
enterTapped(nil)
operaterLabel.text = "+"
}
}
#IBAction func minusTapped(theButton: UIButton) {
if operaterLabel.text == ""
{
operaterLabel.text = "-"
lastNumber = answerField.text
answerField.text = "0"
}
else
{
enterTapped(nil)
operaterLabel.text = "-"
}
}
#IBAction func clearTapped(AnyObject) {
answerField.text = "0"
operaterLabel.text = ""
lastNumber = ""
}
#IBAction func enterTapped(AnyObject?) {
var num1 = lastNumber.toInt()
var num2 = answerField.text.toInt()
if !num1 || !num2
{
showError()
return
}
var answer = 0
if operaterLabel.text == "-"
{
var answer = num1! - num2!
}
else if operaterLabel.text == "+"
{
var answer = num1! + num2!
}
else
{
showError()
return
}
answerField.text = "\(answer)"
}
func showError()
{
println("Ther was an error")
}
}
the error refers to the fact that you're accessing the parameter of an optional value when the optional value is set to nil (e.g. accessing answerField.text when answerField is nil), likely one of your two UILabels.
If the line operaterLabel.text == "" is throwing the exception, then your operaterLabel is nil. Verify that you have connected it successfully to the label in your Interface Builder file.
In my case, I was trying to access the labels in a function that I created which was used after the set of a variable.
var something: String {
didSet {
updateUI()
}
}
func updateUI() {
label.text = "Hello"
}
I solved it by:
var something: String
override func viewDidLoad() {
label.text = "hello"
}
My theory is that my function updateUI was accessed before the views and labels were created.
some times the problem that you have initiate view controller before present it like this:
let myViewController = MyViewController()
replace that by
let myViewController = self.storyboard?.instantiateViewController(withIdentifier: "storyboardID") as! MyViewController
check your outlets, I've had this before labels and buttons can just become dis connected (if for instance you have adjusted constraints ect)
a simple re connection can sometimes fix the issue
If you make sure the xib for your cell is no problem,
Then I occur this issue, my error was register the cell method :
1)
self.tableView.register(TerantInfoTabCell.self, forCellReuseIdentifier: "TerantInfoTabCell")
2)
self.tableView.register(UINib(nibName:"TerantInfoTabCell", bundle: nil), forCellReuseIdentifier: "TerantInfoTabCell")
I use the first method, there will appear the issue,then I use the 2) method replace the 1) , so there is no problem here.
I had the exact same error and spent quiet an amount of time debugging it. What #jmduke said is really the key: where does the error occur?
With my particular error, looking at operaterLabel.text == "" led me on the right path. I accessed the operaterLabel.text while the view was not yet fully initialized. In my particular case I set a variable from a different view during a segue and then acted upon that variable being set and updating a label inside the view. However the view was not completely initialized.
Thus my solution was to update the label inside the viewDidLoad() function.
I searched and searched trying to figure out how to solve my similar problem. As others mentioned, I was accessing UI elements before they were initialized. But figuring out why, was the difficult part. Spoiler --> I was using ProfileVC.swift and profileVC.xib
Even though I had all of my connections right in IB, from the parentVC I was calling
let newVC = ProfileVC()
profile.modalPresentationStyle = .custom
present(profile, animated: true, completion:nil)
Since I had different names (caplital 'P' in my swift file and lowercase 'p' in my xib), calling ProfileVC() didn't work as it didn't know to go to the xib I had made. Instead I had to use:
let newVC = ProfileVC.init(nibName: "profileVC", bundle: Bundle.main)
or just rename the xib to have a captial P and I could use my original code
Obviously this is hard to see in stackoverflow as you need to see what you are calling in the parent VC, the names of the files and IB. So hopefully this may be one solution to someone's problem out there even if it doesn't solve Arshia's problem.
That means your storyboard doesn't have a link to your IBOUTLET, please verify
I had this error and my problem was caused by adding a member (let's call it newProperty) to my model class, then trying to run a project that loaded data with NSCoder.decodeObjectForKey(newPropertyKey). During previous testing, I had saved objects without newProperty, so when the app tried to call decodeObjectForKey(newPropertyKey) on my old data, Xcode responded with this error message.
This error usually occurs because we try to change UILabel text after the view is loaded. Remember that UILabels once loaded in the view cannot be changed in any way they can only be set within viewdidload() function. You can check this by putting your text assigning code in the viewDidLoad() function which will set UILabels when loading the view, It will work.
But now if your application is built in such a way that it is setting UILabels after the view is loaded then the only solution is that you will need to create UILabels dynamically/Programatically where ever you want in the code and assign what ever you want because they will be created/instantiated with that text/label.
As #aircraft said you can register your cell this way :
let cellNib = UINib(nibName: "\(CellClass.self)", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "\(CellClass.self)")
this solved the problem with me.