How to add property to UIButton? - ios

thanks for all help:)! fixed it using iboutlet collection and add properies on viewDidLoad
I'm trying to add properties to keyboard keys like layer.shadowColor or layer.shadowRadius.
I got an error
'Value of type '(UIButton)' -> () has no member 'layer'
how to fix this ?
this is my code keyboardViewController.swift
import UIKit
class KeyboardViewController: UIInputViewController {
var newKeyboardView: UIView!
#IBAction func keyPressed(sender: UIButton) {
}
#IBOutlet var nextKeyboardButton: UIButton!
override func updateViewConstraints() {
super.updateViewConstraints()
// Add custom view sizing constraints here
}
override func viewDidLoad() {
super.viewDidLoad()
loadInterface()
}
func loadInterface() {
// load the nib file
let keyboardNib = UINib(nibName: "newKeyboard", bundle: nil)
// instantiate the view
newKeyboardView = keyboardNib.instantiateWithOwner(self, options: nil)[0] as! UIView
// add the interface to the main view
view.addSubview(newKeyboardView)
// copy the background color
view.backgroundColor = newKeyboardView.backgroundColor
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated
}
override func textWillChange(textInput: UITextInput?) {
// The app is about to change the document's contents. Perform any preparation here.
}
override func textDidChange(textInput: UITextInput?) {
// The app has just changed the document's contents, the document context has been updated.
var textColor: UIColor
let proxy = self.textDocumentProxy
if proxy.keyboardAppearance == UIKeyboardAppearance.Dark {
textColor = UIColor.whiteColor()
} else {
textColor = UIColor.blackColor()
}
self.nextKeyboardButton.setTitleColor(textColor, forState: .Normal)
}
}

I think that in order to apply some style to the button, you need an outlet to this button.
Right now, from what I can understand, you are trying to apply styles to the button from the #IBAction to the sender, which is not the proper way to do it.
Try to make an outlet to the button in the view controller and then to apply the styles from within the viewDidLoad method.
I hope this is clear, but if you want a more specific answer you need to show us what you tried, for example pasting the code you have in the view controller
EDIT:
Based on the code you post, the keyboard is a Nib you instantiate from loadInterface(). I don't have a clear vision of the whole thing with only this piece of code, but it seems to me that you are trying to apply some styles to every key button of a keyboard view. Unfortunately this really depends on how the keyboard is implemented, can you provide some more details?
Anyway, from what I see I think you didn't write this code: probably you are following a tutorial or maintaining someone else's code. That's ok, but I suggest you to follow a an introduction course to iOS development with Swift, like the Udacity's one, which is fantastic IMHO (https://www.udacity.com/course/intro-to-ios-app-development-with-swift--ud585)

If you try to format your UIButton with QuartzCore framework, you'll need to import it first:
import QuartzCore
Then you will be able to access those members.
For example (latest swift3 code):
#IBAction func keyPressed(sender: UIButton) {
let button = sender as UIButton!
button?.backgroundColor = UIColor.red
button?.layer.shadowColor = UIColor.black.cgColor
button?.layer.shadowRadius = 1.0
button?.layer.cornerRadius = 4.0
}
In case you need to apply your styles sooner, try to consider to put this code into viewDidLoad or viewDidAppear methods:
self.nextKeyboardButton.backgroundColor = UIColor.red
self.nextKeyboardButton.layer.shadowColor = UIColor.black.cgColor
self.nextKeyboardButton.layer.shadowRadius = 1.0
self.nextKeyboardButton.layer.cornerRadius = 4.0

Seems like you're trying to "add property" not to a button, but rather to a closure which accepts a button as an argument.
Make it like this:
nextKeyboardButton.layer.shadowColor = UIColor.redColor.cgColor
nextKeyboardButton.layer.shadowRadius = 5.0

Related

How to change the color of all Labels in a UIView in Swift?

I found a similar question here. But the problem is it is in OBJ-C. I do not know the code and am working in SWIFT so please can anyone explain and translate this code in swift.
I am still new to swift so please help me.
Regards
Create
var globalColor = UIColor.red
class CustomLbl:UILabel {
override func awakeFromNib() { // inside IB
super.awakeFromNib()
self.textColor = globalColor
}
override func draw(_ rect: CGRect) { // programmatically
super.draw(rect)
self.textColor = globalColor
}
}
And assign it in IB or code , for programmatically call
self.view.setNeedsDisplay()
after you change global color
with an extension. Maybe its not the perfect solution but once you applied it to all needed labels, then it applies to all labels when you make a change. Create a new swift file and put the following code in:
import UIKit
extension UILabel {
func labelColor() {
self.textColor = UIColor.red //or whichever color you want
}
}
And in the viewDidLoad or viewWillLoad you can do:
yourLabel.labelColor()
self.view.subviews.forEach { (view) in // Loop
if let label = view as? UILabel { // check the type
label.textColor = .red // assign the color
}
}
And self is your viewController
As explain in the similar question, you have to
Loop through all the UIView's in self.view.subviews and check if it's
of type UILabel.

