Found nil while unwrapping an optional value while setting textColor of label - swift3

I am new in ios and I am making an app using XCode 9.2 with swift 3.2.I am facing a problem which is i am setting textColor of label but it show an error which is: Found nil while unwrapping an optional value in line titleBar.textColor = UIColor.white
this happens for all IBOutlet in viewController of this class but in same project other view controller work fine Please help me.
My code is :
#IBOutlet weak var titleBar: UILabel!
override func viewDidLoad()
{
super.viewDidLoad()
titleBar.textColor = UIColor.white
}

The cause of the app crash or found nil is the #IBOutlet is not connected with the storyboard.. somehow the #IBOutlet connection is broken... please check and connect it and then try the code.
*After the connection is done you can use this code -
#IBOutlet weak var titleBar: UILabel! {
didSet {
titleBar.textColor = UIColor.white
}
}

Add self.titleBar.textColor = UIColor.white and also make sure that you have properly bind the IBOutlet in to your class file

Related

Show different Views based on conditions on button click in Swift 3?

I have a ViewControllertheir is a button at top right side. When i click that button i want to Show/Hide a UIView at bottom with size half of ViewControlleron same ViewController . Anyone help me. Thanks in advance.
If only Show/Hide a UIView is your requirement, below code will work:
class ViewController: UIViewController
{
#IBOutlet weak var viewHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var customView: UIView!
override func viewDidLoad()
{
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.viewHeightConstraint.constant = self.view.bounds.height / 2
}
#IBAction func onShowHideButtonPress(_ sender: UIButton)
{
self.customView.isHidden = !self.customView.isHidden
}
}
Storyboard:

UITextField.textColor not called until UITextField gets focus

Could anybody explain please how/when .textColor is called for the UITextField?
XCode9, Swift 4
Consider the following code:
import UIKit
class TestViewController: UIViewController {
#IBOutlet weak var txt1: UITextField!
#IBOutlet weak var txt2: UITextField!
#IBAction func btnaction(_ sender: UIButton) {
txt1.textColor=UIColor.red
txt1.backgroundColor=UIColor.green.withAlphaComponent(0.5)
txt2.textColor=UIColor.red
txt2.backgroundColor=UIColor.green.withAlphaComponent(0.5)
}
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.
}
}
Everything is connected. When you run it and click on the button, only the backgroundColor gets set immediately. The .textColor remains the same. Only when the text field gets a focus, only then the .textColor changes.
Is this correct behaviour or a bug?
Thank you for comments.
I tried the same code in XCode 8, Swift 3 and it worked fine, so I believe it is probably a bug.

Which lifecycle do I activate and deactivate constraints for Swift

