objective-c - developers - login facebook dev
Cómo personalizar FBLoginVIew? (17)
Acabo de encontrar una respuesta para el texto del botón de actualización al presionar el botón de inicio de sesión. Sufrí el mismo problema.
¿Qué tal si intenta configurar el marco de la etiqueta del botón en CGRectMake (0,0,0,0)?
Lo intenté y creo que funcionó.
Agregue este código a la respuesta de ozba:
[loginLabel setFrame:CGRectMake(0, 0, 0, 0)];
Espero que esto ayude.
Para conectarme a Facebook en mi aplicación ios, uso FBLoginVIew de Facebook SDK para iOS .
Muestra un buen botón de inicio de sesión de FB, pero quiero usar mi propia imagen y texto para el botón de inicio de sesión. El problema es que no veo en ninguna parte cómo personalizar eso.
He logrado cambiar la imagen de fondo del botón de inicio de sesión anulando las imágenes en FacebookSDKResources.bundle / FBLoginView / images, pero no he podido encontrar dónde cambiar el texto y la posición del botón de inicio de sesión, por lo que permanece "Iniciar sesión" ...
Solución, alguien?
Gracias
Coloque la vista de FB fuera de pantalla, o con un tamaño de 0x0. Luego, configure la acción de su botón para enviar el botón de mensajePresionada: a la vista FB. Creo que esta es la forma más fácil.
Creo que encontré una forma mucho más sencilla de personalizar el texto, por ejemplo, de un FBSDKLoginButton sin tener que crear un botón completamente personalizado desde cero que contenga todas las funciones de inicio de sesión. Esto es bueno porque el FBSDKLoginButton hace todo el trabajo, solo tiene que cambiar el texto. Lo siento, solo sé Swift ... aquí está el código:
var fbButton = FBSDKLoginButton()
var titleText = NSAttributedString(string: "Your new button title")
fbButton.setAttributedTitle(titleText, forState: UIControlState.Normal)
¡Disfrutar!
De acuerdo con el último inicio de sesión de Facebook para iOS versión 2.3.
Puede usar el siguiente fragmento de código para iniciar sesión mediante cualquier UIButton personalizado.
- (void)loginWithFacebook:(id) sender {
FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init];
[login logInWithReadPermissions:@[@"public_profile",@"email"] handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) {
if (error) {
// Process error
} else if (result.isCancelled) {
// Handle cancellations
} else {
// Login Successful here
// Check for any particular permissions you asked
if ([result.grantedPermissions containsObject:@"email"]) {
// Do work
}
}
}];
}
Aquí está el enlace: https://developers.facebook.com/docs/facebook-login/ios/v2.3#login-apicalls
Desde la última versión 4.X Facebook SDK,
El inicio de sesión personalizado es más fácil, use FBSDKLoginManager
En mi caso, creé un botón atractivo en Photoshop y simplemente lo puse encima del botón de Facebook. (Sé que Apple no aconseja poner vista en el botón Pero iterar en las subvistas no me parece agradable). Es difícil entender por qué una empresa como FB no proporcionó una forma sencilla de hacerlo.
UIImageView *fbImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"facebookButton.png"]];
CGRect newFrame = fBButtonFrame;
newFrame.origin.x = 0; newFrame.origin.y = 0;
[fbImageView setFrame:newFrame];
[fbImageView setUserInteractionEnabled:NO];
FBLoginView *loginView = [[FBLoginView alloc] init];
[loginView setFrame:fBButtonFrame];
[loginView addSubview:fbImageView];
[self.view addSubview:loginView];
Estoy creando una clase de botón FB personalizada en caso de que necesite reciclarla para otros proyectos. Todavía es una primera versión, pero funciona para cambiar la imagen del botón dependiendo del estado registrado y administrar fácilmente su tamaño.
Algunos métodos son para just-in-case.
Como nota, también puede colocar la vista de botón desde el archivo NIB configurando su clase en FBCustomLoginView y su delegado, pero cualquier tamaño que establezca siempre se restablecerá al tamaño predeterminado de FBLoginView, por lo que siempre debe establecer el tamaño específico en el código. (No sé cómo obtener el tamaño de fotograma de NSCoder para evitar esto)
El código es TAL CUAL, usted puede editarlo y es responsable de cualquier error en él. Editaré esta respuesta cuando encuentre alguna. Espero que sea útil para alguien.
En caso de que lo agregue desde NIB, simplemente debe adaptarlo con el texto y las imágenes deseadas, el resto funciona como si fuera un FBLoginView:
_facebookLoginButton.label.text = nil;
[_facebookLoginButton setLoggedImage: [UIImage imageNamed: @"ic_link_fb_on.png"] notLoggedImage: [UIImage imageNamed: @"ic_link_fb_off.png"]];
[_facebookLoginButton wrapButtonToSizeWidth: IS_IPAD ? 38 : 30 height: IS_IPAD ? 38 : 30 ];
FBCustomLoginView.h
#import <Foundation/Foundation.h>
#import <FacebookSDK/FacebookSDK.h>
@interface FBCustomLoginView : FBLoginView <FBLoginViewDelegate>
/** The button actual button */
@property (nonatomic, strong) UIButton* button;
/** The button label */
@property (nonatomic, strong) UILabel* label;
/** To a single button without label, set the same frame for the login button view and the actual button */
- (void)setWrappedButtonFrame:(CGRect)frame;
/** Wraps button to specified size, maintaining frame origin */
- (void)wrapButtonToSizeWidth: (CGFloat) width height: (CGFloat) height;
/** Sets a default background image for all states */
- (void) setBackgroundImage: (UIImage*) image selectedImage: (UIImage*) selectedImage highlightedImage: (UIImage*) highlightedImage disabledImage: (UIImage*) disabledImage;
/** Sets a default background image */
- (void) setBackgroundImage: (UIImage*) image;
/** Resizes the background image to specified size */
- (void) setBackgroundImageSizeWidth: (CGFloat) width height: (CGFloat) height;
/** Place images to manage and differentiate between logged in and out states */
- (void) setLoggedImage: (UIImage*) loggedImage notLoggedImage: (UIImage*) notLoggedImage;
@end
FBCustomLoginView.m
#import "FBCustomLoginView.h"
@interface FBCustomLoginView() {
id<FBLoginViewDelegate> _delegate;
UIImage* _loggedImage;
UIImage* _notLoggedImage;
}
@end
@implementation FBCustomLoginView
@synthesize button = _button;
@synthesize label = _label;
#pragma mark - View lifecycle, superclass override
- (id)init {
if (self = [super init]) {
[self getReferences];
}
return self;
}
- (id)initWithFrame:(CGRect)frame {
if(self = [super initWithFrame: frame]) {
[self getReferences];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if (self = [super initWithCoder: aDecoder]) {
[self getReferences];
}
return self;
}
- (void) getReferences {
for (id obj in self.subviews) {
if ([obj isKindOfClass:[UIButton class]]) {
self.button = obj;
}
if ([obj isKindOfClass:[UILabel class]]) {
self.label = obj;
}
}
}
- (void)setDelegate:(id<FBLoginViewDelegate>)delegate {
_delegate = delegate;
[super setDelegate: self];
}
#pragma mark - FBLoginViewDelegate
- (void)loginViewShowingLoggedInUser:(FBLoginView *)loginView {
if (_loggedImage) {
[self setBackgroundImage: _loggedImage];
}
[_delegate loginViewShowingLoggedInUser: loginView];
}
- (void)loginViewFetchedUserInfo:(FBLoginView *)loginView
user:(id<FBGraphUser>)user {
[_delegate loginViewFetchedUserInfo: loginView user: user];
}
- (void)loginViewShowingLoggedOutUser:(FBLoginView *)loginView {
if (_notLoggedImage) {
[self setBackgroundImage: _notLoggedImage];
}
[_delegate loginViewShowingLoggedOutUser: loginView];
}
- (void)loginView:(FBLoginView *)loginView handleError:(NSError *)error {
if ([_delegate respondsToSelector: @selector(loginView:handleError:)]) {
[_delegate performSelector: @selector(loginView:handleError:) withObject: loginView withObject: error];
}
}
#pragma mark - Custom methods
/** To a single button without label, set the same frame for the login button view and the actual button */
- (void)setWrappedButtonFrame:(CGRect)frame {
[super setFrame: frame];
if (_button) {
[self setBackgroundImageSizeWidth: frame.size.width height: frame.size.height];
}
}
/** Wraps button to specified size, maintaining frame origin */
- (void)wrapButtonToSizeWidth: (CGFloat) width height: (CGFloat) height {
[super setFrame: CGRectMake(self.frame.origin.x, self.frame.origin.y, width, height)];
if (_button) {
[self setBackgroundImageSizeWidth: width height: height];
}
}
- (void) setBackgroundImage: (UIImage*) image selectedImage: (UIImage*) selectedImage highlightedImage: (UIImage*) highlightedImage disabledImage: (UIImage*) disabledImage {
[_button setBackgroundImage:image forState:UIControlStateNormal];
[_button setBackgroundImage:selectedImage forState:UIControlStateSelected];
[_button setBackgroundImage:highlightedImage forState:UIControlStateHighlighted];
[_button setBackgroundImage:disabledImage forState:UIControlStateDisabled];
}
- (void) setBackgroundImage: (UIImage*) image {
[self setBackgroundImage: image selectedImage:nil highlightedImage:nil disabledImage:nil];
}
- (void) setBackgroundImageSizeWidth: (CGFloat) width height: (CGFloat) height {
_button.frame = CGRectMake(0, 0, width, height);
}
- (void) setLoggedImage: (UIImage*) loggedImage notLoggedImage: (UIImage*) notLoggedImage {
_loggedImage = loggedImage;
_notLoggedImage = notLoggedImage;
[self setBackgroundImage: notLoggedImage];
}
@end
La respuesta a todos sus problemas, incluida la etiqueta después de iniciar sesión, es muy simple: es como la respuesta de OZBA, simplemente elimine completamente el UILabel
(agregue: [loginLabel removeFromSuperview];
)
Este es el código de trabajo completo:
- (void)setFacebookConnectButton{
self.loginView.readPermissions = @[@"public_profile", @"email", @"user_friends"];
[self.loginView setDelegate:self];
for (id obj in self.loginView.subviews)
{
if ([obj isKindOfClass:[UIButton class]])
{
UIButton * loginButton = obj;
UIImage *loginImage = [UIImage imageNamed:@"fb_connect"];
[loginButton setBackgroundImage:loginImage forState:UIControlStateNormal];
[loginButton setBackgroundImage:nil forState:UIControlStateSelected];
[loginButton setBackgroundImage:nil forState:UIControlStateHighlighted];
[loginButton setTitle:nil forState:UIControlStateSelected];
[loginButton setTitle:nil forState:UIControlStateHighlighted];
[loginButton sizeToFit];
}
if ([obj isKindOfClass:[UILabel class]])
{
UILabel * loginLabel = obj;
loginLabel.text = @"";
loginLabel.textAlignment = NSTextAlignmentCenter;
loginLabel.frame = CGRectMake(0, 0, 271, 37);
[loginLabel removeFromSuperview];
}
}
}
La respuesta es revisar las subvistas de FBLoginView, buscar el botón y la etiqueta y personalizarlas.
Aquí está el código:
FBLoginView *loginview =
[[FBLoginView alloc] initWithPermissions:[NSArray arrayWithObject:@"publish_actions"]];
loginview.frame = CGRectMake(4, 95, 271, 37);
for (id obj in loginview.subviews)
{
if ([obj isKindOfClass:[UIButton class]])
{
UIButton * loginButton = obj;
UIImage *loginImage = [UIImage imageNamed:@"YourImg.png"];
[loginButton setBackgroundImage:loginImage forState:UIControlStateNormal];
[loginButton setBackgroundImage:nil forState:UIControlStateSelected];
[loginButton setBackgroundImage:nil forState:UIControlStateHighlighted];
[loginButton sizeToFit];
}
if ([obj isKindOfClass:[UILabel class]])
{
UILabel * loginLabel = obj;
loginLabel.text = @"Log in to facebook";
loginLabel.textAlignment = UITextAlignmentCenter;
loginLabel.frame = CGRectMake(0, 0, 271, 37);
}
}
loginview.delegate = self;
[self.view addSubview:loginview];
O lea la documentación de Facebook para crear su propio botón:
https://developers.facebook.com/docs/ios/login-tutorial/#login-apicalls
Me gusta esto:
- (void) buttonSelector
{
[FBSession openActiveSessionWithReadPermissions:@[@"basic_info"]
allowLoginUI:YES
completionHandler:
^(FBSession *session, FBSessionState state, NSError *error) {
if (FBSession.activeSession.state == FBSessionStateOpen) {
//To get the use
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection,NSDictionary<FBGraphUser> *user, NSError *error) {
NSString *token = [[[FBSession activeSession] accessTokenData] accessToken];
}];
}
}];
}
Pensé en el problema, y personalmente no me gustó la respuesta aceptada ... Por varias razones. Todos están libres de cualquier solución que les guste, pero decidí compartir mi propia solución.
for (UIButton *view in loginView.subviews) {
if ([view respondsToSelector:@selector(addTarget:action:forControlEvents:)]) {
[view setBackgroundImage:nil forState:UIControlStateNormal];
[view setBackgroundImage:nil forState:UIControlStateHighlighted];
}
}
Utilicé respondsToSelector
lugar de isKindOfClass
porque la clase podría ser personalizada en el futuro.
Por favor, lea el archivo README en Facebook SDK. Debe agregar la Fila - FacebookBundleName en info.plist y ponerle un nombre para su paquete. Luego, agregue un paquete a su proyecto con este nombre y colóquelo en carpetas llamadas "lang.lproj": por ejemplo: en.lproj - it.lproj - fr.lproj - es.lproj .... En estas carpetas debe agregue el archivo Localizable.strings, luego puede localizar muchas frases, como:
"FBLV:LogOutButton" = "Log Out";
"FBLV:LogInButton" = "Log In";
"FBLV:LoggedInAs" = "Logged in as: %@";
"FBLV:LoggedInUsingFacebook" = "Logged in using Facebook";
"FBLV:LogOutAction" = "Log Out";
"FBLV:CancelAction" = "Cancel";
Espero que te ayude!
Si consulta https://github.com/facebook/facebook-ios-sdk/blob/master/src/UI/FBLoginView.m , línea 299, verá que el texto es proporcionado por un método de instancia en FBLoginView. Por lo tanto, puede cambiar este texto derivando su propia clase de FBLoginView y proporcionando su propia implementación de logInText:
@interface CustomFBLoginView : FBLoginView
@end
@implementation CustomFBLoginView
-(NSString*) logInText {
return @"Some custom text";
}
@end
Esto es un poco arriesgado, ya que depende de los detalles de implementación interna.
Yo quería ser FBL. Visiones de muestra como un botón UIB, así que hice un enfoque simple:
Primero agregué FBLoginView como una propiedad:
@property (nonatomic, strong) FBLoginView* loginView;
Y luego agregué la vista de inicio de sesión fuera de la vista:
self.loginView = [[FBLoginView alloc] init];
self.loginView.frame = CGRectMake(-500, -500, 0, 0);
[self.view addSubview:self.loginView];
self.loginView.delegate = self;
Y luego, agregué un sistema estándar UIbarbuttonItem
UIBarButtonItem* fbButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(fireFbLoginView)];
[self.navigationItem setRightBarButtonItem:fbButton];
Y luego configuro el botón de la barra para disparar la acción de clic de FBLoginView;)
-(void)fireFbLoginView{
for(id object in self.loginView.subviews){
if([[object class] isSubclassOfClass:[UIButton class]]){
UIButton* button = (UIButton*)object;
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
}
cambiar texto en el paquete de recursos de Facebook en.lproj Localizable.strings ... supongo que funciona
Cuando estoy escribiendo esto, Facebook ya ha lanzado la versión 3.0 de su SDK para iOS.
La respuesta de ozba está funcionando pero, desde mi opinión, no debería usarse.
- En primer lugar, y más importante, es una regla general que es una mala práctica iterar a través de las subvistas / superviews de un componente SDK porque la jerarquía puede cambiar entre las versiones SDK , causando errores que serán difíciles de rastrear y, luego, reparar.
- En segundo lugar, cuando se hace clic en el botón, durante uno o dos segundos, vuelve al texto original.
Mi solución es realmente simple. En la carpeta descargada de Facebook , FacebookSDK , tiene una carpeta llamada Muestras . Allí, debe mirar en la SessionLoginSample . Puede ver que tienen un Botón de Rectángulo Redondo ordinario, que, a través del Controlador de Vista que lo posee, que tiene el FBLoginViewDelegate , puede cambiar el texto dependiendo del estado de FBSession. Confía en mí, es realmente simple.
La solución más simple
let FB_LoginButton = FBSDKLoginButton()
let imgV = UIImageView(frame: FB_LoginButton.frame)
img.image = UIImage(named: "Your Image Name")
let textV = UILabel(frame: CGRect(x: 0, y: 0, width: FB_LoginButton.frame.size.width, height: 20)) // Set Frames as you need
textV.text = "Your Text"
textV.font = textV.font.fontWithSize(20)
// Swift 3
textV.font = textV.font.withSize(20)
imgV.addSubview(textV)
FB_LoginButton.addSubview(imgV)