I'm trying to add Google sign in functionality to a custom button, and I'm following this tutorial. It's telling me to select the button, and set its class as GIDSignInButton, then add this code: #IBOutlet weak var signInButton: GIDSignInButton!.
However, it doesn't let me set the class to GIDSignInButton. When I type it in and press enter, the field just clears.
You should try assign GIDSignInButton not to the Button Object from the Object library but to the the View Object instead
It's work for me.
It will look like this using UIView instead of UIButton.
You can create UIButton and then on its action method you can write this code for signing via google:
GIDSignIn.sharedInstance().signIn()
It works for me, in this way you can customize UIButton according to your requirement and also perform signin by using google
That's because GIDSignInButton is a subclass of UIView, not UIButton.
Add to the storyboard / nib a regular UIView and change it's class to GIDSignInButton instead.
From google doc:
Add a GIDSignInButton to your storyboard, XIB file, or instantiate it
programmatically. To add the button to your storyboard or XIB file,
add a View and set its custom class to GIDSignInButton.
GIDSignInButton can be set by using a UIView or a UIButton.
If you are using GIDSignInButton as a UIButton
open the storyboard as source code
Find the button in resulting XML
Add the below code as an attribute for the button tag
customClass="GIDSignInButton"
4.open storyboard again as Interface Builder, button class will be changed
If you are using GIDSignInButton as a UIView
1.copy paste the custom class as GIDSignInButton in Identity Inspector
The second one is the correct approach in my opinion.
The workaround is open the storyboard in text mode and put it directly. When you return to the interface builder it will show normally.
Open storyboard as source code.
Locate the button in the xml.
Set customClass="GIDSignInButton" as an attribute for the button tag.
Open storyboard as interface builder.
You can now link the button to the IBOutlet
If you use a UIView instead of a UIButton, you can assign the view a custom class of GIDSignInButton. From there you can connect the view to a button outlet and action as seen below.
#IBOutlet weak var googleLoginButton: GIDSignInButton!
#IBAction func googleLoginButtonPressed(_ sender: Any) {
GIDSignIn.sharedInstance()?.signIn()
}
I had the same problem a few months ago,
Your code seems to be right
#IBOutlet weak var signInButton: GIDSignInButton!
But, the problem might be
• You haven’t added the Framework properly
(Go to your project setting in the left side navigator, and click Build phases, add your framework and SHIFT + CMD + K)
• Or alternatively, go ahead and write the #IBOutlet in your swift file, then drag the button to assign it
• your last option is to close xcode, or maybe delete the derived data
Xcode itself has plenty of bugs, I am not sure if it’s your problem, it’s xcode’s
Hope this helps!
The simple way to do is just make a button action and paste the following lines in it.
#IBAction func gSignInAction(_ sender: Any) {
GIDSignIn.sharedInstance()?.signIn()
}
Use UIView instead of UIButton and assign custom class as GIDSignInButton
Swift- 5
Open storyboard as source code.
Locate the button in the xml.
Set customClass="GIDSignInButton" as an attribute for the button tag.
Open storyboard as interface builder.
//MARK:- You will not find this with button XML Forcly Add this (customClass="GIDSignInButton")[![enter image description here][1]][1]
Related
I am working on an iOS project in Xcode 11 to create an app that converts Farenheit to Celsius. I deleted the default ViewController.swift file and created a custom class with a more descriptive name called ConversionViewController.swift. This file was then saved to the current project. The file contains these lines of code:
class ConversionViewController: UIViewController {
#IBOutlet var celsiusLabel: UILabel!
#IBAction func fahrenheitFieldEditingChanged(_ textField: UITextField) {
celsiusLabel.text = textField.text
}
}
In Main.storyboard I selected the View Controller in the document outline then opened the identity inspector. In the Custom Class section of the identity inspector I changed the class to ConversionViewController and below the module field I checked Inherit module from target. Next, I want to create an outlet to the Celsius text label and create an action for the text field to call when the text changes. So, I open Main.storyboard and try to control-drag from the Conversion View Controller in the document outline to the Celsius label and connect it to the celsiusLabel in ConversionViewController.swift.
The problem is that Xcode won't let me. When I control-drag from the Conversion View Controller to the Celsius label nothing happens. I don't get a pop-up box that gives me the option to select the outlet celsiusLabel.
I've tried going to Product --> Clean Build Folder but that didn't fix the problem. Is there a step missing? I am using the iOS Programming: Big Nerd Ranch Guide 6th edition, which I know isn't written for Xcode 11.
When I control-drag from the Conversion View Controller to the Celsius label nothing happens. I don't get a pop-up box that gives me the option to select the outlet celsiusLabel.
Yes, I often see that problem. Usually I can solve it by dragging a different way. For example, select the label, switch on the right to the Connections inspector, and drag from the circle next to New Referencing Outlet onto the view controller in the outline. Now does it let you make the connection?
In your StoryBoard select the ViewController by clicking on top where the name is displayed after that select the connections inspector (last option). You will see your celsius label there under outlets. Drag from the label's empty circle there to the label in the ViewController's View and connect.
I have faced the same problem:-
It will be resolved by two ways:-
1) After changing the name of the .swift file just clean the build. If it not lets you create outlet then just quit the xcode and run it again then it will allow you to add outlet to the class.
2). In the connections Inspector select the circle coming under Referencing Outlets and drag that to the viewController to create outlet of the control.
This typically happens to me when I move or rename a file. The fix in those circumstances is to remove the file from the 'compile sources' list, then re-add. Then build (no need for clean build).
I am using Xcode 9.1 and trying to build a program. I have designed one textbook , one label and one button. Now I am trying to place the textbook in view controller to code it, But Unable to do this.
In your view controller, you want to setup an outlet. Add a property like
#IBOutlet var textField: UITextField?
In the interface you have screenshot, a small circle should then appear next to it, which you want to drag over to connect to your text field. This creates a binding between the property in your controller and the view element.
You can then reference this property in your controller to access the text field.
I wrote some code in Swift for an iOS app in XCode (7.1.1) and I can't use the drag and drop in the interface builder for the outlet I want to connect. I tried to do it manually too but the outlet didn't show up in the reference collection when I tried to do it.
I did see this answer:
Can't connect IBOutlet in Interface Builder
But this appears to be for Objective-C/older versions of XCode. The way I have it right now is I have my main DataViewController.swift file and then I created a PhotoViewer.swift file (it's just an example so the code doesn't really matter it's pretty simple). I used the following code:
import Foundation
import UIKit
class PhotoViewer: UIViewController {
#IBOutlet weak var viewerButton: UIButton!
func loadPhotoUI() {
viewerButton.setTitle("View Photos", forState: .Normal)
}
}
The viewerButton does not show up as an option and when I open up the story board and try to Ctrl-Click and drag to the file on the right side, it doesn't let me drop it in.
If I try it on the DataViewController.swift file (the one that was there when I started the initial template), it still works.
I'm guessing I just need to change a setting on the new file but I can't seem to figure that out. I basically will be using the classes functions in the DataViewController like:
let photoClass = PhotoViewer()
self.photoClass.loadPhotoUI()
etc etc. I'm just wanting to keep everything super organized.
I'm obviously a bit of a noob at Swift so thanks for the help!
Your ViewController in your Storyboard needs to be linked to your Swift file.
You have to change the Class to "PhotoViewer" in your Identify Inspector in your Storyboard Viewcontroller:
I know the second button here shows the Assistant editor:
And I know how to make an Outlet and Action by Control dragging from an object in the Interface Builder to the View Controller code. Ideally it should be as easy as the documentation makes it look:
But this is usually what Xcode actually looks like for me when I press the "Assistant" editor:
A mess. I have to minimize lots of things, try to get the storyboard object in view, and then go find the right View Controller. All this before I can do the Control-drag.
Is there a way to make the connection without using the Assistant editor? (And preferably without having to type a lot of code in myself.)
Don't press the assistant editor button. Sometimes it opens a random file instead of the one you want.
When you are in Storyboard, Option click on the .h file that you want to open in the Project Navigator. This will open the proper .h file to add the outlets or actions.
When you're done, close the Assistant editor right pane (which is displaying the .h file) and you will be back in Storyboard.
Yes, you can do it without the Assistant editor and without writing lots of code. It requires learning to do two things:
Use code snippets
Use the Connections inspector
Create code snippets for the IBOutlet and IBAction
Normally when you create an IBOutlet and IBAction with the Assistant editor it automatically adds code like this to your View Controller:
#IBOutlet weak var myOutletName: UIButton!
#IBAction func myActionName(sender: AnyObject) {
}
You could type this all yourself and then add the connection in the Connection inspector, but why do all that typing? Just make a code snippet that will autocomplete. Drag the code to the Code Snippets library in the Utility panel.
Give it a title and most importantly, a Completion Shortcut. I called mine "ibaction" for the #IBAction code.
Now all I have to do is start typing "ibaction" and I can autocomplete the code snippet. I only have to edit the name of the action. It is a similar process for the Outlet.
Read more about creating code snippets:
Xcode Snippets
Creating a Custom Code Snippet
Now all you have to do is connect the IB object to the code.
Make the connection with the Connections inspector
First, click the object in the storyboard that you want to connect. For me, I am using a Button.
Then select the Connections inspector. It is on the far right.
Alternatively, you can right click or control click the object to get a menu.
Then click the New Referencing Outlet to connect it to your Outlet or the Touch Up Inside under Sent Events to connect it to your Action.
For whatever reason I find that sometimes I need to drag just a little bit after clicking the "+" button to get the menu of available connections to show up.
I have a number of view controllers, each with their own menu button (a UIBarButton, added in the storyboard). Now I want to link all these up to a single #IBAction function in their superclass (the superclass is the same for all the view controllers with that menubutton).
Now I have linked up #IBOutlets to a superclass before, but it doesn't seem to work with #IBActions, even though the function isn't private, and it definitely is part of the superclass (I am refactoring, previously it was an #IBAction in each class, which only did menuButtonTap() (calling the method in the superclass).
Any ideas?
I have solved the problem by manually creating an #IBAction on the superclass, and giving them the same name as the ones I create in the subclasses. Then I deleted the ones in the subclasses. This leaves a 'dangling reference' from the storyboard, according to Xcode, but I know it's there.
Although this still does not work as of Xcode 9.4 for general purpose UIViewController (but your workaround still does work 👍🏻), please note that it works as expected for UITableViewCell templates in storyboard.
If some of your template cells in storyboard share the same base class containing #IBOutlet properties, you will be able to link them to every template cell instance as you usually do:
Then Xcode will show a popup for telling in which prototype cell the link is "backed":
I'm not sure why this second step is necessary though, since you designate a specific component from within a given prototype cell
You can do it like you do when adding an action to a UITabbar button from subview class.
Assuming btn is a UIBarButtonItem,
[btn setTarget:self.superview];
[btn setAction:#selector(menuButtonTap:)]
Are you using __unused keyword by any chance? If you do the IBAction won't show up in storyboard(I am using Xcode 6.3.2)
- (IBAction)actionBack:(__unused id)sender;
vs
- (IBAction)actionBack:(id)sender;
To make it show up and selectable removed the __unsused keyword.