[UIButton setText:]: unrecognized selector sent to instance - ios

I have read several answers on this question but can't seem to find one that applies to my code. When I assign the "text" member of "myLabel" (below) I get: "[UIButton setText:]: unrecognized selector sent to instance...." The program compiles OK but then crashes when the assignment statement is encountered.
However I am able to assign and even print out the backgroundColor of the same object. Any ideas on what I am doing wrong?
//********
import UIKit
class ViewController: UIViewController {
//********* Button 1 *********//
#IBOutlet weak var lbl1: UILabel!
#IBAction func btn1(sender: AnyObject) {
nextColorFor1++
makeColor (self.lbl1, nextColor: nextColor1)
}
//**** Button 2 **********//
#IBOutlet weak var lbl2: UILabel!
#IBAction func btn2(sender: AnyObject) {
nextColorFor2++
makeColor (self.lbl2, nextColor: nextColorFor2)
}
//***************************//
func makeColor (myLabel:UILabel, nextColor:Int)
{
switch nextColor
{
case 0: myLabel.backgroundColor = UIColor(red: 0.1, green: 0, blue: 0, alpha: 0.1)
case 1: myLabel.backgroundColor = UIColor(red: 0.2, green: 0, blue: 0, alpha: 0.2)
case 2: myLabel.backgroundColor = UIColor(red: 0.3, green: 0, blue: 0, alpha: 0.3)
case 3: myLabel.backgroundColor = UIColor(red: 0.4, green: 0, blue: 0, alpha: 0.4)
case 4: myLabel.backgroundColor = UIColor(red: 0.5, green: 0, blue: 0, alpha: 0.5)
default: print("end of colors")
}
print(myLabel.backgroundColor)
myLabel.text = "4" <<< --- This is where the crask occurs
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}

It seems like you have connected the UIButton(which is on your storyboard or xib) as as UILabel in the code, and you are trying to treat it as label. Make sure to replace the button on the IB to label, and it will work.

Don't pass the local variable
func makeColor()
{
myLabel.backgroundColor = UIColor(red: 0.1, green: 0, blue: 0, alpha: 0.1)
print(myLabel.backgroundColor)
myLabel.text = "4"
}
#IBAction func myButton(sender: AnyObject) {
makeColor ()
}
Now If you want to set the title for button
#IBOutlet var myButton: UIButton!
#IBAction func myButton(sender: AnyObject)
{
myButton.backgroundColor = UIColor(red: 0.1, green: 0, blue: 0, alpha: 0.1)
myButton.titleLabel?.text = "4"
}

try this to ease the bug in case the origin (xib || storyboard) is unknown
extension UIButton
{
func setText(_ text: String) {
assertionFailure("crashlytics reported Fatal Exception: NSInvalidArgumentException -[UIButton setText:]: unrecognized selector sent to instance 0xyyy objc_exception_throw keyboard_arrow_down")
titleLabel?.text = text
}
}

Related

Is there a way to change all of my IOS App page's Bg Color by using User Defaults?

