Add button programmatically - ios

I want to make a button appear when there are 1 or more characters in a text field.
Currently, I have 3 problems:
I can't use the #objc if I do that then I get the following error "#objc can only be used with members of classes, #objc protocols, and concrete extensions of classes".
So basically I can't use the button.
I want to add constraints to the button, but on some of those I want the Safe Area to be the "toItem" but I don't know which "name" it has for that, I used view.safeAreaInsets but I'm not sure if that's the right way to do it.
I want to check how many characters there are in a text field (so I want the button to appear the moment that the user types a letter).
I would think it has to be done in an if statement but I don't know how to check for the characters in a text field.
This is my code for the first problem:
addButton.addTarget(self, action: #selector(buttonAction(_ :)), for: .touchUpInside)
self.view.addSubview(addButton)
#objc func buttonAction(_ : UIButton) {
}
This is for the second one:
let buttonRightConstraint = NSLayoutConstraint(item: addButton, attribute: .right, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view.safeAreaInsets, attribute: .right, multiplier: 1.0, constant: 16)
let buttonTopConstraint = NSLayoutConstraint(item: addButton, attribute: .top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view.safeAreaInsets , attribute: .top , multiplier: 1.0, constant: 16)
This is for the third one:
if (TextFieldName.text!.count > 0) {
}
This is my total code:
import UIKit
extension AddWorkoutController {
func hideKeyboard() {
let tap:UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
view.addGestureRecognizer(tap)
}
#objc func dismissKeyboard() {
view.endEditing(true)
}
}
class AddWorkoutController: UIViewController {
#IBOutlet weak var TextFieldName: UITextField!
let addButton = UIButton(type: UIButton.ButtonType.custom) as UIButton
override func viewDidLoad() {
super.viewDidLoad()
configureTextFields()
self.hideKeyboard()
addButton.setBackgroundImage(UIImage(named: "Add-Button"), for: UIControl.State.normal)
addButton.setTitle("", for: UIControl.State.normal)
let buttonRightConstraint = NSLayoutConstraint(item: addButton, attribute: .right, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view.safeAreaInsets, attribute: .right, multiplier: 1.0, constant: 16)
let buttonTopConstraint = NSLayoutConstraint(item: addButton, attribute: .top, relatedBy: NSLayoutConstraint.Relation.equal, toItem: view.safeAreaInsets , attribute: .top , multiplier: 1.0, constant: 16)
let buttonHeightConstraint = NSLayoutConstraint(item: addButton, attribute: .height, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 32)
let buttonWidthConstraint = NSLayoutConstraint(item: addButton, attribute: .width, relatedBy: NSLayoutConstraint.Relation.equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 64)
addButton.addTarget(self, action: #selector(buttonAction(_ :)), for: .touchUpInside)
self.view.addSubview(addButton)
self.view.addConstraints([buttonRightConstraint, buttonTopConstraint, buttonHeightConstraint, buttonWidthConstraint])
#objc func buttonAction(_ : UIButton) {
}
if (TextFieldName.text!.count > 0) {
}
}
private func configureTextFields () {
TextFieldName.delegate = self
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
extension UIViewController: UITextFieldDelegate {
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Maybe it sounds like a stupid question but I'm a beginner.​

#objc func buttonAction(_ : UIButton)
is a function and she must be outside of viewDidLoad, at the same level
class AddWorkoutController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#objc func buttonAction(_ : UIButton) {
}
}
For me the best solution is to add your addButton in the storyboard with hidden property checked by default (select your button and then go to right panel > Show the attributes inspector > hidden property)
You must add func textFieldDidEndEditing(_ textField: UITextField) in your AddWorkoutController extension. Inside you can add your if (TextFieldName.text!.count > 0) and then change isHidden property of addButton (addButton.isHidden)
extension AddWorkoutController: UITextFieldDelegate {
public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidEndEditing(_ textField: UITextField) {
}
}
PS: Be carefull of your indentation for more lisibility and in general variable are written in camelCase You'll find some best practice here => https://github.com/raywenderlich/swift-style-guide

Related

How to unwrap programmed UIButton (swift4)

I am trying to create a button using programmed constraints. I am trying to not use the storyboard. I am having trouble unwrapping the button. How do I do this?
import UIKit
var aa: [NSLayoutConstraint] = []
class ViewController: UIViewController {
var btn: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(btn)
let leadingc2 = btn.widthAnchor.constraint(equalToConstant: 80)
let trailingC2 = btn.heightAnchor.constraint(equalToConstant: 50)
let topc2 = btn.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -50)
let bottomc2 = btn.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)
aa = [leadingc2,trailingC2,topc2,bottomc2]
NSLayoutConstraint.activate(aa)
}
}
You do not need to unwrap it. You need to instantiate it before using it.
override func viewDidLoad() {
super.viewDidLoad()
btn = UITextField() // Create the button like this before using it.
self.view.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false
let leadingc2 = btn.widthAnchor.constraint(equalToConstant: 80)
let trailingC2 = btn.heightAnchor.constraint(equalToConstant: 50)
let topc2 = btn.centerXAnchor.constraint(equalTo: self.view.centerXAnchor, constant: -50)
let bottomc2 = btn.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -250)
aa = [leadingc2,trailingC2,topc2,bottomc2]
NSLayoutConstraint.activate(aa)
}
Any variable declared with ! will be force unwrapped, meaning that if you forget to create an instance and use the variable, it will throw an error and crash your app.
Use this code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
setupConstraints()
}
lazy var button: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Button", for: .normal)
button.backgroundColor = .blue
//your action here
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
return button
}()
private func setupConstraints() {
button.translatesAutoresizingMaskIntoConstraints = false
let top = NSLayoutConstraint(item: button, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 100)
let left = NSLayoutConstraint(item: button, attribute: .left, relatedBy: .equal, toItem: view, attribute: .left, multiplier: 1, constant: 50)
let right = NSLayoutConstraint(item: button, attribute: .right, relatedBy: .equal, toItem: view, attribute: .right, multiplier: 1, constant: -50)
let height = NSLayoutConstraint(item: button, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 50)
view.addConstraints([top, left, right, height])
}
#objc func buttonAction() {
print("Button has pressed")
}
}

