swift playgrounds display uiview with nonstop looping - swift

I create and display uiview in live view windows, when i create the button and add to the uiview , the program fail with nonstop looping which continuously load addbutton . Did somebody meet this problem and please tell me why :-)
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
var label1 : UILabel?
override func loadView() {
let view = UIView()
view.backgroundColor = .white
print("code run here ")
let label = UILabel()
label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
label.text = "Hello World!"
label.textColor = .black
label1 = label
view.addSubview(label)
let k1:UIButton = addnewbutton() as! UIButton
//view.addSubview(k1)
self.view = view
}
#objc func buttonPressed(sender: UIButton!) {
var alertController = UIAlertController(title: "title", message: "message", preferredStyle: UIAlertControllerStyle.alert)
self.present(alertController, animated: true, completion: nil)
}
func addnewbutton() -> UIView{
var btn : UIButton
btn = UIButton()
btn.frame = CGRect(x:200,y:300,width:100,height:25)
btn.setTitle("clickme",for: UIControlState.normal)
//btn.titleLabel?.text = "clickme"
btn.backgroundColor = UIColor.black
btn.titleLabel?.textColor = UIColor.white
btn.titleColor(for: UIControlState.normal)
btn.addTarget(self, action: #selector(buttonPressed), for: UIControlEvents.touchUpInside)
view.addSubview(btn)
return btn
}
}
// Present the view controller in the Live View window
PlaygroundPage.current.liveView = MyViewController()

You add the button here
view.addSubview(btn)
inside addnewbutton
which recursively searches for the parent view of the VC and it's not yet setted inside loadView so control calls it again and the problem happens to infinite loop , so comment that line and uncomment this
view.addSubview(k1) // which is inside loadView
BTW make the return of addnewbutton to UIButton directly instead of a cast

Related

How can I properly reload the UIViewController after dismiss method is called?

I have 2 viewControllers named vcA and vcB.
vcA has navigationController and vcB is just viewController which don't have navigationController.
I saved text data in a file in vcB, and I wanna show that text in vcA when I come back to vcA after the dismiss method is called.
I thought reloading vcA after dismiss is called is the proper way to show text, but I figured out that it might be difficult to do that between vcA and vcB, because vcA has navigationController but vcB doesn't have navigationController.
How can I refresh vcA?
You can use self.present over self.dismiss. Like this:
let vc = vcA()
And here you can pass data. For example, if vcA() has a var called text that is a string you can use vc.text = "something". And this data will go with the self.present method
vc.modalPresentationStyle = .fullScreen
self.present(vc,animated: true, completion: nil)
You can pass the value back to the presenting view controller using the protocol/delegate pattern. Following is an example of how to pass a text from a text field in vcB to vcA as vcB is being dismissed so you can substitute that with the value you want to pass.
protocol ValuePassingDelegate {
func didPassValue(of text: String)
}
class ViewControllerA: UIViewController, ValuePassingDelegate {
let label = UILabel(frame: CGRect(origin: CGPoint(x: 0, y: 100), size: CGSize(width: 200, height: 100)))
let button = UIButton(type: .system)
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(label)
label.text = "Initial text"
label.textAlignment = .center
button.frame = CGRect(origin: CGPoint(x: 0, y: 300), size: CGSize(width: 200, height: 100))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(buttonHandler), for: .touchUpInside)
view.addSubview(button)
}
#objc func buttonHandler() {
let vcB = ViewControllerB()
vcB.delegate = self
self.navigationController?.pushViewController(vcB, animated: true)
}
func didPassValue(of text: String) {
DispatchQueue.main.async {
self.label.text = text
}
}
}
class ViewControllerB: UIViewController {
let textField = UITextField(frame: CGRect(origin: .zero, size: CGSize(width: 200, height: 100)))
var delegate: ValuePassingDelegate?
override func viewDidLoad() {
super.viewDidLoad()
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.black.cgColor
view.addSubview(textField)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
delegate?.didPassValue(of: textField.text ?? "")
}
}
The way that I followed for this purpose is :
in vcB I added:
internal var senderVC: UIViewController?
in vcA I added:
vcB.senderVC = self
in vcB I added:
if let firstVC = self.senderVC as? vcA { firstVC.tableView.reloadData(); }