I am following this tutorial provided on Youtube for: How to Save Data with UserDefaults - Swift
https://www.youtube.com/watch?v=sUhq1vIrRbo
And I have this code that works for one page only and would like to know how to do the same exact thing (changing background color) but for my entire app pages based on the user's choice.
I have tried keeping the checkForStylePreference() in the viewDidLoad()of another page but it did not recognize it. I copy pasted the whole checkForStylePreference() but still other pieces of code were missing. Is the only way to do it is by copy pasting all of the methods of the viewController in all App pages? Or there is a much simpler way as a believe to reduce amount of code? Currently I can change BgColor from white to grey perfectly enter image description here but I don't know how to apply it for all.
This is the code of my NameViewController.swift (the one I've created for the page in the screenshot). Please note that I have 2 more swift files which are SAButton.swift and ConstantStyles.swift (for the colors)
class NameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
nameLbl.text = myString
checkForStylePreference()
}
#IBAction func didChangeStyleSeg(_ sender: UISegmentedControl) {
isDarkMode = sender.selectedSegmentIndex == 1
saveStylePreference()
updateStyle()
}
var myString = String()
#IBOutlet weak var styleSegment: UISegmentedControl!
#IBOutlet weak var nameLbl: UILabel!
var isDarkMode = false
let defaults = UserDefaults.standard
struct Keys {
static let preferDarkMode = "preferDarkMode"
}
func updateStyle(){
UIView.animate(withDuration: 0.4){
// self.view.backgroundColor = self.isDarkMode ? Colors.darkGrey : .white
// UIColor(hue: 287/360, saturation: 15/100, brightness: 85/100, alpha: 1.0)
self.view.backgroundColor = self.isDarkMode ? Colors.lightGrey : .white
//recent correct one
// self.view.backgroundColor = self.isDarkMode ? Colors.darkGrey : .white
//self.view.UIBackgroundFetchResult = self.isDarkMode? UIColor.grey : .white
}
}
func saveStylePreference(){
defaults.set(isDarkMode, forKey: Keys.preferDarkMode)
}
func checkForStylePreference(){
let preferDarkMode = defaults.bool(forKey: Keys.preferDarkMode)
if preferDarkMode{
isDarkMode = true
updateStyle()
styleSegment.selectedSegmentIndex = 1
}
}
// Do any additional setup after loading the view.
}
Code of the SAButton.swift
class SAButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setupButton()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupButton()
}
private func setupButton() {
setTitleColor(.white, for: .normal)
backgroundColor = Colors.lightBlue
titleLabel?.font = .boldSystemFont(ofSize: 20)
layer.cornerRadius = frame.size.height / 2
}
}
Code of the ConstantStyles.swift
import UIKit
struct Colors {
static let darkGrey = UIColor(red: 40/255, green: 40/255, blue: 40/255, alpha: 1)
// static let purple = UIColor(red: 212/255, green: 186/255, blue: 86/255, alpha: 1)
static let lightBlue = UIColor(red: 89/255, green: 205/255, blue: 242/255, alpha: 1)
static let darkPurple = UIColor(red: 242/255, green: 232/255, blue: 255/255, alpha: 1.0)
// UIColor(hue: 287/360, saturation: 15/100, brightness: 85/100, alpha: 1.0)
static let lightPurple = UIColor(red: 240/255, green: 229/255, blue: 255/255, alpha: 1.0)
static let lightGrey = UIColor(red: 237/255, green: 237/255, blue: 237/255, alpha: 1.0)
//UIColor(red: 249/255, green: 244/255, blue: 255/255, alpha: 1.0)
}
I believe it could be simple but I am new to Swift, I would like to know what part of code to keep exactly and where. Much appreciated.
Ps: Original project Source Code is provided below the Youtube Video.
You can create a main class and inherit from it
class GeneralVC : UIViewController {
override func viewDidLoad() {
self.view.backgroundColor = .red // read color from userdefaults and set it here
}
}
class ViewController: GeneralVC {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Same applies to any UIKit component that you need to affect globally
Another interesting way to do it is to use Appearance:
Perhaps you can use UIViewControllerWrapperView as a parent.
UIView.appearance(whenContainedInInstancesOf: [UIViewControllerWrapperView]) // UIViewControllerWrapperView might be private. In that case it might take some wizardry to get it to work
Another way to do it is to set it when the UITabBarController or UINavigationController presents a new UIViewController. You can do this by subclassing them.
The reason why I don't like subclassing is that you force a subclass for just one simple thing. If you only do it in a few navigation based ones it's much easier and also easier to override with extensions instead of everything through subclassing.

How To Store Data Permanently With User Defaults In xCode Swift for toggle button

How can I save the state of my toggle button using userdefaults? Here is the code, please help me.
import UIKit
class LawFigure: UIViewController {
//Outlets:
#IBOutlet weak var likeButton: UIButton!
//Variables:
var isButtonOn = false
override func viewDidLoad() {
super.viewDidLoad()
customiseUI()
}
func customiseUI() {
likeButton.layer.borderWidth = 3.0
likeButton.layer.borderColor = UIColor(red: 0/255, green: 166/255, blue: 221/255, alpha: 1.0).cgColor
likeButton.layer.cornerRadius = 20.0
likeButton.clipsToBounds = true
}
#IBAction func followActionPressed(_ sender: Any) {
self.activateButton(bool: !isButtonOn)
}
func activateButton(bool: Bool) {
isButtonOn = bool
likeButton.backgroundColor = bool ? UIColor(red: 0/255, green: 166/255, blue: 221/255, alpha: 1.0) : .clear
likeButton.setTitle(bool ? "unlike": "like", for: .normal)
likeButton.setTitleColor(bool ? .white : UIColor(red: 0/255, green: 166/255, blue: 221/255, alpha: 1.0), for: .normal)
}
}
You can try every open of the app
likeButton.isEnabled = !(UserDefaults.standard.bool(forKey:"IsBtnEnabled"))
whenever button is clicked save it
UserDefaults.standard.set(state, forKey: "IsBtnEnabled")
var isButtonOn = UserDefaults.standard.bool(forKey: "isButtonOn")
override func viewDidLoad() {
super.viewDidLoad()
activateButton(bool: isButtonOn)
customiseUI()
}
func activateButton(bool: Bool) {
isButtonOn = bool
UserDefaults.standard.set(isButtonOn, forKey: "isButtonOn")
UserDefaults.standard.synchronize()
likeButton.backgroundColor = bool ? UIColor(red: 0/255, green: 166/255, blue: 221/255, alpha: 1.0) : .clear
likeButton.setTitle(bool ? "unlike": "like", for: .normal)
likeButton.setTitleColor(bool ? .white : UIColor(red: 0/255, green: 166/255, blue: 221/255, alpha: 1.0), for: .normal)
}

