In my code, I call a function to change the image of my custom UIButton from a blue button to a different colored one.
func changeButtonColor(_ colorChange: String, buttonToChange: UIButton) {
switch colorChange {
case "Blue": buttonToChange.setImage(#imageLiteral(resourceName: "blue-glossy-button-blank-hi"), for: .normal)
print("Blue")
case "Green": buttonToChange.setImage(#imageLiteral(resourceName: "asia2Greenadd"), for: .normal)
print("green")
case "Red": buttonToChange.setImage(#imageLiteral(resourceName: "asia2Redadd"), for: .normal)
case "Purple": buttonToChange.setImage(#imageLiteral(resourceName: "asia2add"), for: .normal)
default: print("Error")
}
print("hello")
greenButton1.setImage(#imageLiteral(resourceName: "asia2add"), for: .normal)
}
This function is in the View Controller that it wishes to modify.
Strangely, the "Blue" and the "Green" get printed when they should. And after it prints "Hello" I tried to set the button image again with its corresponding outlet, but when it returns to my view controller,all the buttons are the same images as before. Do I have to do this image setting in viewDidLoad? Am I missing a step for my view to be modified?
This is where I call changeButtonColor
class EditorViewController: UIViewController
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "Back" {
if let destinationVC = segue.destination as? ViewController {
destinationVC.tagColorPairings[button!] = colorToSendBack
delegate?.changeButtonColor(colorToSendBack, buttonToChange: (button)!)
}
}
}
RESOLVED
-I was having a button segue back to my root view controller which was pushing an un-updated VC onto the stack, when I really needed to use self.navigationController?.popToRootViewController
Related
I am using SecondView programmatically. I click the button in ViewController to open SecondView controller, but now I want to back to ViewController from SecondView. I do not have storyboard in SecondView and I want to click the closeButton to go back to ViewController. My code work but when I click the close button it does not work. Any idea?
import UIKit
class SecondView: UIViewController {
var closeButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
closeButton.addTarget(self, action: #selector(dismissActionSheet), for: .touchUpInside)
}
#objc func dismissActionSheet() {
self.navigationController?.popViewController(animated: true)
}
}
You are instantiating a new UIButton, adding a target, but never adding the button to the UI. If you are seeing a button in your UI, it must be one that you added in Interface Builder, not the one you reference here. I suspect your intent was not:
var closeButton = UIButton()
but rather:
#IBOutlet var closeButton: UIButton!
… and hook that button’s outlet in IB.
Or better, rather than adding a target in viewDidLoad, hook up an #IBAction for the button directly in IB:
#IBAction func didTapButton(_ sender: Any) {
navigationController?.popViewController(animated: true)
}
You don't appear to need the closeButton outlet (at least for what you have shared with us thus far).
By the way, popViewController only works if this is embedded in a navigation controller. If you are not using a navigation controller (i.e., you “presented” the view controller rather than “pushing” one), the navigationController will be nil (and navigationController?.popViewController will do nothing). If not using navigation controller, call dismiss rather than popViewController.
If you have created the Second view programmatically:
Why not set a frame to the button and add it to self.view?
eg:
let button = UIButton(frame: CGRect(x: 50, y: 100, width: 80, height: 40))
button.setTitle("Pop VC", for: .normal)
button.addTarget(self, action: #selector(btnTouched), for: .touchUpInside)
self.view.addSubview(button)
then try to pop back:
func btnTouched(sender: UIButton!) {
if let navController = self.navigationController {
navController.popViewController(animated: true)
}
}
Im a beginner in swift and I am creating a login screen using Material.io in Swift and my UI looks like this .
However i dont see anything on my main.storyboard
I am used to creating a segue manually and then using
performSegue(withIdentifier: <#T##String#>, sender: <#T##Any?#>)
to use the segue but now since i dont see the button i'm unable to use the segue on clicking the 2 buttons Login and Register.
Also, usually from main.storyboard you have an IBOutlet or IBAction block to trigger certain features such as do something on a button click.
How does that work when you use MDCButton for instance. How do you link up the button to an action such as trigger a segue or update a text field.
Thank you.
I have declared my button like this
let nextButton: MDCButton = {
let nextButton = MDCButton()
let containerScheme = MDCContainerScheme()
nextButton.applyTextTheme(withScheme: containerScheme)
nextButton.setTitleColor(.white, for: .normal)
nextButton.translatesAutoresizingMaskIntoConstraints = false
nextButton.setTitle("CREATE NEW ACCOUNT", for: .normal)
nextButton.addTarget(self, action: #selector(didTapNext(sender:)), for: .touchUpInside)
return nextButton
}()
And i am calling it like this
#objc func didTapNext(sender: Any) {
self.performSegue(withIdentifier: "toRegistration", sender: self)
self.dismiss(animated: true, completion: nil)
}
I have a segue linking the 2 view controllers.
I can't see your code and don't have enough rep to comment, but it looks like you are building your view programmatically. To see when the button receives touchUp as you would from an outlet, you need to add a target. Try something like this:
func functionWhereYouCreateTheButton() { (PROBABLY YOUR VIEW DID LOAD)
let loginButton = UIButton()...
...
...
...
loginButton.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)
}
func buttonTapped() {
self.performSegue(withIdentifier: "SEGUEID", sender: self)
}
I am trying to activate a segue between a UICollectionView, subview of a UIViewController, and a separate ViewController (called RegisterController). The CollectionView is all set up programmatically, and there is a button on the last cell. However, I can't do the typical performSegue(_:withIdentfier) because the button is in the CollectionView. So, I have set up a method in the ViewController holding the CollectionView to performSegue(_:withIdentifier). I set up an instance in the CollectionViewController to call the method:
lazy var registerButton: UIButton = {
let btn = UIButton(type: .system)
btn.setTitle("Don't have an account?", for: .normal)
btn.setTitleColor(lighterOrange, for: .normal)
btn.addTarget(self, action: #selector(registerScreenAppear), for: .touchUpInside)
return btn
}()
#objc func registerScreenAppear(){
let vc: ViewController = ViewController()
_ = vc.toRegister()
}
The method in the ViewController is
func toRegister(){
performSegue(withIdentifier: "toRegister", sender: self)
}
I am getting the call stack:
NSInvalidArgumentException', reason: 'Receiver (<audible.ViewController: 0x7fe780724770>) has no segue with identifier 'toRegister''
I know I'm probably doing something completely wrong, but I've searched and searched and can't find a solution. Any help is appreciated, thanks
(Yes, I have configured the segue and gave it an identifier in the storyboard, but the reason I have to do this through code is because the CollectionView and the button are created programmatically, so I can't use the Interface Builder)
call performSegue in registerScreenAppear method or call self.toRegister() like
#objc func registerScreenAppear(){
self.toRegister()
}
OR
#objc func registerScreenAppear(){
performSegue(withIdentifier: "toRegister", sender: self)
}
Note: use later one as it will remove the extra function call i.e. toRegister().
I have three buttons that change the colour of my background. I want to hide the RED button when it's pushed. The show it if GREEN or BLUE button is pushed.
The same goes for the GREEN and BLUE buttons.
I can't find a way to call removeFromSuperview. In ObjectiveC I used to do mybutton.hidden = true
but this doesn't work.
ViewController: UIViewController {
#IBAction func RED(_ sender: Any) {
print("background was \(String(describing: self.view.backgroundColor))")
self.view.backgroundColor = UIColor.red
print("background is now \(String(describing: self.view.backgroundColor))")
}
#IBAction func GREEN(_ sender: Any) {
print("background was \(String(describing: self.view.backgroundColor))")
self.view.backgroundColor = UIColor.green
print("background is now \(String(describing: self.view.backgroundColor))")
}
#IBAction func BLUE(_ sender: UIButton) {
print("background was \(String(describing: self.view.backgroundColor))")
self.view.backgroundColor = UIColor.blue
print("background is now \(String(describing: self.view.backgroundColor))")
}
You need to create an IBOutlet for each button in order to access the "isHidden" property. Right now you only have an IBAction defined for each (at least in the code you've provided). To create the IBOutlet, control-drag from the button to your view controller's code, similar to what you did to create the IBActions you already have. In the popup, make sure that "Connection" says "Outlet" and "Type" is "UIButton". Name them as desired (e.g., redButton, blueButton). Then you can type "redButton.isHidden = true" in the appropriate location.
An IBAction only allows you to control what the button will do when it is pressed. An IBOutlet is required to access the properties of a UIButton.
I'm trying to have a button send it's title to a new view controller, and the have a button on the new view controller have it's title set to the original button title.
I know how to do this on one view controller:
#IBAction func buttonPressed(_ sender: Any) {
buttonOne.setTitle("Hello", for: .normal)
buttonTwo.setTitle("Hi there", for: .normal)
But not on another...
I thought maybe to use
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let sendTitle = segue.destination as! ViewControllerTwo
sendTitle.notesent = sender as! String
but I get an error saying that the button can't be translated into a string, which makes sense to me, but I'm not sure how to target the string that is the button's title...
Thanks very much for any assistance!
From your question it appears that you just wondering how to get a title from the button.
In your code you have to exchange sender as! String with
(sender as! UIButton).title(for: .normal)