How to implement didTapCheckBox of BEMCheckBox IOS Library?

I am new in Ios and i am having hard time wrapping my head around protocols and delegates concept. I am implementing a library called BEMCheckBox https://github.com/Boris-Em/BEMCheckBox or https://cocoapods.org/pods/BEMCheckBox for implementing radio buttons. Its documentation is pretty descriptive using which i have successfully added checkboxes, grouped them together to work as radio boxes.
#IBOutlet var inarelashipcb: BEMCheckBox!
#IBOutlet var complicatedcb: BEMCheckBox!
#IBOutlet var singlecb: BEMCheckBox!
var groupbx:BEMCheckBoxGroup!
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
}
Now i want to use didTapCheckBox method but i donot understand how. The documentation is blurry there no snippets for that. For the record this is what the documentation states
"BEMCheckBox uses a delegate to receive check box events. The delegate object must conform to the BEMCheckBoxDelegate protocol, which is composed of two optional methods:
didTapCheckBox:
Sent to the delegate every time the check box gets tapped, after its properties are updated (on), but before the animations are completed."
Any snippets to help me use delgate so i can implement didTapCheckBox method?
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
for checkbox in groupbx {
checkbox.delegate = self
}
}
must call initialize in viewDidLoad of the viewController
override func viewDidLoad() {
// Do your work
initialize()
}
compiler will show you an error, error will be gone if you add this codes
extension ViewController : BEMCheckBoxDelegate {
func didTap(_ checkBox: BEMCheckBox) {
//do your work
// if you have multiple checkboxes, then do like that
//if checkBox == checkBox1 {
//do work for checkbox1
//} else if {
// ..
//}
}
}
Don't forget to add the following line
import BEMCheckBox
The outlet checkbox you have declared, set delegate to self.
For eg, if your checkbox outlet is checkbox1 set its delegate as
checkbox1.delegate = self
I solve it.
using this code
func initialize(){
groupbx = BEMCheckBoxGroup(checkBoxes: [inarelashipcb,
complicatedcb, singlecb])
groupbx.selectedCheckBox = singlecb
groupbx.mustHaveSelection = true
inarelashipcb.delegate = self
complicatedcb.delegate = self
singlecb.delegate = self
}
func didTap(_ checkBox: BEMCheckBox) {
print("here hello")
}
Also my uiviewcontroller inherited from BEMCheckBoxDelegate

Access TextField from another class or method without storyboard

Okay, this might be one of the most basic questions ever, but all answers I find use storyboard to declare an outlet for a label, textfield or whatever element that needs to be changed. I, however, don't use storyboards and write everything in code. Now I have a function setupViews, where I define a textfield:
let usernameInput = UITextField()
Now, I can perfectly set the text or placeholder or whatever inside this setupViews() class, but how can I access it outside? For example, if I have a function logIn(), I want to call usernameInput.text and use it in this function.
Someone who can point me in the right direction? Do I need to declare this textfield globally, in another file, or something else?
When I create my views in code I always associate a property with the view that has all those various display values.
I have not tested this code to see but hopefully the following will give you an idea.
import UIKit
struct {
var name: String
}
class CustomViewController : UIViewController {
// some struct which contains data for view
var customViewData : ViewDataInfo? {
didSet {
labelOnScreen.text = customViewData.name
}
}
var labelOnScreen: UILabel = {
let label = UILabel()
label.text = "Placeholder information..."
// stuff auto layout
label.translateAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
setupView()
}
private func setupView() {
view.addSubview(label)
// set your constraints here
}
}

Swift 3 - If else statement based on button state