“Unrecognized selector sent to instance” in UIView class when calling addTarget

I am trying to create a DropDownMenu class, but when I try to call addTarget to one of the buttons, this error comes up.
unrecognized selector sent to instance 0x7fd167f06120' terminating with uncaught exception of type NSException
I would really appreciate any help and no answer is a bad one!
Here is my entire class
class DropDownMenu: UIView {
// Main button or Pre
var main: UIButton! = UIButton(frame: CGRect(x: 0, y: 0, width: 46, height: 30))
var view: UIView!
// Title
var buttonTitles: [String]! = [""]
var titleColor: UIColor! = UIColor.black
var font: UIFont! = UIFont.systemFont(ofSize: 18)
// Individual Button
var buttonsBorderWidth: CGFloat! = 0
var buttonsBorderColor: UIColor? = UIColor.white
var buttonsCornerRadius: CGFloat! = 0
var color: UIColor! = UIColor.clear
// Button Images
var buttonsImageEdgeInsets: UIEdgeInsets? = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
var images: [UIImage]? = nil
// Onclick stuff
var target: UIViewController!
private var currentSelected: String? = nil
private var optionsStack = UIStackView()
init(main: UIButton) {
self.main = main
super.init(frame: CGRect())
}
func createDropDownMenu() {
main.addTarget(target, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
print("Button Target?: \(main.allTargets), self.target: \(String(describing: target))")
let mainFrame = main.frame
optionsStack.frame = CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: CGFloat(buttonTitles.count) * mainFrame.height)
optionsStack.axis = .vertical
view.addSubview(optionsStack)
var y: CGFloat! = 0
for title in buttonTitles {
let button = UIButton(frame: CGRect(x: 0, y: y, width: mainFrame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleColor, for: .normal)
button.backgroundColor = color
button.titleLabel?.font = font
button.addTarget(target, action: #selector(DropDownMenu.onclick), for: .touchUpInside)
y += mainFrame.height
optionsStack.addArrangedSubview(button)
}
for button in optionsStack.arrangedSubviews {
button.isHidden = true
button.alpha = 0
}
}
#objc private func openDropdown(_ sender: UIButton) {
print("sender: \(String(describing: sender))")
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.view.layoutIfNeeded()
}
}
}
#objc private func onclick(_ sender: UIButton) {
let title = sender.titleLabel!.text
print(title as Any)
main.setTitle(title, for: .normal)
optionsStack.arrangedSubviews.forEach { (button) in
UIView.animate(withDuration: 0.7) {
button.isHidden = true
button.alpha = 0
}
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Here is the code and creation of the object in ViewController
let grade = UIButton(frame: CGRect(x: 50, y: 300, width: 80, height: 30))
grade.layer.borderWidth = 1
grade.setTitle("Grade", for: .normal)
grade.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
grade.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = view
view.addSubview(grade)
gradeDP.createDropDownMenu()
The first print statement in the createDropDownMenu() function prints...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
After editing it with the help of mightknow I came up with this class. It doesn't have any onclick actions for the mainButton in it.
class DropDownMenu: UIStackView {
var options: [String]! = [] // Labels for all of the options
var titleButton: UIButton! = UIButton() // The Main Title Button
init(options: [String]) {
self.options = options
let mainFrame = titleButton.frame
super.init(frame: CGRect(x: mainFrame.minX, y: mainFrame.maxY, width: mainFrame.width, height: mainFrame.height * CGFloat(options.count)))
var y: CGFloat = 0
for title in self.options {
let button = UIButton(frame: CGRect(x: 0, y: y, width: self.frame.width, height: mainFrame.height))
button.setTitle(title, for: .normal)
button.setTitleColor(titleButton.titleLabel?.textColor, for: .normal)
button.backgroundColor = titleButton.backgroundColor
button.addTarget(self, action: #selector(dropDownOptionClicked(_:)), for: .touchUpInside)
button.isHidden = true
button.alpha = 0
self.addArrangedSubview(button)
y += 1
}
}
#objc func openDropDown(_ sender: UIButton) {
print("Open DropDownMenu")
for button in self.arrangedSubviews {
UIView.animate(withDuration: 0.7) {
button.isHidden = !button.isHidden
button.alpha = button.alpha == 0 ? 1 : 0
self.layoutIfNeeded()
self.superview?.layoutIfNeeded()
}
}
}
#objc private func dropDownOptionClicked(_ sender: UIButton) {
print(sender.titleLabel?.text as Any)
}
init() {
super.init(frame: CGRect.zero)
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
And than my ViewController is ...
let dp = DropDownMenu(options: ["Label 1", "Label 2", "Label 3"])
let titleButton = UIButton(frame: CGRect(x: 100, y: 300, width: 180, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("DropDownMenu", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.addTarget(self, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
dp.titleButton = titleButton
The error ...
Button Target?: [AnyHashable(<HomeworkHelp.DropDownMenu: 0x7ffb555200b0; frame = (0 0; 0 0); layer = <CALayer: 0x600002bdf5c0>>)], self.target: Optional(<HomeworkHelp.CreateAccountViewController: 0x7ffb5550a7b0>)
still comes up and I am clueless as to why.
You're setting the target as a UIViewController when the method you're calling is actually a method of the DropDownMenu class. What you need to do is set the target to self instead of the target property:
main.addTarget(self, action: #selector(DropDownMenu.openDropdown(_:)), for: .touchUpInside)
EDIT: In response to your comment, here is the code I'm using to test it. There are some layout/color choices I made just to make it clear to me, but this works:
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
let main = UIButton(frame: CGRect(x: 0, y: 100, width: 80, height: 30))
main.layer.borderWidth = 1
main.setTitle("Grade", for: .normal)
main.titleLabel?.font = UIFont.boldSystemFont(ofSize: 20)
main.setTitleColor(UIColor.black, for: .normal)
let gradeDP = DropDownMenu(main: main)
gradeDP.buttonTitles = ["Title 1", "Title 2", "Title 3"]
gradeDP.color = UIColor.gray
gradeDP.target = self
gradeDP.titleColor = UIColor.white
gradeDP.view = UIView()
self.view.addSubview(gradeDP)
let b = self.view.bounds
gradeDP.frame = CGRect(x: b.minX, y: b.minY, width: b.width, height: b.height/2)
gradeDP.backgroundColor = UIColor.purple
gradeDP.target = self
gradeDP.addSubview(gradeDP.main)
gradeDP.createDropDownMenu()
}}
As for your code, I'm going on the assumption that the code you added in the second part of your question is inside your ViewController's viewDidLoad() method, and that the main variable you're using to initialize your DropDownMenu is an instance variable of your ViewController, because I'm not seeing it anywhere else in scope. If that's the case, there are definitely some issues. They are:
You never actually add gradeDP to your view hierarchy. If that's what the line gradeDP.view = view is supposed to do, it's not. What that code actually does is set the view property of gradeDP to be a reference to the ViewController's view property. And, unless there is code in your DropDownMenu class that you haven't included, you're not actually using that reference for anything. So, you can get rid of that line entirely, and the view property in your DropDownMenu class. If what you're trying to do is set the ViewController's view to be gradeDP, that code would be self.view = gradeDP, but I don't actually recommend doing it that way. A UIViewController's view property is used in some special functionality and probably shouldn't be messed with much. You probably want to add gradeDP as a subview, like I did in my code above.
The grade button you created is not used by your DropDownMenu. I'm guessing you meant to initialize with that instead of the main variable (that is out of scope of your code), like this:
let gradeDP = DropDownMenu(main: grade)
In short, unless there is code elsewhere that you haven't shared, what your code above does is create a UIButton labeled "Grade" that is visible but doesn't actually do anything (and isn't part of your DropDownMenu), and a DropDownMenu that isn't actually visible, but would have a main button that calls openDropdown(_:) if it was. I'm guessing that's not how it's supposed to work. Hopefully the code I provided above helps get you where you want to be, though.
As for suggestions with rebuilding your class so it works properly, you may want to start with something like this:
class DropDownMenu : UIView {
var dropdownOptions : [String] = []
private var titleButton : UIButton = UIButton()
private var optionsStack : UIStackView = UIStackView()
private var optionsButtons : [UIButton] = []
#objc private func openDropdown(_ sender: UIButton) {
// Add code to make dropdown options appear. There are multiple ways of doing this. For instance, the optionsButtons could be hidden and then unhidden when it's clicked, or they could be created only once the button is clicked.
}
#objc private func selectedOption(_ sender: UIButton) {
// Code here for when option is selected
}
init(options: [String]) {
self.dropdownOptions = options
super.init(frame: CGRect.zero)
// Customize all of your subviews here, and add them to your DropDownMenu (as subviews)
// Add openDropdown(_:) target to self.titleButton
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
}
A lot of the code you have already written for your original version of the class can go inside the functions there. Also, there is a lot of unnecessary code in your original version. For example, the target variable is unused once you fixed the original error issue, the view variable is obsolete, and the createDropDownMenu() function is unnecessary because all of that code can go either in the init(options:) or openDropdown(_:) functions.
Then, if you choose to build out a class using that template, you would implement it in your ViewController's viewDidLoad() method with the code:
let dropdown = DropDownMenu(titles: ["Title 1", "Title 2", "Title 3"])
self.view.addSubview(dropdown)
// Follow that with layout code that ensures it's the proper size and in the proper location
I hope that combined with my comments make sense, are helpful, and aren't too overwhelming. What I recommend doing is starting a new empty project (or target) and building your class and adding it to a ViewController with nothing else in it. That's a good way to isolate it and check and make sure everything looks and works right. In case you want an alternate suggestion with how to build your class, you can actually try making DropDownMenu be a subclass of UIStackView (instead of UIView) with the main button and all option buttons being arranged subviews. This might actually be simpler, because it kind of cuts out the middleman, if you will, and all you'd need to do when opening/closing the dropdown is add/remove views from the .arrangedSubviews property.
Also important is that if your view needs to pass information (such as which option is selected) back to the ViewController, make sure the reference to the ViewController is marked weak so you don't create a retain cycle.
On a final note, if you're disappointed that there isn't a quick fix to get the original class to work and want to keep trying at that, there might be some way to cobble together a solution (like the code from my first answer, which does actually work...), but ultimately it will probably only cause more issues further down the line. So, best of luck with everything.
I finally figured it out! The target has to be the DropDownMenu.
titleButton.addTarget(dp, action: #selector(dp.openDropDown(_:)), for: .touchUpInside)
Here is the rest of the code...
let titleButton = UIButton(frame: CGRect(x: 50, y: 290, width: 100, height: 40))
titleButton.backgroundColor = UIColor.white
titleButton.setTitle("Grade", for: .normal)
titleButton.setTitleColor(UIColor.black, for: .normal)
titleButton.layer.borderWidth = 2
titleButton.layer.cornerRadius = 10
let dp = DropDownMenu(options: ["1", "Freshman", "Sophomore", "Junior", "Senior", "College"])
dp.titleButton = titleButton
dp.target = self
dp.borderWidth = 2
dp.spacing = 5
dp.cornerRadius = 10
dp.bgColor = UIColor.white
Adding it to subviews and creating it...
view.addSubview(titleButton)
view.addSubview(dp)
dp.createDropDownMenu()

How can I center a button on view programmatically

I am trying to center a Button onto the bottom of a view but it never appears. The only time it appears is when I uncomment takePhotoButton.frame. What is the proper way to do this?
import UIKit
import AVFoundation
class InputViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let photoPreviewImageView = UIImageView()
photoPreviewImageView.frame = view.bounds
photoPreviewImageView.backgroundColor = UIColor.green
view.addSubview(photoPreviewImageView)
let imageOfPhotoButton = UIImage(named: "smallcircle.circle.fill") as UIImage?
let takePhotoButton = UIButton(type: .custom) as UIButton
takePhotoButton.setImage(imageOfPhotoButton, for: .normal)
//takePhotoButton.frame = CGRect(x: 10, y: 10, width: 60, height: 60) // It will appear with this code however i took it away because im trying to center it at the bottom of the screen
takePhotoButton.center = view.center
photoPreviewImageView.addSubview(takePhotoButton)
}
}
Use constraint anchors. After you add the takePhotoButton set them the following way:
takePhotoButton.bottomAnchor.constraint(equalTo: photoPreviewImageView.bottomAnchor).isActive = true
takePhotoButton.centerXAnchor.constraint(equalTo: photoPreviewImageView.centerXAnchor).isActive = true
This will set make your button have the same bottom and center as it's container.
Good day,
you have to add constraint.
import UIKit
class ViewController: UIViewController {
var loginButton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("Login", for: .normal)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .red
button.tintColor = .white
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
constraintsInit()
}
func constraintsInit(){
view.addSubview(loginButton)
NSLayoutConstraint.activate([
loginButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor),
loginButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
loginButton.heightAnchor.constraint(equalToConstant: 30),
loginButton.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: 30),
loginButton.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant: -30),
])
}
}
on youtube you can find several people that explain how create the views, using only code.

