I have a button that creates many more buttons with a textfield:
func CreateButtonWithIndex(index:Int) {
let newButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
newButton.setTitle(“Button”, forState: UIControlState.Normal)
newButton.addTarget(self, action: Selector("go:"), forControlEvents: UIControlEvents.TouchUpInside)
newButton.tag = index+1;
var textFieldButton: UITextField = UITextField()
textFieldButton.tag = index+1;
textFieldButton.text = “textfield”
self.view.addSubview(textFieldButton)
self.view.addSubview(newButton)
}
func go(sender: AnyObject) {
println(“ok press button“)
}
How can I detect the textfield corresponding to the button pressed?
convert the sender into a UIButton
#IBAction func go(sender: AnyObject) {
let yourButton = sender as UIButton
println(yourButton.titleLabel.text)
}
Even better, if you're certain that only buttons are going to call the "go" action, you could instead do this:
#IBAction func go(sender: UIButton) {
println(sender.titleLabel.text)
if(sender.titleLabel.text == "OK")
println("OK button was pressed")
}
And more information can be found in the "Comparing Strings" section of Apple's Strings & Characters Swift documentation and the #IBOutlet thing I found in this tutorial.
Subclass UIButton. Add a UITextField variable to the subclassed UIButton. Assign the new UITextField variable after you create the UIButton subclass.
UIButton subclass:
class TextFieldButton: UIButton {
var textField: UITextField! // use this to reference the related text field
}
The code in your other class:
func CreateButtonWithIndex(index:Int) {
let newButton = UIButton.buttonWithType(UIButtonType.System) as TextFieldButton // use our new subclass
newButton.setTitle(“Button”, forState: UIControlState.Normal)
newButton.addTarget(self, action: Selector("go:"), forControlEvents: UIControlEvents.TouchUpInside)
newButton.tag = index+1;
var textFieldButton: UITextField = UITextField()
textFieldButton.tag = index+1;
textFieldButton.text = "textfield"
newButton.textField = textFieldButton // set reference to the text field
self.view.addSubview(textFieldButton)
self.view.addSubview(newButton)
}
func go(sender: AnyObject) {
println("ok press button")
println(sender.textField) // now we can access the related text field
}
Related
I have a UIViewController with a UIView displayed on it; pressing a button on the UIView loads my interstitial ad. When the UIView is subsequently displayed, I want the interstitial to be displayed with the rootVC as the UIViewController.
However, this code does not seem to work as intended:
1) My View Controller:
class MyViewController: UIViewController {
let button: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("BUTTON", for: .normal)
btn.addTarget(self, action: #selector(showUIView), for: .touchUpInside)
return btn
}()
#objc func showUIView(_ sender: UIButton) {
let popUp = MyUIView()
self.view.addSubview(popUp)
}
2) My UIView:
class MyUIView: UIView {
var interstitial: GADInterstitial!
let button: UIButton = {
let btn = UIButton()
btn.translatesAutoresizingMaskIntoConstraints = false
btn.setTitle("UIVIEW BUTTON", for: .normal)
btn.addTarget(self, action: #selector(prepareInterstitial), for: .touchUpInside)
return btn
}()
#objc func prepareInterstitial(_ sender: UIButton) {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
let request = GADRequest()
interstitial.load(request)
dismissPopUp()
if interstitial.isReady {
interstitial.present(fromRootViewController: MyViewController())
}
}
I get this in the console:
Warning: Attempt to present <GADFullScreenAdViewController: 0x7f8611e22fc0> on <Project.MyViewController: 0x7f8612884800> whose view is not in the window hierarchy!`
which I do not understand because MyViewController is still very much a part of the view hierarchy.
I'd be really grateful if someone could show me how to fix this error, I'm relatively new to coding and not sure what I am doing wrong. Thank you!
The reason why this doesn't work is because you are creating a brand new VC here:
interstitial.present(fromRootViewController: MyViewController())
This MyViewController() is not the VC that is shown on the screen! You just created by calling its initialiser.
You need to somehow get the VC that's shown on the screen. One simple way to do this is to add a rootVC property to your MyUIView:
weak var rootVC: UIViewController?
And then present this instead:
if let rootVC = self.rootVC { // nil check!
interstitial.present(fromRootViewController: rootVC)
}
In showUIView, set self as rootVC:
#objc func showUIView(_ sender: UIButton) {
let popUp = MyUIView()
popUp.rootVC = self
self.view.addSubview(popUp)
}
I generated a multiple UIButton and UIView using loop, the problem is, I want that generated UIView to be hidden when the generated UIButton was clicked,
The question is, how can I pass the UIView on a UIButton click event so that the system knows what UIView will going to be hidden
This is my code that generate UIButtons and UIViews
for (key, value) in myStringsArray {
let myButton = UIButton()
let myView = UIView()
panelButton.tag = value
panelButton.addTarget(self, action: #selector(onMyButtonClick), for: .touchUpInside)
}
The only data that I can pass on .tag was Int
And this is my onMyButtonClick function that listen on click event of the UIButton
#objc func onMyButtonClick (sender: UIButton) {
print(sender.tag)
}
What I want to do is to have a click listener function that is working like this
func clickMe (view: UIView, isOpen: Bool) {
view.isHidden = isOpen
}
You can assign the button and the view the same tag.
then you can find the view by tag and hide it.
#objc func onMyButtonClick (sender: UIButton) {
print(sender.tag)
if let foundView = view.viewWithTag(sender.tag) {
foundView.isHidden = true
}
}
I have a view subView in my mainViewController, the subView has 4 buttons. How can I recognise the onClick action of these buttons in my mainViewController?
Below is my mainViewController
import UIKit
class HomeViewController: UIViewController{
let tableList = ["HIPAA Rules", "Know Your HIPPA Status", "Covered Entity", "Business Associate"]
var metrics : [String : CGFloat] = [:]
let menuBar = MenuBar()
let table = OptionsTable()
var views : [UIView] = []
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.barTintColor = UIColor.getColorFromHex(hexCode: "1B9AF7")
navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
setUpTable()
}
private func setUpTable(){
views += [table]
view.addSubview(table)
table.backgroundColor = UIColor.red
//Code For Constraints Of the SubView
table.setUpButtons(numberOfButtons: 4, buttonTitleList: tableList, optionsTableHeight: optionTableHeight)
}
Below is my OptionsTable //subView of the Main ViewController
class OptionsTable: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
func setUpButtons(numberOfButtons : Int, buttonTitleList : [String], optionsTableHeight : CGFloat) {
let cellHeight = optionsTableHeight / CGFloat(numberOfButtons)
for buttonNumber in 0...numberOfButtons-1{
var views : [UIView] = []
var metrics : [String : CGFloat] = [:]
let paddingInTermsOfButtons = (numberOfButtons-buttonNumber)-1
let button = UIButton()
button.setTitle(buttonTitleList[buttonNumber], for: .normal)
button.backgroundColor = UIColor.white
button.layer.borderColor = UIColor.gray.cgColor
button.layer.borderWidth = 1;
button.setTitleColor(UIColor.black, for: .normal)
print("For button : \(buttonNumber)" )
print(self.frame)
self.addSubview(button)
views += [button]
//Code For Constraints of the buttons
}
}
So, how to do I recognise the onclick action for these buttons in the OptionsTable because they are created dynamically ?
You have to add target to recognize click event in you button like this.
Swift
buttonOne.tag = index
buttonOne.addTarget(self, action: #selector(buttonOneClicked), for: .touchUpInside)
This method will called when you tap button.
#objc func buttonOneClicked(button: UIButton) {
//Do whatever you want to do here and check button tags so you will get to know which index is clicked
}
Objecitve-C
buttonOne.tag = index;
[buttonOne addTarget:self action:#selector(buttonOneClicked:) forControlEvents:UIControlEventTouchUpInside];
This method will called when you tap button.
- (void) buttonOneClicked:(UIButton *) sender {
//Do whatever you want to do here and check button tags so you will get to know which index is clicked
}
I am trying to create 4 UIButtons that highlight and stay highlighted when they are clicked. The only problem is I need only one UIButton to be Highlighted at a time. So, if there is a UIButton highlighted already, I need it to be "unhighlighted" and highlight the UIButton I clicked. I have tried to do this before and failed. Please help me with this problem.
I am using the Swift coding language to do this.
Any input or suggestions would be greatly appreciated.
If you give this answer an upvote, remember to upvote dasblikenlight's answer as well.
class ViewController: UIViewController {
// Connect all 4 buttons to this outlet
#IBOutlet var radioGroup: [UIButton]!
// Connect this action to all 4 buttons
#IBAction func radioGroupClicked(sender: AnyObject) {
// Unhighlight all buttons
unhighlightRadioGroup()
// Highlight the one being clicked on
highlightRadioGroup(sender as! UIButton)
}
// Set all 4 buttons in unselected state
func unhighlightRadioGroup() {
for button in radioGroup {
button.selected = false
}
}
// Set one button in the selected state
func highlightRadioGroup(button : UIButton) {
button.selected = true
}
}
You can do it with an IBOutletCollection. Command-drag one of the buttons into the view controller code, and choose creating of an IBOutletCollection on drop, and name your collection something - say, radioGroup. Then control-drag the remaining three buttons into the same IBOutletCollection.
Next thing is to add a method to un-highlight all buttons in your radioGroup. This can be done with a simple loop.
Finally, add calls to unhighlightRadioGroup from the event handler of your buttons. Event handler should first call your unhighlightRadioGroup method, and then highlight the sender received in the event handler.
lazy var buttonsArray: [UIButton] = {
var buttons = [UIButton]()
let firstButton = UIButton()
let secondButton = UIButton()
let thirdButton = UIButton()
let fourthButton = UIButton()
buttons = [firstButton, secondButton, thirdButton, fourthButton]
return buttons
}()
private func setupButtonMethods() {
filteredButtons[0].addTarget(self, action: #selector(firstButtonPressed(sender:)), for: .touchUpInside)
filteredButtons[1].addTarget(self, action: #selector(secondButtonPressed(sender:)), for: .touchUpInside)
filteredButtons[2].addTarget(self, action: #selector(thirdButtonPressed(sender:)), for: .touchUpInside)
filteredButtons[3].addTarget(self, action: #selector(fourthButtonPressed(sender:)), for: .touchUpInside)
}
private func setupHiglightedStateOnButton(button: UIButton) {
for btn in buttonsArray {
btn.isSelected = false
btn.backgroundColor = .gray
btn.setTitleColor(.white, for: .normal)
btn.isUserInteractionEnabled = true
}
button.isSelected = true
button.backgroundColor = .yellow
button.setTitleColor(.black, for: .normal)
button.isUserInteractionEnabled = false
}
#objc func firstButtonPressed(sender: UIButton) {
setupHiglightedStateOnButton(button: sender)
}
#objc func secondButtonPressed(sender: UIButton) {
setupHiglightedStateOnButton(button: sender)
}
#objc func thirdButtonPressed(sender: UIButton) {
setupHiglightedStateOnButton(button: sender)
}
#objc func fourthButtonPressed(sender: UIButton) {
setupHiglightedStateOnButton(button: sender)
}
remember to call setupButtonMethods() inside viewDidLoad()
func setupNewBinderButton() {
let binderButton = UIButton.buttonWithType(UIButtonType.Custom) as UIButton
binderButton.frame = CGRectMake(50, 384-25, 50, 50)
binderButton.setTitle("Add", forState: UIControlState.Normal)
binderButton.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
binderButton.addTarget(self, action: "addBinderTapped", forControlEvents: UIControlEvents.TouchUpInside)
binderButton.userInteractionEnabled = true
self.view.addSubview(binderButton)
}
func addBinderTapped() {
println("hi")
abort()
}
override func viewDidLoad() {
super.viewDidLoad()
setupNewBinderButton()
The breakpoint I set in this function doesn't get hit. The log doesn't get hit. The abort doesn't happen.
How do I make my UIButton respond to touches in Swift?
Use like this as it needs to be tied to IBAction
#IBAction func addBinderTapped(sender: UIButton)
{
}
Connect this action with your button by command+drag to storyboard button to tie this function.