I am really new to Swift and working on my first project (I have a bit of experience with Javascript and web development). I have run into trouble (going on 4 hours of trying different solutions).
I have an app where when a UIButton is pushed it logs a value to FireBase (ON). When it is pushed a second time it logs (OFF) to the database.
When I make the button change the view.backgroundColor and put if else tied to the colour it works.
But I can't for the life of me figure out how to build my if else based on the state of the button. I have now ended up trying to change the colour of the button itself and tie the if else to that. Which I know is a really messy improper way to go about it.
import UIKit
import Firebase
import FirebaseDatabase
class ViewController: UIViewController {
#IBAction func OnOffButton(_ sender: UITapGestureRecognizer){
if button.backgroundColor == UIColor.white {
OnOff(state:"ON")
OnOffButton.backgroundColor = UIColor.blue
} else{
OnOff(state:"OFF")
OnOffButton.backgroundColor = UIColor.white
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
OnOff(state: "Off")
OnOffButton.backgroundColor = UIColor.white
}
UIButton inherits from UIControl which has an isSelected property. Use this to track state. Typically you'll use button.isSelected == true to correspond to your on state, and false is your off state.
To toggle state you can use button.isSelected = !button.isSelected.
For your specific example:
// User pressed the button, so toggle the state:
button.isSelected = !button.isSelected
// Now do something with the new state
if button.isSelected {
// button is on, so ...
} else {
// button is off, so...
}
Here’s a quick and dirty implementation of Duncan C’s suggestion to use a buttonIsSelected variable to store the button state:
import UIKit
class ViewController: UIViewController {
var buttonIsSelected = false
#IBOutlet weak var onOffButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
updateOnOffButton()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func onOffButtonTapped(_ sender: Any) {
buttonIsSelected = !buttonIsSelected
updateOnOffButton()
}
func updateOnOffButton() {
if buttonIsSelected {
onOffButton.backgroundColor = UIColor.blue
}
else {
onOffButton.backgroundColor = UIColor.white
}
}
}
Par's solution should work. However, I would suggest a different approach.
In general it's not good design to store state in a view object. It's fragile, and doesn't follow the MVC design pattern, where view objects display and collect state information, not store it.
Instead I would create an instance variable in your view controller, buttonIsSelected. Toggle that when the button is tapped, and have it change the state of the button's selected property, the button's color, AND log the new state to FireBase.
If you store more complex state in your view controller it would be worth separating that out into a model object. It can be as simple as a struct that holds the different state values. That way you have a clear separation between your controller (view controller) and model.

Click button in a UIViewController that was loaded a subView (UIView)

I'm trying to add a UIView subview into a UIViewController, and that UIView has a UISwitch that I want the user to be able to toggle. Based on the state, a UITextField's value will toggle back and forth. Here is the subview (InitialView):
import UIKit
class InitialView: UIView {
// All UI elements.
var yourZipCodeSwitch: UISwitch = UISwitch(frame: CGRectMake(UIScreen.mainScreen().bounds.width/2 + 90, UIScreen.mainScreen().bounds.height/2-115, 0, 0))
override func didMoveToSuperview() {
self.backgroundColor = UIColor.whiteColor()
yourZipCodeSwitch.setOn(true, animated: true)
yourZipCodeSwitch.addTarget(ViewController(), action: "yourZipCodeSwitchPressed:", forControlEvents: UIControlEvents.TouchUpInside)
self.addSubview(yourZipCodeSwitch)
}
}
If I want to have it's target properly pointing at the below function, where should I either set the target or include this function? I tried:
Setting the target in the UIViewController instead of the UIView
Keeping the function in the UIView
Here's the function:
// Enable/disable "Current Location" feature for Your Location.
func yourZipCodeSwitchPressed(sender: AnyObject) {
if yourZipCodeSwitch.on
{
yourTemp = yourZipCode.text
yourZipCode.text = "Current Location"
yourZipCode.enabled = false
}
else
{
yourZipCode.text = yourTemp
yourZipCode.enabled = true
}
}
And here is where I'm loading it into the UIViewController:
// add initial view
var initView : InitialView = InitialView()
// Execute on view load
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
view.addSubview(initView)
}
Any help is much appreciated - thanks!
Yeah, the didMoveToSuperView() placement doesn't make much sense. So you're creating a random, totally unconnected ViewController instance to make the compiler happy but your project sad. Control code goes in controllers, view code goes in views.
You need in your real ViewController:
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(initView)
// Note 'self' is the UIViewController here, so we got the scoping right
initView.yourZipCodeSwitch.addTarget(self, action: "yourZipCodeSwitchPressed:", forControlEvents: .ValueChanged)
}
Also, .TouchUpInside is for UIButtons. Toggle switches are much more complicated, so their events are different. Touching up inside on a toggle switch's current setting can and should do nothing, whereas touchup inside on the opposite setting triggers the control event above. iOS does all the internal hit detection for you.

Resources