web-dev-qa-db-fra.com

Comment personnaliser FBLoginVIew?

Pour me connecter à Facebook dans mon application ios, j'utilise FBLoginVIew depuis Facebook SDK pour iOS .

Il montre un joli bouton de connexion FB, mais je souhaite utiliser ma propre image et mon propre texte pour le bouton de connexion .. Le problème est que je ne vois nulle part comment personnaliser cela.

J'ai réussi à modifier l'image d'arrière-plan du bouton de connexion en remplaçant les images dans FacebookSDKResources.bundle/FBLoginView/images, mais je ne trouvais pas où modifier le texte et la position du bouton de connexion afin qu'il reste "Connexion" ...

Solution, n'importe qui?

Je vous remercie

34
ozba

La solution consiste à examiner les sous-vues FBLoginView, à rechercher le bouton et l'étiquette et à les personnaliser.

Voici le code:

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];
67
ozba

Je voulais être FBLoginview montre comme un UIBarbutton, donc j'ai fait une approche simple: 

J'ai d'abord ajouté FBLoginView en tant que propriété:

@property (nonatomic, strong) FBLoginView* loginView;

Et puis j'ai ajouté la vue de connexion en dehors de la vue:

    self.loginView = [[FBLoginView alloc] init];
    self.loginView.frame = CGRectMake(-500, -500, 0, 0);
    [self.view addSubview:self.loginView];
    self.loginView.delegate = self;

Et puis, j'ai ajouté un UIbarbuttonItem système standard 

    UIBarButtonItem* fbButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(fireFbLoginView)];
    [self.navigationItem setRightBarButtonItem:fbButton];

Et puis je mets le bouton de la barre pour déclencher l'action 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];
    }
  }
}
9
dreampowder

Quand j'écris ceci, Facebook a déjà publié la version 3.0 de leur SDK pour iOS.

la réponse de ozba fonctionne, mais de mon point de vue, elle {ne devrait pas} être utilisée.

  • Tout d’abord, et le plus important, c’est une règle générale selon laquelle il est déconseillé de procéder à une itération dans les sous-vues/superviews d’un composant SDK, car la hiérarchie peut changer entre les versions du SDK}, puis réparer.
  • Deuxièmement, lorsque le bouton est cliqué, pendant une seconde ou deux, il revient au texte d'origine.

Ma solution est vraiment simple. Dans le dossier téléchargé de Facebook, FacebookSDK, vous avez un dossier nommé Exemples. Là, vous devez regarder dans le SessionLoginSample. Vous pouvez voir qu'ils ont un Round Rect Button ordinaire, qui, via le ViewController qui le possède, a le FBLoginViewDelegate, il peut changer le texte en fonction de l'état de FBSession. Croyez-moi, c'est vraiment simple.

8
Bogdan Raducan

Ou lisez la documentation de Facebook pour créer votre propre bouton:

https://developers.facebook.com/docs/ios/login-tutorial/#login-apicalls

comme ça: 

- (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];


             }];

         }
     }];

}
6
Damien Romito

Je crée une classe de boutons FB personnalisée au cas où je devrais la recycler pour d'autres projets. Il s'agit toujours d'une première version, mais permet de modifier l'image du bouton en fonction de l'état de journalisation et de gérer facilement sa taille.

Certaines méthodes sont pour juste au cas où.

Remarque: vous pouvez également placer la vue de bouton du fichier NIB en définissant sa classe sur FBCustomLoginView et son délégué. Toutefois, quelle que soit la taille que vous définissez, elle sera toujours réinitialisée à la taille par défaut de FBLoginView. Vous devez donc toujours définir la taille spécifique dans le code. (Je ne sais pas comment obtenir la taille du cadre de NSCoder pour éviter cela)

Le code est tel quel, vous pouvez le modifier et êtes responsable de tous les bugs qu'il contient. Je modifierai cette réponse au fur et à mesure de ma découverte. J'espère que c'est utile à quelqu'un.

Si vous l'ajoutez à partir de NIB, il vous suffit de l'adapter au texte et aux images souhaités. Le reste fonctionne comme s'il s'agissait d'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
3
htafoya