Button loaded from xib addTarget not performing action

I'm having a problem when I want to add a target to a button from a loaded xib.
I have this:
var cleanFilters = FilterLabelView()
override func viewWillAppear(_ animated: Bool) {
navigationItem.title = "EXPLORE WORKOUTS"
self.navigationController!.navigationBar.titleTextAttributes = [NSFontAttributeName: UIFont(name: "OpenSans-CondensedBold", size: 16.0)!]
setFilterLabel()
}
func setFilterLabel() {
cleanFilters = (Bundle.main.loadNibNamed("FilterLabelView", owner: self, options: nil)?.first as? FilterLabelView)!
self.view.addSubview(cleanFilters)
cleanFilters.translatesAutoresizingMaskIntoConstraints = false
self.view.addConstraint(NSLayoutConstraint(item: cleanFilters, attribute: .top, relatedBy: .equal, toItem: self.topLayoutGuide, attribute: .bottom, multiplier: 1, constant: 30))
self.view.addConstraint(NSLayoutConstraint(item: cleanFilters, attribute: .trailingMargin, relatedBy: .equal, toItem: self.view, attribute: .trailingMargin, multiplier: 1, constant: 35))
cleanFilters.deleteButton.addTarget(self, action: #selector(hideFilterLabel), for: .touchUpInside)
cleanFilters.confirmButton.addTarget(self, action: #selector(setDefaultFilters), for: .touchUpInside)
cleanFilters.isHidden = defaultsManager.isDefaultFilters()
if !cleanFilters.isHidden {
self.workoutsCollection.isUserInteractionEnabled = false
}
}
func hideFilterLabel() {
cleanFilters.isHidden = true
self.workoutsCollection.isUserInteractionEnabled = true
}
func setDefaultFilters() {
defaultsManager.setDefaultFilters()
cleanFilters.isHidden = true
getAllWorkouts()
}
The deleteButton and confirmButton actions are not being called and I can't figure out why.
Here's the FilterLabelView I'm loading:
import UIKit
class FilterLabelView: UIView {
#IBOutlet weak var deleteButton: UIButton!
#IBOutlet weak var confirmButton: UIButton!
#IBOutlet weak var labelTapRecongnizer: UITapGestureRecognizer!
}
Are you sure that your buttons are not hidden? remember that if a button is hidden the hittest can't perform touches... is it also posible your buttons are really little or have isUserInteractionEnabled as false... A good way to be aware whether is a problem with the view is looking out the Debug view hierarchy

Two UISlider and UILabel setting them programmatically but does not know which slider is slides

I have an iOS project in which I am setting up two sliders and corresponding labels.
Labels are for the slider value. When they slide, the value in the labels change.
I have another class in which I set the slider and label after they create and save that instance in the array. The difficulty I face is when I slide the slider, I do not know which slider is slides.
Here is code:
SliderWidget Class
class SliderWidget {
private var label: UILabel?
private var slider: UISlider?
public func setLable(label: UILabel) {
self.label = label
}
public func setSlider(slider: UISlider) {
self.slider = slider
}
public func getLabel() -> UILabel {
return self.label!
}
public func getSlider() -> UISlider {
return slider!
}
}
Here is the controller on which I set slider and label
class WidgetsVC: UIViewController {
private let step: Float = 10
private var labels: UILabel?
private var sliderArray: Array<SliderWidget> = Array()
override func viewDidLoad() {
super.viewDidLoad()
displaySlider(sliderY: 100,labelY: 70)
displaySlider(sliderY: 200, labelY: 170)
}
private func displaySlider(sliderY: Int, labelY: Int) {
let slider = UISlider()
slider.tintColor = #colorLiteral(red: 0.2980392277, green: 0.6862744689, blue: 0.3137254715, alpha: 1)
let label = displayLabel(labelY: labelY, slider: slider)
view.addSubview(slider)
let horizonalContraints =
NSLayoutConstraint(item: slider, attribute: .leadingMargin,
relatedBy: .equal, toItem: view,
attribute: .leadingMargin, multiplier: 1.0,
constant: 20)
let horizonal2Contraints =
NSLayoutConstraint(item: slider, attribute: .trailingMargin,
relatedBy: .equal, toItem: view,
attribute: .trailingMargin, multiplier: 1.0,
constant: -20)
let pinTop =
NSLayoutConstraint(item: slider, attribute: .top,
relatedBy: .equal, toItem: view,
attribute: .top, multiplier: 1.0,
constant: CGFloat(sliderY))
slider.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([horizonalContraints, horizonal2Contraints, pinTop])
slider.addTarget(self, action: #selector(WidgetsVC.sliderValueDidChange(_:)), for: .valueChanged)
}
private func displayLabel(labelY: Int, slider: UISlider) -> UILabel {
let label = UILabel()
label.text = "0"
labels = label
view.addSubview(label)
let temp = SliderWidget()
temp.setLable(label: label)
temp.setSlider(slider: slider)
sliderArray.append(temp)
let horizonalContraints =
NSLayoutConstraint(item: label, attribute: .leadingMargin,
relatedBy: .equal, toItem: view,
attribute: .leadingMargin, multiplier: 1.0,
constant: 20)
let pinTop =
NSLayoutConstraint(item: label, attribute: .top,
relatedBy: .equal, toItem: view,
attribute: .top, multiplier: 1.0,
constant: CGFloat(labelY))
label.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([horizonalContraints, pinTop])
return label
}
}
I am not sure what do you want for exactly but you could do it in this way
#objc func sliderValueDidChange(slider: UISlider) {
print(slider.tag)
let changedSliderWidget = sliderArray.filter { (sliderWidget) -> Bool in
return sliderWidget.getSlider() == slider
}.last
}
changedSliderWidget will contain the widget that you need
The easy way to identify each one is to set tag values:
displaySlider(sliderY: 100,labelY: 70, tag: 1)
displaySlider(sliderY: 200, labelY: 170, tag: 2)
And
private func displayLabel(labelY:Int,slider:UISlider, tag: Int)->UILabel{
let label=UILabel()
label.tag = tag
label.text="0"
....
So you can identify the sliders with their .tag value.

Why is a UIButton consuming touches but not a UIControl

I have some custom buttons in a table view cell.
These buttons are contained by another view which does not take up the whole cell.
I want the buttons to always respond to taps (and consume the tap so that the cell is not selected at the same time).
I want my button container view to consume taps that are not on the buttons themselves (so that the cell is not selected).
I want anywhere in the cell outside my buttons container to select the cell as per usual.
To this end, I have attached a gesture recogniser to my buttons container view.
This has the desired effect, as long as my buttons are UIButtons (ie tapping the button itself cause a TouchUpInside event on the button, tapping anywhere else in the buttons container does nothing and tapping anywhere else in the cell, outside the buttons container, causes the cell to be selected). However, if I use a UIControl instead of a UIButton then this is no longer the case — the control never responds to tapping (the buttons container always consumes the tap and tapping outside the buttons container, in the cell, causes the cell to be selected). It should be noted that if I do not add a gesture recogniser to my buttons container then the control responds to taps in the same way as a UIButton.
My only explanation is that a UIButton (which inherits from UIControl) somehow adds some extra touch handling. In which case I would like to know what it does and how I should emulate it (I need to use a UIControl instead of a UIButton because my button has a custom view hierarchy for which I do not want to play around in the UIButton).
The code below for a view controller should allow anyone to reproduce the problem:
class ViewController: UITableViewController, UIGestureRecognizerDelegate {
lazy var containerView: UIView = {
let view: UIView = UIView()
view.backgroundColor = UIColor.redColor()
view.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(self.buttonContainerView)
view.addConstraints([
NSLayoutConstraint(item: self.buttonContainerView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.buttonContainerView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.buttonContainerView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.TopMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.buttonContainerView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1.0, constant: 0.0)
])
return view
}()
lazy var buttonContainerView: UIView = {
let view: UIView = UIView()
view.backgroundColor = UIColor.blueColor()
view.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(self.control)
view.addSubview(self.button)
view.addConstraints([
NSLayoutConstraint(item: self.control, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 0.5, constant: 0.0),
NSLayoutConstraint(item: self.control, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.button, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1.5, constant: 0.0),
NSLayoutConstraint(item: self.button, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1.0, constant: 0.0)
])
return view
}()
lazy var control: UIControl = {
let view: UIControl = TestControl(frame: CGRectZero)
view.addTarget(self, action: Selector("controlTapped:"), forControlEvents: UIControlEvents.TouchUpInside)
return view
}()
lazy var button: UIButton = {
let view: UIButton = UIButton.buttonWithType(UIButtonType.Custom) as! UIButton
view.setTitle("Tap button", forState: UIControlState.Normal)
view.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addTarget(self, action: Selector("buttonTapped:"), forControlEvents: UIControlEvents.TouchUpInside)
return view
}()
func controlTapped(sender: UIControl) -> Void {
println("Control tapped!")
}
func buttonTapped(sender: UIButton) -> Void {
println("Button tapped!")
}
var recogniser: UITapGestureRecognizer?
var blocker: UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.rowHeight = 200.0
self.containerView.layoutMargins = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
let recogniser: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("tappedContainer:"))
recogniser.delegate = self
self.recogniser = recogniser
self.containerView.addGestureRecognizer(recogniser)
let blocker: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("tappedBlocker:"))
blocker.delegate = self
self.blocker = blocker
self.buttonContainerView.addGestureRecognizer(blocker)
}
func tappedContainer(recogniser: UIGestureRecognizer) -> Void {
println("Tapped container!")
}
func tappedBlocker(recogniser: UIGestureRecognizer) -> Void {
println("Tapped blocker!")
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let identifier: String = "identifier"
let cell: UITableViewCell
if let queuedCell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(identifier) as? UITableViewCell {
cell = queuedCell
}
else {
cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: identifier)
cell.contentView.layoutMargins = UIEdgeInsets(top: 10.0, left: 10.0, bottom: 10.0, right: 10.0)
cell.contentView.backgroundColor = UIColor.purpleColor()
cell.contentView.addSubview(self.containerView)
cell.contentView.addConstraints([
NSLayoutConstraint(item: self.containerView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.containerView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.TrailingMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.containerView, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.TopMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: self.containerView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: cell.contentView, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1.0, constant: 0.0)
])
}
return cell
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: true)
println("selected cell")
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
}
class TestControl: UIControl {
override init(frame: CGRect) {
super.init(frame: frame)
let view: UIControl = self
let label: UILabel = UILabel()
label.text = "Tap control"
label.userInteractionEnabled = false
view.layer.borderColor = UIColor.orangeColor().CGColor
view.layer.borderWidth = 2.0
view.setTranslatesAutoresizingMaskIntoConstraints(false)
label.setTranslatesAutoresizingMaskIntoConstraints(false)
view.addSubview(label)
view.addConstraints([
NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Top, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.TopMargin, multiplier: 1.0, constant: 5.0),
NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.GreaterThanOrEqual, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 0.0),
NSLayoutConstraint(item: label, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.LessThanOrEqual, toItem: view, attribute: NSLayoutAttribute.BottomMargin, multiplier: 1.0, constant: 0.0)
])
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
EDIT
To be clear, I am not looking for an alternative solution which 'just works' — I want to understand what this difference is and what I should be doing to emulate it, or potentially another semantically correct way.
My only explanation is that a UIButton (which inherits from UIControl) somehow adds some extra touch handling.
You are correct that UIButton is special. I did some research while answering a related question a while back and the reason why the button's event fires is mentioned in the Event Handling Guide for iOS: Gesture Recognizers' "Interacting with Other User Interface Controls" section:
In iOS 6.0 and later, default control actions prevent overlapping gesture recognizer behavior. For example, the default action for a button is a single tap. If you have a single tap gesture recognizer attached to a button’s parent view, and the user taps the button, then the button’s action method receives the touch event instead of the gesture recognizer.
It then lists examples and a single finger single tap on a UIButton is one of them.
The way to block gesture recognizers like the default controls do would be to have TestControl override gestureRecognizerShouldBegin: (see UIView Class Reference). If you wanted to mimic UIButton's behavior, you could use something like:
override func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer {
if tapGestureRecognizer.numberOfTapsRequired == 1 && tapGestureRecognizer.numberOfTouchesRequired == 1 {
return false;
}
}
return true;
}