swift, embed ui view controller with navigation controller to allow for back button

I am trying to get a back button on my MyServiceTypeSelector() controller so that after i present MyServiceTypeSelector() I can go back to the BRPServiceSelector() controller , how can i do this ? do i some how need to embed it with a nav controller and if so i am not using storyboards so it would need to be done programmatically?
import Foundation
import UIKit
class BRPServiceSelector: UIViewController, UITextFieldDelegate {
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
let businessAccountLabel: UILabel = {
let label = UILabel()
label.text = "Business Account"
label.backgroundColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
label.textAlignment = .center
return label
}()
lazy var serviceSelectorButton: UIButton = {
let button = UIButton(type: .system)
button.backgroundColor = UIColor.black
button.setTitle("Select A Service Type?", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.addTarget(self, action: #selector(presentServiceSelector), for: .touchUpInside)
button.layer.cornerRadius = 3
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
return button
}()
func presentServiceSelector(){
let msts = MyServiceTypeSelector()
let navController = UINavigationController(rootViewController: msts)
self.present(navController, animated: true, completion: nil)
let containerView: UIView = {
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
return v
}()
let scrollView: UIScrollView = {
let v = UIScrollView()
v.translatesAutoresizingMaskIntoConstraints = false
v.backgroundColor = .white
return v
}()
func setupViews(){
containerView.addSubview(serviceSelectorButton)
serviceSelectorButton.anchor(top: containerView.topAnchor, left: nil, bottom: nil, right: nil, paddingTop: 50, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 220, height: 25)
serviceSelectorButton.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true
}
}
}
If you want the VC in the navigation stack then push it onto the stack instead of presenting it. presenting is normally used for modal windows and they dont usually have navigation bars.
self.navigationController?.pushViewController(vc, animated: true)

How to connect multiple buttons in a storyboard to a single action, by code not drag&drop?

I'm currently using Xcode 7.3 and I'm simply wondering how to select multiple buttons across different UIViews, but under a single view controller. CMD clicking doesn't seem to work. I need this functionality because in Xcode 7.3 the only way to let two buttons on IB to share the same action is to select them at once and then drag the action to your view controller. I'm doing this by code and no drag & drop
class LogIn: UIViewController {
var mail_tf : UITextField!
var pass_tf : UITextField!
var btnL : UIButton!
var btnC : UIButton!
let cl1 = UIColor (red: 255/255.0, green: 258/255.0, blue: 196/255.0, alpha: 1)
let cl2 = UIColor (red: 238/255.0, green: 233/255.0, blue: 191/255.0, alpha: 1)
override func loadView() {
super.loadView()
let backgroundView = UIImageView(image: UIImage(named: "4")!)
//backgroundView.layer.cornerRadius = backgroundView.frame.size.width / 2
backgroundView.frame = CGRectMake(0, 0, 900, 900)
//backgroundView.clipsToBounds = true
//backgroundView.layer.borderColor = UIColor.whiteColor().CGColor
// backgroundView.layer.borderWidth = 1
self.view.addSubview(backgroundView)
mail_tf = UITextField()
mail_tf.frame = CGRectMake(95, 90, 190, 60)
mail_tf.layer.cornerRadius = 10
mail_tf.layer.borderWidth = 1
mail_tf.layer.borderColor = UIColor.blackColor().CGColor
mail_tf.placeholder = "e-mail"
mail_tf.textColor = UIColor.redColor()
mail_tf.backgroundColor = cl1
mail_tf.borderStyle = UITextBorderStyle.RoundedRect
self.view.addSubview(mail_tf)
pass_tf = UITextField()
pass_tf.frame = CGRectMake(95, 190, 190, 60)
pass_tf.layer.cornerRadius = 10
pass_tf.layer.borderWidth = 1
pass_tf.layer.borderColor = UIColor.blackColor().CGColor
pass_tf.placeholder = "password"
pass_tf.secureTextEntry = true
pass_tf.textColor = UIColor.redColor()
pass_tf.backgroundColor = cl1
pass_tf.borderStyle = UITextBorderStyle.RoundedRect
self.view.addSubview(pass_tf)
btnL = UIButton()
btnL.frame = CGRectMake(195, 260, 90, 40)
btnL.setTitle("Log In ", forState: UIControlState.Normal)
btnL.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
btnL.layer.borderWidth = 1
btnL.layer.borderColor = UIColor.blackColor().CGColor
btnL.layer.cornerRadius = 10
btnL.backgroundColor = cl1
self.view.addSubview(btnL)
btnL.addTarget(self , action: #selector(self.action(_:)), forControlEvents: UIControlEvents.TouchUpInside)
btnC = UIButton()
btnC.frame = CGRectMake(228, 350, 150, 40)
btnC.setTitle("Create new account ", forState: UIControlState.Normal)
btnC.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
btnC.layer.borderWidth = 1
btnC.layer.borderColor = UIColor.blackColor().CGColor
btnC.layer.cornerRadius = 10
btnC.backgroundColor = cl1
self.view.addSubview(btnC)
btnC.addTarget(self , action: #selector(self.action(_:)), forControlEvents: UIControlEvents.TouchUpInside)
}
func action (sender: UIButton!) {
// btnL & btnC open the Logged_in file . there is the problem
let vc = Logged_In()
let navigation = UINavigationController(rootViewController:vc)
self.navigationController?.presentViewController(navigation, animated: true, completion: nil)
let vc1 = create()
let navigation1 = UINavigationController(rootViewController:vc1)
self.navigationController?.presentViewController(navigation1, animated: true, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = "Log in"
self.navigationController?.navigationBar.barTintColor = UIColor.blackColor()
self.navigationController?.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: cl1]
}
}
EDITED ANSWER:
Okay, I think I understand what you are asking now. You want to have the same function action(sender: UIButton) do a different action depending on the button that calls it.
You can actually set a variable called tag and set a number to make it unique. For example btnL.tag = 0 and btnC.tag = 1
So then your function action would look like this:
func action (sender: UIButton!) {
if sender.tag == 0 {
let vc = Logged_In()
let navigation = UINavigationController(rootViewController:vc)
self.navigationController?.presentViewController(navigation, animated: true, completion: nil)
} else if sender.tag == 1 {
let vc1 = create()
let navigation1 = UINavigationController(rootViewController:vc1)
self.navigationController?.presentViewController(navigation1, animated: true, completion: nil)
}
}
A UIButton has a function that does this, specifically:
public func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents)
The buttons need to be declared like this: #IBOutlet var button: UIButton above the class.
To add an action we call the above function in your class (viewController) that has access to variable button:
button.addTarget(self, action: #selector(self.sender(_:)), forControlEvents: .TouchDown)
You'll need to repeat this for each UIButton but the selector function will just be the same (ei, button1.addTarget(...), button2.addTarget(...), etc).
Your function will look something like this:
func sender(sender: UIButton) { }
You can probably iterate through all the buttons you want to add action to
for button in [button1, button2, button3, button4] {
button.addTarget(self, action: #selector(self.someFunction), forControlEvents: .TouchUpInside)
}
Search for all of your buttons and add the same target:
override func viewDidLayoutSubviews() {//This cannot be view did load; it can be view did appear or view will appear
super.viewDidLayoutSubviews()
for subview in self.view.subviews {
if let button = subview as? UIButton {
button.addTarget(target: self, action: #selector(self.someFunc), forControlEvents: .touchUpInside)
}
}
}