I am having an issue with PageMenu

I am having that issue when I using PageMenu Framework and put all code for the PageMenu but its showing white space in my controller. Anybody have the solutions for that type of issue.let me know how can I remove it.
Blow I put complete code for PageMenu
import UIKit
import PageMenu
class TradingHistoryVC: UIViewController {
#IBOutlet weak var pagerView: UIView!
var controllerArray : [UIViewController] = []
var pageMenu : CAPSPageMenu?
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.topItem?.title = ""
// Do any additional setup after loading the view.
}
override func viewDidAppear(_ animated: Bool) {
pager()
}
func pager()
{
let buy = storyboard?.instantiateViewController(withIdentifier: "TradingSuccessfullyVCSID") as! TradingSuccessfullyVC
buy.parentNavigationController = navigationController!
buy.title = "Trading Successfully"
controllerArray.append(buy)
let sell = storyboard?.instantiateViewController(withIdentifier: "GlobalTradingVCSID") as! GlobalTradingVC
sell.parentNavigationController = navigationController!
sell.title = "Global Trading"
controllerArray.append(sell)
// Customize menu (Optional)
let parameters: [CAPSPageMenuOption] = [
.scrollMenuBackgroundColor(UIColor(red: 72/255.0, green: 175/255.0, blue: 230/255.0, alpha: 1.0)),
.viewBackgroundColor(UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)),
.selectionIndicatorColor(UIColor(red: 255/255, green: 255/255, blue: 255/255, alpha: 1.0)),
.addBottomMenuHairline(false),
.menuItemFont(UIFont(name: "Times New Roman", size: 16)!),
.menuItemWidth((self.pagerView.frame.width-30)/2),
.menuHeight(50.0),
.enableHorizontalBounce(true),
.menuItemWidthBasedOnTitleTextWidth(false),
.selectedMenuItemLabelColor(UIColor.white),
.unselectedMenuItemLabelColor(UIColor.white),
.menuItemSeparatorWidth(4.5),
.useMenuLikeSegmentedControl(false),
.menuItemSeparatorRoundEdges(true),
.selectionIndicatorHeight(2.0),
.menuItemSeparatorPercentageHeight(0.0),
]
// Initialize scroll menu
pageMenu = CAPSPageMenu(viewControllers: controllerArray, frame: CGRect(x: 0.0, y: 0.0, width: self.pagerView.frame.width, height: self.pagerView.frame.height), pageMenuOptions: parameters)
self.pagerView.addSubview(pageMenu!.view)
// End Pagemenu
}
#IBAction func btnMenuAction(_ sender: Any) {
toggleSideMenuView()
}
}
If anyone have its solutions plz. Please Help to solve it.