I'm struggling with when is the correct time to activate or deactivate constraints in the storyboard.
I've made an extremely simplified view controller showing this issue I'm having.
Basically, there is UIView (the red box) and inside of that is the UIScrollView, and finally inside of that is the label containing the text. The UIScrollView is 15 away from all edges of the red UIView it is inside of. And the UILabel is 0 on all sides from the UIScrollView it is inside of. By default, I have a constraint from the bottom (called bottomConst) of the red UIView to the bottom of the super view. Meaning its always the same distance. And if nothing is changed it will look the following way on both a 4 inch and 4.7 inch screen. This is initiated as isActive = true.
.
As you can see, there is a large amount of blank white space on the 4.7 inch screen.
To fix this I've added a second constraint that controls the height of the red UIView (called heightConst) and this is initiated as isActive = false.
I use the code to check after layoutIfNeeded() if the bounds height of the UIScrollView is taller than the contentSize height of the UIScrollView. And if it is, then it deactivates the bottomConst and activates the heightConst. The problem is, instead of that happening. I end up getting a zero height UIScrollView and a UIView that 30 tall because of the 15 on top and bottom edge constraints.
But if I manually go in and switch them before running them, everything looks correct.
Here is the code I'm using. (see below)
I've tried placing the code in various places such as viewDidLoad, viewDidAppear, viewWillLayoutSubviews, viewDidLayoutSubviews. But none of them seem to work. I'm starting to wonder if I should be calling the LayoutIfNeeded() in a separate lifecycle but there are so many possibilities of how to do that I figured I'd come the people who always seem to know best. Any help would be much appreciated.
import UIKit
class ViewController: UIViewController {
#IBOutlet var bottomConst: NSLayoutConstraint!
#IBOutlet var heightConst: NSLayoutConstraint!
#IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
scrollView.setNeedsLayout()
scrollView.layoutIfNeeded()
let scrollHeight = scrollView.contentSize.height
if (scrollHeight <= scrollView.bounds.height) {
bottomConst.isActive = false
heightConst.constant = scrollHeight + 30
heightConst.isActive = true
view.layoutIfNeeded()
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Well, I was able to find the answer to my problem. But its slightly complicated, and also may depend on how the view controller is setup.
For the case I show above the following code worked.
import UIKit
class ViewController: UIViewController {
#IBOutlet var bottomConst: NSLayoutConstraint!
#IBOutlet var heightConst: NSLayoutConstraint!
#IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.setNeedsLayout()
view.layoutIfNeeded()
let scrollHeight = scrollView.contentSize.height
if (scrollHeight <= scrollView.bounds.height) {
bottomConst.isActive = false
heightConst.constant = scrollHeight + 30
heightConst.isActive = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Turns out putting that code in viewWillAppear was where it needed to go, and marking the view as setNeedsLayout instead of the scrollView. But I also had another case that was very similar to the one I described above except the bottom constraint wasn't to the super view, it was to another UIView. In that case even with using the new code I still got a 0 height scrollView.
After doing some testing, I found that heightConst would remain true after I set it in the above code. But then it would go through the viewWillLayoutSubviews and viewDidLayoutSubviews one final time and in those it would become false again. My work around for that was to modify my code to the following.
import UIKit
class ViewController: UIViewController {
var changeSize: Bool = false //Additional Code
#IBOutlet var bottomConst: NSLayoutConstraint!
#IBOutlet var heightConst: NSLayoutConstraint!
#IBOutlet var scrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.setNeedsLayout()
view.layoutIfNeeded()
let scrollHeight = scrollView.contentSize.height
if (scrollHeight <= scrollView.bounds.height) {
changeSize = true //Addition Code
bottomConst.isActive = false
heightConst.constant = scrollHeight + 30
heightConst.isActive = true
}
}
//Addition Code
override function viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
if (changeSize == true && heightConst.isActive == false) {
heightConst.isActive = true
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
But ultimately, the way I found the work around was to put a print() function in each lifecycle and see what it was reporting that constraint was. That way, I could see when it was going wrong. Hopefully this helps someone else in the future!

IOS 10 - Swift 3.0: Stop the delegated function to save the image

I'm making an App with swift 3, xCode 8.2 and IOS10. The interface has a thermal vision screen (FLIR ONE). My question is, how can I take a photo? My code is:
import UIKit
class ThermalCameraVC: UIViewController, FLIROneSDKImageReceiverDelegate, FLIROneSDKStreamManagerDelegate {
//MARK: OUTLETS
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var labelStatusCamera: UITextField!
#IBOutlet weak var labelCargeCamera: UITextField!
#IBOutlet weak var icnCancelPicture: UIButton!
#IBOutlet weak var icnUploadPicture: UIButton!
#IBOutlet weak var iconTakePicture: UIButton!
//MARK: VARIABLES
var simulatorStatus = false
var cameraBussy = false
override func viewDidLoad() {
super.viewDidLoad()
FLIROneSDKStreamManager.sharedInstance().addDelegate(self)
FLIROneSDKStreamManager.sharedInstance().imageOptions = FLIROneSDKImageOptions(rawValue: FLIROneSDKImageOptions.blendedMSXRGBA8888Image.rawValue)!
icnCancelPicture.isHidden = true
icnUploadPicture.isHidden = true
}
//MARK: CANCEL PICTURE
#IBAction func cancelPicture(_ sender: Any) {
cameraBussy = false
}
//MARK: UPLOAD PICTURE AMAZON S3
#IBAction func uploadPicture(_ sender: Any) {
}
func flirOneSDKDelegateManager(_ delegateManager: FLIROneSDKDelegateManager!, didReceiveBlendedMSXRGBA8888Image msxImage: Data!, imageSize size: CGSize){
let image = FLIROneSDKUIImage(format: FLIROneSDKImageOptions.blendedMSXRGBA8888Image, andData: msxImage, andSize: size)
//HERE I NEED TO STOP THE DELEGATED FUNCTION TO SAVE THE IMAGE !!
if self.cameraBussy{
//cameraBussy = false
}else{
DispatchQueue.main.async{
self.imageView.image = image
}
}
}
#IBAction func takeThermalPicture(_ sender: Any) {
cameraBussy = true
icnCancelPicture.isHidden = false
icnUploadPicture.isHidden = false
iconTakePicture.isHidden = true
}
}
How can I stop the flow of data in this delegated function? Because it is continually calling.
Set the delegate value to nil.
#IBAction func takeThermalPicture(_ sender: Any) {
FLIROneSDKStreamManager.sharedInstance().addDelegate(nil)
cameraBussy = true
icnCancelPicture.isHidden = false
icnUploadPicture.isHidden = false
iconTakePicture.isHidden = true
}

SWIFT : Display label

I begin to learn swift language and i've a problem.
I try to display a label when i put the button. I show you :
#IBAction func nextRule(sender : UIButton) {
rule = Rules(game: Int(randomNumber))
}
#IBOutlet var lTitle: UILabel!
#IBOutlet var lRule: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
lTitle.text = rule.title
lRule.text = rule.rule
Rules(game: Int) contain a model whith "title" And "rule"
When i press the button, i want to display a new Rule, is it possible by doing something like his?
Thanks for your answer.
How about assign your rule to lTitle and lRule like this
#IBAction func nextRule(sender : UIButton) {
rule = Rules(game: Int(randomNumber))
lTitle.text = rule.title
lRule.text = rule.rule
}