Je pense avoir trouvé un moyen beaucoup plus simple de personnaliser le texte, par exemple, d'un FBSDKLoginButton sans avoir à créer un bouton entièrement personnalisé à partir de rien, contenant toutes les fonctionnalités de connexion. C'est bien parce que FBSDKLoginButton fait tout le travail - il suffit de changer le texte. Désolé je ne connais que Swift ... voici le code:

var fbButton = FBSDKLoginButton()
var titleText = NSAttributedString(string: "Your new button title")
fbButton.setAttributedTitle(titleText, forState: UIControlState.Normal)

Prendre plaisir!

3
Matt Schwartz

changer le texte du paquet de ressources Facebook en.lproj Localizable.strings ... je suppose que ça marche

3
Luca Rocchi

Je viens de trouver une réponse pour la mise à jour du texte du bouton lorsque vous appuyez sur le bouton de connexion. J'ai subi le même problème.

Pourquoi ne pas essayer de définir le cadre de l'étiquette du bouton sur CGRectMake (0,0,0,0).

J'ai essayé et je pense que ça a fonctionné.

Ajoutez ce code à la réponse de ozba:

[loginLabel setFrame:CGRectMake(0, 0, 0, 0)];

J'espère que cela t'aides.

1
jmac

Veuillez lire le fichier README dans le SDK Facebook. Vous devez ajouter la ligne - FacebookBundleName dans info.plist et lui attribuer un nom. Ensuite, ajoutez un paquet à votre projet avec ce nom et placez-le dans des dossiers nommés "lang.lproj": par exemple: en.lproj - it.lproj - fr.lproj - es.lproj ... ajoutez le fichier Localizable.strings, vous pourrez alors localiser de nombreuses phrases, telles que:

"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";

J'espère que ça vous aide!

1
Mellaito

Positionnez la vue FB à l’écran ou avec une taille de 0x0. Définissez ensuite l'action de votre bouton pour envoyer le message buttonPressed: à la vue FB. Je pense que c'est le moyen le plus simple.

0
pachun

Selon la dernière connexion Facebook pour iOS version 2.3.

Vous pouvez utiliser l'extrait de code suivant pour vous connecter via n'importe quel UIButton personnalisé.

- (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
        }
     }
  }];
}

Voici le lien: https://developers.facebook.com/docs/facebook-login/ios/v2.3#login-apicalls

0
n.by.n

J'ai réfléchi au problème, et personnellement, je n'ai pas vraiment aimé la réponse acceptée ... Pour diverses raisons ... Tout le monde est libre quelle que soit la solution qu'il souhaite, mais j'ai décidé de partager ma propre solution 

for (UIButton *view in loginView.subviews) {
    if ([view respondsToSelector:@selector(addTarget:action:forControlEvents:)]) {
        [view setBackgroundImage:nil forState:UIControlStateNormal];
        [view setBackgroundImage:nil forState:UIControlStateHighlighted];
    }
}

J'ai utilisé respondsToSelector au lieu de isKindOfClass car la classe pourrait être personnalisée à l'avenir.

0
Dumoko

La solution la plus 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)
0
ZAFAR007

Si vous faites référence à https://github.com/facebook/facebook-ios-sdk/blob/master/src/UI/FBLoginView.m , ligne 299, vous verrez que le texte est fourni par une instance méthode dans FBLoginView. Par conséquent, vous pouvez modifier ce texte en dérivant votre propre classe à partir de FBLoginView et en fournissant votre propre implémentation de logInText:

@interface CustomFBLoginView : FBLoginView

@end

@implementation CustomFBLoginView

-(NSString*) logInText {
    return @"Some custom text";
}

@end

C'est un peu risqué car cela dépend des détails de l'implémentation interne.

0
Ian Newson

Dans mon cas, j'ai créé un beau bouton dans Photoshop et je l'ai simplement placé sur le bouton de FaceBook. (Je sais que Apple ne conseille pas de mettre la vue au bouton, mais itérer sur les vues secondaires ne me semble pas agréable). Difficile de comprendre pourquoi une entreprise telle que FB n’a pas fourni un moyen simple de le faire. 

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];
0
Mike.R

Depuis la dernière version 4.X Facebook SDK,

La connexion personnalisée est facilitée, utilisez FBSDKLoginManager

0
Vineeth Joseph