How can I properly group and minimize style code for UITextfields?

I'm trying to implement a standard universal styling of my text fields based strictly on the login/sign up fields.
So, I designed them all to be identical, but I think that I'm reusing a lot of code that can be condensed and maybe used in a variable? I'm not sure how to do so.
The way it is works, but i'm sure it can be done better than this. I'm almost certain there's a way to minimize this code for better practice.
I'm still learning, so I really want to learn better practice in dev.
Here's an example of my sign up view & the styling of the fields:
class JoinVC: UIViewController, UITextFieldDelegate {`
#IBOutlet weak var enterEmailTextField: UITextField!
#IBOutlet weak var enterPasswordTextField: UITextField!
#IBOutlet weak var enterNameTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Field Border Corner + Width
self.enterEmailTextField.layer.cornerRadius = 24.0
self.enterEmailTextField.layer.borderWidth = 1.5
self.enterPasswordTextField.layer.cornerRadius = 24.0
self.enterPasswordTextField.layer.borderWidth = 1.5
self.enterNameTextField.layer.cornerRadius = 24.0
self.enterNameTextField.layer.borderWidth = 1.5
// ...
// Field Placeholder ColorEnter
var placeholderEnterEmail = NSAttributedString(string: "Enter Email", attributes: [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)])
var placeholderEnterPass = NSAttributedString(string: "Choose Password", attributes: [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)])
var placeholderEnterName = NSAttributedString(string: "Choose Username", attributes: [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)])
enterEmailTextField.layer.sublayerTransform = CATransform3DMakeTranslation(20, 0, 0);
enterPasswordTextField.layer.sublayerTransform = CATransform3DMakeTranslation(20, 0, 0);
enterNameTextField.layer.sublayerTransform = CATransform3DMakeTranslation(20, 0, 0);
// ...
// Text Field Border color
var borderColor : UIColor = UIColor( red: 255, green: 255, blue:255, alpha: 0.8 )
self.enterPasswordTextField.layer.borderColor = borderColor.CGColor; enterEmailTextField.attributedPlaceholder = placeholderEnterEmail;
self.enterEmailTextField.layer.borderColor = borderColor.CGColor; enterPasswordTextField.attributedPlaceholder = placeholderEnterPass;
self.enterNameTextField.layer.borderColor = borderColor.CGColor; enterNameTextField.attributedPlaceholder = placeholderEnterName;
// ...
}
}
The way I have solved this before, especially if all text fields in the project are:
Always going to have identical attributes,
Always going to be created from the storyboard
is to subclass UITextField and apply the attributes in -awakeFromNib:
class KBTextField: UITextField {
let myAttributes = [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)]
let mySublayerTransform = CATransform3DMakeTranslation(20, 0, 0)
let myBorderColor = UIColor( red: 255, green: 255, blue:255, alpha: 0.8 )
override func awakeFromNib () {
self.layer.sublayerTransform = mySublayerTransform
self.layer.borderColor = myBorderColor.CGColor
self.layer.cornerRadius = 24.0
self.layer.borderWidth = 1.5
self.attributedPlaceholder = NSAttributedString(string: self.placeholder!, attributes: myAttributes)
}
}
Then you can just set the class right on the storyboard (to KBTextField, in this case) and it will take care of all your attributes automatically.
This way, you can ensure that all KBTextFields in your app look identical, as long as you create them through the storyboard.
easy solution for reusable code is a handler
func setupTextField(textField : UITextField, placeHolderString: String)
{
let borderColor = UIColor( red: 1.0, green: 1.0, blue:1.0, alpha: 0.8 )
textField.layer.cornerRadius = 24.0
textField.layer.borderWidth = 1.5
textField.layer.sublayerTransform = CATransform3DMakeTranslation(20, 0, 0);
textField.layer.borderColor = borderColor.CGColor;
textField.attributedPlaceholder = NSAttributedString(string: placeHolderString, attributes: [NSForegroundColorAttributeName : UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)])
}
override func viewDidLoad() {
super.viewDidLoad()
setupTextField(enterEmailTextField, placeHolderString: "Enter Email")
setupTextField(enterPasswordTextField, placeHolderString: "Choose Password")
setupTextField(enterNameTextField, placeHolderString: "Choose Username")
}
Note: UIColor values must be in the range of 0.0 to 1.0
You can use the Extension functionality.
Just create an Extension of UITextField an place your code into that Extension
(easy tutorial here)
Ex:
extension UITextField
{
func setPlaceholderColorAndString(pholder: String, color: UIColor)
{
self.attributedPlaceholder = NSAttributedString(string:pholder,
attributes:[NSForegroundColorAttributeName: color])
}
func setupField()
{
self.layer.cornerRadius = 24.0
self.layer.borderWidth = 1.5
}
}
Then in your code you can use it like:
self.enterEmailTextField.setPlaceholderColorAndString(pholder: "Enter Email", color: UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)
self.enterEmailTextField.setupField()
self.enterPasswordTextField.setPlaceholderColorAndString(pholder: "Enter Password", color: UIColor(red: 255/255, green: 255/255, blue:255/255, alpha: 0.6)
self.enterPasswordTextField.setupField()
And so on. Of course the above snippet it's only to give you an idea how using it, you can improve it a lot to fit your needs.

Change the View BackgroundColor on Tap

I want to change the text and the background color of the view on tap. The quotes are changing, but the view background color don't change. What am I doing wrong?
Here is the code:
import UIKit // UI: user interface
class ViewController: UIViewController {
// IB: Interface Builder
#IBOutlet weak var quoteLabel: UILabel!
var quotes = Quotes()
// gets called when the view is loaded
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
// Interface Builder Action.
// Gets called whenever the user taps on the button
#IBAction func inspireMeDidTap(sender: UIButton)
{
let quote = quotes.randomQuote()
quoteLabel.text = quote
// change the background color of the view
view.backgroundColor = randomColor()
}
func randomColor() -> UIColor
{
let random = Int(arc4random()) % 5 // 0 -> 4
switch random {
case 0: return UIColor(red: 211/255.0, green: 86/255.0, blue: 87/255.0, alpha: 0)
case 1: return UIColor(red: 71/255.0, green: 178/255.0, blue: 137/255.0, alpha: 0)
case 2: return UIColor(red: 229/255.0, green: 177/255.0, blue: 93/255.0, alpha: 0)
case 3: return UIColor(red: 92/255.0, green: 163/255.0, blue: 178/255.0, alpha: 0)
case 4: return UIColor(red: 38/255.0, green: 38/255.0, blue: 38/255.0, alpha: 0)
default: return UIColor(red: 56/255.0, green: 72/255.0, blue: 72/255.0, alpha: 0)
}
}
}
try this:
put all alpha = 1 in your colors (instead of 0).
If alpha = 0, entirely transparent
Meaning of alpha
You are setting alpha parameter to zero it means whatever the color is it will be completely transperent(not white).
So what you need to do is just set alpha to 1 and you will get your correct color

Resources