Swift: Pass parameter value to Selector function

I'm trying to pass value from addKey function to Selector function (didTapAny function) but couldn't figure how. Below is my code:
var keyName: UIButton!
func addKey(var keyTitle: String, var yValue: Float32){
keyName = UIButton.buttonWithType(.System) as UIButton
keyName.setTitle(keyTitle, forState: .Normal)
keyName.sizeToFit()
keyName.setTranslatesAutoresizingMaskIntoConstraints(false)
// Couldn't figure how to pass parameter value to Selector at this line
// action: Selector("didTapAny:")
keyName.addTarget(self, action: "didTapAny", forControlEvents: .TouchUpInside)
keyName.titleLabel.font = UIFont.systemFontOfSize(24)
keyName.backgroundColor = UIColor(white: 0.9, alpha: 9)
keyName.layer.cornerRadius = 5
view.addSubview(keyName)
var keyNameButtonLeftSideConstraint = NSLayoutConstraint(item: keyName, attribute: .CenterY, relatedBy: .Equal, toItem:view, attribute:.CenterY, multiplier: 1.0, constant: 0.0)
var keyNameButtonBottomConstraint = NSLayoutConstraint(item: keyName, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1.0, constant: yValue)
view.addConstraints([keyNameButtonLeftSideConstraint, keyNameButtonBottomConstraint])
}
// want to pass above function's keyTitle to this function
func didTapAny(keyTitle: String){
var proxy = textDocumentProxy as UITextDocumentProxy
proxy.insertText(keyTitle)
}
Thanks.
// want to pass above function's keyTitle to this function
func didTapAny(keyTitle: String){
You cannot pass whatever you wish into a button action method. The method will receive a reference to the button and you can access its currentTitle property. It goes more like:
func didTapAny(sender: UIButton) {
// use here sender.currentTitle
}

Resources