I have a UIButton that I am placing on a different UIView than the one it is declared in but I want the Target Selector to be in the UIView I declared the button in. The init_button function is getting called because the button is being placed on the view. Here is what I have:
import Foundation
import UIKit
class Menu1 : Element {
var color_base = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
var mock : UIView = UIView()
var button : UIButton = UIButton()
var view_width: CGFloat = 0,
view_height: CGFloat = 0,
menu_vertical_buffer : CGFloat = 0,
menu_width : CGFloat = 0,
button_vertical_buffer : CGFloat = 0,
button_width : CGFloat = 0
required init(mock: UIView) {
super.init(mock: mock)
self.mock = mock
init_dims()
init_button()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func init_dims(){
view_width = mock.frame.width
view_height = mock.frame.height
menu_vertical_buffer = CGFloat(floor(Double(view_height/17.5)))
menu_width = CGFloat(floor(Double(view_width/2.67)))
button_vertical_buffer = CGFloat(floor(Double(menu_vertical_buffer/3.6)))
button_width = menu_width - CGFloat(floor(Double(menu_width/7)))
}
func init_button(){
button = UIButton(frame: CGRect(x: mock.frame.width - menu_width,
y: mock.frame.height - (menu_vertical_buffer + (2 * button_vertical_buffer)),
width: button_width,
height: menu_vertical_buffer))
button.backgroundColor = color_base
button.layer.cornerRadius = button.frame.height/2
button.addTarget(self, action: #selector(changeMenuState), for: .touchUpInside)
mock.addSubview(button)
}
dynamic func changeMenuState(){
print("Menu state changed")
}
}
changeMenuState is the function I am adding as the target selector but the button is in the view mock not in the view that these functions are in.
changeMenuState must be dynamic or #objc exposed like
#objc func changeMenuState(){
print("Menu state changed")
}
My best guess is this might be a scoping issue. You aren't showing where the button is stored or the lifetime of the scope. In a typical scenario, you would define a button in a viewcontroller (or perhaps a cell) like so:
class MyViewController: UIViewController {
var button: UIButton? = nil
override func viewDidLoad() {
super.viewDidLoad()
init_button()
}
}
This way the button stays in scope as long as the view controller is within scope. Your code looks valid so my "best guess" is the references to button are going out of scope.
You probably need to provide more insight on how these views are working together and the scope of their lifetime (if this comment doesn't help you).
Did you set button's frame corretly? You can set mock's clipsToBounds to YES, then observe.
update:
As #Badhan Ganesh comment ,you can see the view stack.
The code you have written is correct and I have given the try on same. The issue I found is that your button is appearing on screen but placed out of bound of mock view, hence button is unable to receive the touch event on it. Try to place button inside mock view bounds by setting the frame correctly.
I was able to solve the problem and it was a scoping issue. I never added the Menu1 class to the mock class or any other view so I believe after it was instantiated and the button placed, that instance was killed so the button was placed but the target was in a class that was no longer in use. what solved my problem was adding mock.addSubview(self) to this class.
Related
Currently, I am implementing somewhat of a custom UIBarButtonItem when I use a couple custom methods to change the positioning of the button image to move it to the right of the text and add some padding. However, when I leave the screen and come back the buttons text and images get switched and distorted as can be seen in the attached images.
First picture is the way the button looks when i leave the screen and come back second picture is what it originally looks like. i have included the code for the uibarbuttonitem if anyone sees anything I don't that is causing this rendering issue I would greatly appreciate it.
import Foundation
import UIKit
class LocationManager: UIBarButtonItem {
var viewController: MainViewController?
lazy var customButton : UIButton = {
let customButton = UIButton(type: .system)
customButton.setImage(UIImage(named: "downArrow"), for: .normal)
customButton.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, -10)
guard let customFont = UIFont(name: "NoirPro-SemiBold", size: 20) else {
fatalError("""
Failed to load the "CustomFont-Light" font.
Make sure the font file is included in the project and the font name is spelled correctly.
"""
)
}
customButton.semanticContentAttribute = UIApplication.shared
.userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft
customButton.titleLabel?.font = customFont
customButton.setTitleColor(UIColor.black, for: .normal)
return customButton
}()
override init() {
super.init()
setupViews()
}
#objc func setupViews(){
customView = customButton
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
customView should be of type UIView. I suspect using the higher type of UIButton is causing issues. Within your customView you will need to set up the title and image as sub views and constrain according to your wishes.
I am new on iOS and Swift and I need some help.
I want create custom UIButton
Here is what I did
protocol ButtonProtocol {}
extension ButtonProtocol where Self: UIButton {
func addOrangeButton(){
layer.cornerRadius = 8
layer.backgroundColor = UIColor(netHex:ButtonColor.orange).cgColor
}
}
I want all params came from here which are cornerRadius, backgrounColor, highlightedColor, textColor, size etc...
I want use this way bcoz maybe in future the button color will change I will change it from one place directly.
But I don't understand what is layer how could I cast it as UIButton?
Is anyone can tell me which way should I take ?
You can create the subclass of UIButton, to add your own custom look to your button. like this
import UIKit
protocol DVButtonCustomMethods: class {
func customize()
}
class DVButton: UIButton {
var indexPath: IndexPath?
override init(frame: CGRect) {
super.init(frame: frame)
customize()// To set the button color and text size
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
customize()// To set the button color and text size
}
override func layoutSubviews() {
super.layoutSubviews()
customize()
}
}
extension DVButton: DVButtonCustomMethods {
func customize() {
layer.cornerRadius = self.frame.size.height / 2
backgroundColor = UIColor.white
tintColor = UIColor.red
titleLabel?.textColor = UIColor.black
clipsToBounds = true
}
}
Now what is need to do is, create one button in interface builder and assign you subClass as its class. Thats all everything will change as you want. If you want to change button colour just change in your subclass, it will affect in all button which is assigned your subclass.
Assigning subclass to your button: Refer below image
Thanks:)
The way you defined the extension, doesn't make you able to use it in the UIButton instance so simple.
So, you can decide whether extend UIButton to conform the protocol, or you can create a subclass of UIButton
// in this way you can use the `addOrangeButton` method anywhere
extension UIButton: ButtonProtocol {}
// in this way your new subclass contains the addOrangeButton definition
// and a normal UIButton cannot access that method
final class OrangeButton: UIButton, ButtonProtocol {
func setupButton() {
addOrangeButton()
}
}
Try this:
class func CutomeButton(bgColor: UIColor,corRadius: Float,hgColor: UIColor, textColor: UIColor, size: CGSize, titleText: String) -> UIButton {
let button = UIButton()
button.layer.cornerRadius = CGFloat(corRadius)
button.backgroundColor = bgColor
button.setTitleColor(textColor, for: .normal)
button.frame.size = size
button.setTitle(titleText, for: .normal)
return button
}
If I understand well, you want to modify a UIButton with specific parameters, let me tell you how do I do this:
extension UIButton
{
func setRadius(radius:CGFloat) {
self.layer.cornerRadius = radius
}
}
Use it as the following:
yourButton.setRadius(radius: 15)
Goal
I want to make a custom keyboard that is only used within my app, not a system keyboard that needs to be installed.
What I have read and tried
Documentation
App Extension Programming Guide: Custom Keyboard
Custom Views for Data Input
The first article above states:
Make sure a custom, systemwide keyboard is indeed what you want to
develop. To provide a fully custom keyboard for just your app or to
supplement the system keyboard with custom keys in just your app, the
iOS SDK provides other, better options. Read about custom input views
and input accessory views in Custom Views for Data Input in Text
Programming Guide for iOS.
That is what led me to the second article above. However, that article did not have enough detail to get me started.
Tutorials
iOS 8: Creating a Custom Keyboard in Swift
How to make a custom keyboard in iOS 8 using Swift
Xcode 6 Tutorial: iOS 8.0 Simple Custom Keyboard in Swift
Creating a Custom Keyboard Using iOS 8 App Extension
I was able to get a working keyboard from the second tutorial in the list above. However, I couldn't find any tutorials that showed how to make an in app only keyboard as described in the Custom Views for Data Input documentation.
Stack Overflow
I also asked (and answered) these questions on my way to answering the current question.
How to input text using the buttons of an in-app custom keyboard
Delegates in Swift
Question
Does anyone have a minimal example (with even one button) of an in app custom keyboard? I am not looking for a whole tutorial, just a proof of concept that I can expand on myself.
This is a basic in-app keyboard. The same method could be used to make just about any keyboard layout. Here are the main things that need to be done:
Create the keyboard layout in an .xib file, whose owner is a .swift file that contains a UIView subclass.
Tell the UITextField to use the custom keyboard.
Use a delegate to communicate between the keyboard and the main view controller.
Create the .xib keyboard layout file
In Xcode go to File > New > File... > iOS > User Interface > View to create the .xib file.
I called mine Keyboard.xib
Add the buttons that you need.
Use auto layout constraints so that no matter what size the keyboard is, the buttons will resize accordingly.
Set the File's Owner (not the root view) to be the Keyboard.swift file. This is a common source of error. See the note at the end.
Create the .swift UIView subclass keyboard file
In Xcode go to File > New > File... > iOS > Source > Cocoa Touch Class to create the .swift file.
I called mine Keyboard.swift
Add the following code:
import UIKit
// The view controller will adopt this protocol (delegate)
// and thus must contain the keyWasTapped method
protocol KeyboardDelegate: class {
func keyWasTapped(character: String)
}
class Keyboard: UIView {
// This variable will be set as the view controller so that
// the keyboard can send messages to the view controller.
weak var delegate: KeyboardDelegate?
// MARK:- keyboard initialization
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initializeSubviews()
}
override init(frame: CGRect) {
super.init(frame: frame)
initializeSubviews()
}
func initializeSubviews() {
let xibFileName = "Keyboard" // xib extention not included
let view = Bundle.main.loadNibNamed(xibFileName, owner: self, options: nil)![0] as! UIView
self.addSubview(view)
view.frame = self.bounds
}
// MARK:- Button actions from .xib file
#IBAction func keyTapped(sender: UIButton) {
// When a button is tapped, send that information to the
// delegate (ie, the view controller)
self.delegate?.keyWasTapped(character: sender.titleLabel!.text!) // could alternatively send a tag value
}
}
Control drag from the buttons in the .xib file to the #IBAction method in the .swift file to hook them all up.
Note that the protocol and delegate code. See this answer for a simple explanation about how delegates work.
Set up the View Controller
Add a UITextField to your main storyboard and connect it to your view controller with an IBOutlet. Call it textField.
Use the following code for the View Controller:
import UIKit
class ViewController: UIViewController, KeyboardDelegate {
#IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// initialize custom keyboard
let keyboardView = Keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 300))
keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped
// replace system keyboard with custom keyboard
textField.inputView = keyboardView
}
// required method for keyboard delegate protocol
func keyWasTapped(character: String) {
textField.insertText(character)
}
}
Note that the view controller adopts the KeyboardDelegate protocol that we defined above.
Common error
If you are getting an EXC_BAD_ACCESS error, it is probably because you set the view's custom class as Keyboard.swift rather than do this for the nib File's Owner.
Select Keyboard.nib and then choose File's Owner.
Make sure that the custom class for the root view is blank.
The key is to use the existing UIKeyInput protocol, to which UITextField already conforms. Then your keyboard view need only to send insertText() and deleteBackward() to the control.
The following example creates a custom numeric keyboard:
class DigitButton: UIButton {
var digit: Int = 0
}
class NumericKeyboard: UIView {
weak var target: (UIKeyInput & UITextInput)?
var useDecimalSeparator: Bool
var numericButtons: [DigitButton] = (0...9).map {
let button = DigitButton(type: .system)
button.digit = $0
button.setTitle("\($0)", for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.addTarget(self, action: #selector(didTapDigitButton(_:)), for: .touchUpInside)
return button
}
var deleteButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("⌫", for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = "Delete"
button.addTarget(self, action: #selector(didTapDeleteButton(_:)), for: .touchUpInside)
return button
}()
lazy var decimalButton: UIButton = {
let button = UIButton(type: .system)
let decimalSeparator = Locale.current.decimalSeparator ?? "."
button.setTitle(decimalSeparator, for: .normal)
button.titleLabel?.font = .preferredFont(forTextStyle: .largeTitle)
button.setTitleColor(.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.darkGray.cgColor
button.accessibilityTraits = [.keyboardKey]
button.accessibilityLabel = decimalSeparator
button.addTarget(self, action: #selector(didTapDecimalButton(_:)), for: .touchUpInside)
return button
}()
init(target: UIKeyInput & UITextInput, useDecimalSeparator: Bool = false) {
self.target = target
self.useDecimalSeparator = useDecimalSeparator
super.init(frame: .zero)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
// MARK: - Actions
extension NumericKeyboard {
#objc func didTapDigitButton(_ sender: DigitButton) {
insertText("\(sender.digit)")
}
#objc func didTapDecimalButton(_ sender: DigitButton) {
insertText(Locale.current.decimalSeparator ?? ".")
}
#objc func didTapDeleteButton(_ sender: DigitButton) {
target?.deleteBackward()
}
}
// MARK: - Private initial configuration methods
private extension NumericKeyboard {
func configure() {
autoresizingMask = [.flexibleWidth, .flexibleHeight]
addButtons()
}
func addButtons() {
let stackView = createStackView(axis: .vertical)
stackView.frame = bounds
stackView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(stackView)
for row in 0 ..< 3 {
let subStackView = createStackView(axis: .horizontal)
stackView.addArrangedSubview(subStackView)
for column in 0 ..< 3 {
subStackView.addArrangedSubview(numericButtons[row * 3 + column + 1])
}
}
let subStackView = createStackView(axis: .horizontal)
stackView.addArrangedSubview(subStackView)
if useDecimalSeparator {
subStackView.addArrangedSubview(decimalButton)
} else {
let blank = UIView()
blank.layer.borderWidth = 0.5
blank.layer.borderColor = UIColor.darkGray.cgColor
subStackView.addArrangedSubview(blank)
}
subStackView.addArrangedSubview(numericButtons[0])
subStackView.addArrangedSubview(deleteButton)
}
func createStackView(axis: NSLayoutConstraint.Axis) -> UIStackView {
let stackView = UIStackView()
stackView.axis = axis
stackView.alignment = .fill
stackView.distribution = .fillEqually
return stackView
}
func insertText(_ string: String) {
guard let range = target?.selectedRange else { return }
if let textField = target as? UITextField, textField.delegate?.textField?(textField, shouldChangeCharactersIn: range, replacementString: string) == false {
return
}
if let textView = target as? UITextView, textView.delegate?.textView?(textView, shouldChangeTextIn: range, replacementText: string) == false {
return
}
target?.insertText(string)
}
}
// MARK: - UITextInput extension
extension UITextInput {
var selectedRange: NSRange? {
guard let textRange = selectedTextRange else { return nil }
let location = offset(from: beginningOfDocument, to: textRange.start)
let length = offset(from: textRange.start, to: textRange.end)
return NSRange(location: location, length: length)
}
}
Then you can:
textField.inputView = NumericKeyboard(target: textField)
That yields:
Or, if you want a decimal separator, too, you can:
textField.inputView = NumericKeyboard(target: textField, useDecimalSeparator: true)
The above is fairly primitive, but it illustrates the idea: Make you own input view and use the UIKeyInput protocol to communicate keyboard input to the control.
Also please note the use of accessibilityTraits to get the correct “Spoken Content” » “Speak Screen” behavior. And if you use images for your buttons, make sure to set accessibilityLabel, too.
Building on Suragch's answer, I needed a done and backspace button and if you're a noob like me heres some errors you might encounter and the way I solved them.
Getting EXC_BAD_ACCESS errors?
I included:
#objc(classname)
class classname: UIView{
}
fixed my issue however Suragch's updated answer seems to solve this the more appropriate/correct way.
Getting SIGABRT Error?
Another silly thing was dragging the connections the wrong way, causing SIGABRT error. Do not drag from the function to the button but instead the button to the function.
Adding a Done Button
I added this to the protocol in keyboard.swift:
protocol KeyboardDelegate: class {
func keyWasTapped(character: String)
func keyDone()
}
Then connected a new IBAction from my done button to keyboard.swift like so:
#IBAction func Done(sender: UIButton) {
self.delegate?.keyDone()
}
and then jumped back to my viewController.swift where i am using this keyboard and added this following after the function keyWasTapped:
func keyDone() {
view.endEditing(true)
}
Adding Backspace
This tripped me up a lot, because you must set the textField.delegate to self in the viewDidLoad() method (shown later).
First: In keyboard.swift add to the protocol func backspace():
protocol KeyboardDelegate: class {
func keyWasTapped(character: String)
func keyDone()
func backspace()
}
Second: Connect a new IBAction similar to the Done action:
#IBAction func backspace(sender: UIButton) {
self.delegate?.backspace()
}
Third: Over to the viewController.swift where the NumberPad is appearing.
Important: In viewDidLoad() set all textFields that will be using this keyboard. So your viewDidLoad() should look something like this:
override func viewDidLoad() {
super.viewDidLoad()
self.myTextField1.delegate = self
self.myTextField2.delegate = self
// initialize custom keyboard
let keyboardView = keyboard(frame: CGRect(x: 0, y: 0, width: 0, height: 240))
keyboardView.delegate = self // the view controller will be notified by the keyboard whenever a key is tapped
// replace system keyboard with custom keyboard
myTextField1.inputView = keyboardView
myTextField2.inputView = keyboardView
}
I'm not sure how to, if there is a way to just do this to all textFields that are in the view. This would be handy...
Forth: Still in viewController.swift we need to add a variable and two functions. It will look like this:
var activeTextField = UITextField()
func textFieldDidBeginEditing(textField: UITextField) {
print("Setting Active Textfield")
self.activeTextField = textField
print("Active textField Set!")
}
func backspace() {
print("backspaced!")
activeTextField.deleteBackward()
}
Explanation of whats happening here:
You make a variable that will hold a textField.
When the "textFieldDidBeginEditing" is called it sets the variable so it knows which textField we are dealing with. I've added a lot of prints() so we know everything is being executed.
Our backspace function then checks the textField we are dealing with and uses .deleteBackward(). This removes the immediate character before the cursor.
And you should be in business.
Many thanks to Suragchs for helping me get this happening.
I'm creating pages dynamically, each page contains a Navigation Controller and UIViewController.
Inside each page, there are components like link, images, texts.
Each component is a class like the following:
class link: Component, ComponentProtocol {
var text: String
var url: String
func browseURL(sender: UIButton!){
let targetURL = NSURL(fileURLWithPath: self.url)
let application = UIApplication.sharedApplication()
application.openURL(targetURL!)
}
func generateView() -> UIView?{
var result: UIView?
var y = CGRectGetMinY(frame)
var linkBtn = UIButton(frame: CGRect(x: 0, y:30 , width:300 , height: 50)
linkBtn.setTitle(self.text, forState: UIControlState.Normal)
linkBtn.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
linkBtn.titleLabel?.font = linkBtn.titleLabel?.font.fontWithSize(15)
// this doesn't seem to be registered properly
linkBtn.addTarget(self, action: "browseURL:", forControlEvents: UIControlEvents.TouchUpInside)
result = UIView()
result?.addSubview(linkBtn)
return result
}
Then in the ViewDidLoad of the page ViewController method I would have this to initialise the page components:
for component in components!{
if let acomponent:ComponentProtocol = component as? ComponentProtocol {
if let res = acomponent.generateView(innerFrame) {
if let view = res.view {
self.view.addSubview(view)
}
}
}
}
The button is showing, but when I touch nothing happens. When I debugged, the browseURL is no triggered at all.
What's wrong with my code? I'm guessing because I registered the action in link class and not in the ViewController of the page?
UPDATE
This could be a similar issue, but the answer is not so straightforward and I actually have the component reference in my ViewController: (Target: Object) not working for setting UIButton from outside viewController
I'm not at a Mac right now so I can't test, but does this work:
linkBtn.target = self
linkBtn.action = "browseURL:"
I think if you have selectors in Swift you have to be careful with colons and specifying #objc if your class doesn't inherit from NSObject, it could also be something to do with that?
I am trying to create a custom drop down list in a ViewController. There are going to be 5 drop down lists and each list will have 4 options. Because of the number of lists, I decided to make a UIView that has the four choices in the form of UIButtons for each of the lists. Right now I am just trying to get one down; therefore, the following code is for ONE drop down list with FIVE options (including the one selected, which I will explain further below).
Essentially what I want is to have a button showing the selected value (or a default value at launch) and then when you click on that value then the UIView that contains 4 buttons (aka the drop down list) is shown below the original button. When the user clicks on one of the buttons I want the the button with the selected value to have the title of the button that was clicked on.
I am having the following issues:
I want to be able to pass the titles of the four buttons from the ViewController to the UIView because I want to use this UIView multiple times with different values for the titles of the four buttons. I don't know how to pass values to a UIView class.
When a choice from the drop down list (ie a UIButton) is clicked I can't figure out how to pass the value of the title of the button from the UIView back to UIViewController. I tried setting the title to a variable in the ViewController but that didn't work (showed up as nil).
Thank you so much in advance - I know this is a long questions and I am really unsure if this is even a good approach to take for what I am trying to do but it made sense in my head.
Here is my code for the ViewController
var buttonsLeft: buttonsView = buttonsView() // this is the UIView subclass
var time = UIButton.buttonWithType(UIButtonType.System) as! UIButton
override func viewWillAppear(animated: Bool) {
//hidden drop down list
self.buttonsLeft.frame = CGRect(x: self.view.bounds.width*(1/6) - 50, y:120, width:100, height: 135)
self.buttonsLeft.hidden = true
//button with selection showing or the default value at launch
self.time.frame = CGRectMake(self.view.bounds.width * (1/6) - 50, 90, 100, 30)
self.time.setTitle("1 DAY", forState: UIControlState.Normal)
self.time.addTarget(self, action: "showLeft", forControlEvents: UIControlEvents.TouchUpInside)
self.time.hidden = false
self.view.addSubview(self.time)
}
//this function shows the list
func showLeft(){
self.view.addSubview(self.buttonsLeft)
self.buttonsLeft.hidden = false
}
Here is the code for the UIView buttonsView:
import UIKit
class buttonsView: UIView {
var option1 = UIButton()
var option2 = UIButton()
var option3 = UIButton()
var option4 = UIButton()
var buttons: Array<UIButton> = Array()
var title:String = String()
override init(frame: CGRect) {
super.init(frame: frame)
self.buttons = [option1, option2, option3, option4]
self.option1.setTitle("1 DAY", forState: UIControlState.Normal)
self.option2.setTitle("1 MONTH", forState: UIControlState.Normal)
self.option3.setTitle("1 YEAR", forState: UIControlState.Normal)
self.option4.setTitle("LONGER", forState: UIControlState.Normal)
var yStep = 35
for var i:Int = 0; i < 4; ++i {
var totalY:CGFloat = CGFloat(i*yStep)
buttons[i].frame = CGRectMake(0, totalY, 100, 30)
buttons[i].addTarget(self, action: "choseOption:", forControlEvents: UIControlEvents.TouchUpInside)
buttons[i].hidden = false
self.addSubview(buttons[i])
}
}
func choseOption(sender:UIButton){
self.title = sender.titleLabel!.text!
MyView().parentTitle = sender.titleLabel!.text! // my attempt at assigning to variable in View Controller
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Delegation will help you to pass value to UIViewController.
Here are the way you can implement delegate in swift.
Step 1 : Declare protocol in class which is used to sending data. here is buttonsview.
#objc protocol MyButtonDelegate{
optional func didSelectButton(text:String)
}
Step 2 : Now declare delegate in sending class. here is buttonsview.
class buttonsView: UIView {
var delegate:MyButtonDelegate?
[other stuf......]
}
Step 3: now use delegate to send data to 'UIViewController'.
func choseOption(sender:UIButton){
delegate!.didSelectButton(text: sender.titleLabel!.text!)
}
Step 4 : adopt protocol in receiving class.
class ViewController: UIViewController,MyButtonDelegate {
Step 5: implement delegate method in receiving class.
func didSelectButton(text: String) {
parentTitle = "The Buttons title is " + text
}
Step 6: now set delegate
override func viewDidLoad() {
super.viewDidLoad()
buttonsLeft.delegate = self
}
Hope this help you.