Как настроить FBLoginVIew?

для подключения к facebook в моем приложении ios я использую FBLoginVIew из Facebook SDK для iOS.

Он показывает хорошую кнопку входа FB, но я хочу использовать свое собственное изображение и текст для кнопки входа. Проблема в том, что я не вижу, как настроить это.

мне удалось изменить фоновое изображение кнопки входа в систему, переопределив изображения в FacebookSDKResources.bundle/FBLoginView / images, Но я не мог найти, где изменить логин текст и положение кнопки, поэтому он остается "войти"...

решение, кто?

спасибо

17 ответов


ответ состоит в том, чтобы перейти к подвидам FBLoginView, найти кнопку и метку и настроить их.

вот код:

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

Я хотел быть fbloginview показывает как UIBarbutton, поэтому я сделал простой подход:

сначала я добавил FBLoginView как свойство:

@property (nonatomic, strong) FBLoginView* loginView;

и затем я добавил представление входа в систему вне представления:

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

и затем я добавил стандартную систему UIbarbuttonItem

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

и затем я установил кнопку панели, чтобы запустить действие щелчка FBLoginView;)

-(void)fireFbLoginView{
for(id object in self.loginView.subviews){
    if([[object class] isSubclassOfClass:[UIButton class]]){
        UIButton* button = (UIButton*)object;
        [button sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
  }
}

когда я пишу это, Facebook уже выпустил версию 3.0 своего SDK для iOS.

ответ озбы вроде как работает, но, на мой взгляд, это не стоит использоваться.

  • во-первых, и самое главное, это общее правило, что это плохая практика итерации через подвиды / обзоры компонента SDK, потому что иерархия может меняться между версиями SDK, вызывая ошибки, которые будут трудно трек, а затем ремонт.
  • во-вторых, когда кнопка нажата, на секунду или две она возвращается к исходному тексту.

мое решение очень простое. В загруженной папке Facebook,FacebookSDK, у вас есть папка с именем образцы. Там, вы должны посмотреть в SessionLoginSample. Вы можете видеть, что у них обычный Круглая Кнопка Rect, который через ViewController, которому он принадлежит, что имеет FBLoginViewDelegate, он может изменять текст в зависимости от состояния FBSession. Поверь мне, все очень просто.


или прочитайте документацию Facebook, чтобы создать свою собственную кнопку:

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

такой:

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


             }];

         }
     }];

}

изменить текст в пакете ресурсов Facebook en.lproj по локализации.веревка... я полагаю, это работает


Я создаю пользовательский класс кнопки FB в случае, если мне нужно переработать его для других проектов, он по-прежнему является первой версией, но работает, чтобы изменить изображение кнопки в зависимости от состояния журнала и легко управлять его размером.

некоторые методы предназначены для Just-in-case.

как Примечание, Вы также можете поместить вид кнопки из файла NIB, установив его класс В FBCustomLoginView и его делегат, но какой бы размер вы ни установили, он всегда будет сброшен до размера по умолчанию FBLoginView, поэтому вы необходимо всегда задавать определенный размер в коде. (Я не знаю, как получить размер кадра из NSCoder, чтобы избежать этого)

код как есть, вы можете редактировать его и нести ответственность за любые ошибки в нем, я буду редактировать этот ответ, как я нахожу любой. Надеюсь, это кому-то пригодится.

в случае, если вы добавляете его из пера, вы просто адаптируете его с нужным текстом и изображениями, остальное работает так, как будто это 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.м

#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

Я думаю, что нашел гораздо более простой способ настроить текст, например, FBSDKLoginButton без необходимости создавать полностью настроенную кнопку с нуля, которая содержит все функции входа в систему. Это хорошо, потому что FBSDKLoginButton делает всю работу - вам просто нужно изменить текст. Извините, я знаю только Свифта...вот код:

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

наслаждайтесь!


ответ на все ваши проблемы, включая метку после нажатия входа в систему, очень прост: Это как OZBA ответ просто удалить полностью UILabel (add:[loginLabel removeFromSuperview];)

это полный рабочий код:

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

пожалуйста, прочитайте файл README в Facebook SDK. Вы должны добавить строку-FacebookBundleName в info.plist и поставьте его имя для вашего пакета. Затем добавьте пакет в свой проект с этим именем и поместите в папки с именем "lang.lproj": например: en.lproj по - его.lproj-fr.lproj по - Эс.lproj все.... В эти папки вы должны добавить Localizable.строки файла, то вы можете локализовать много фраз, как:

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

надеюсь, это поможет вам!


Я только что нашел ответ на обновление текста кнопки при нажатии кнопки входа в систему. У меня была та же проблема.

Как насчет попробовать установить рамку метки кнопки в CGRectMake (0,0,0,0).

я попробовал, и я думаю, что это сработало.

добавьте этот код в ответ озбы:

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

надеюсь, что это помогает.


Я думал о проблеме, и мне лично не очень понравился принятый ответ... По разным причинам. Каждый свободен в любом решении, которое ему нравится, но я решил поделиться своим собственным решением.

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

Я respondsToSelector вместо isKindOfClass потому что класс может быть выполнен в будущем.


расположите вид FB за пределами экрана или с размером 0x0. Затем установите Действие кнопки для отправки сообщения buttonPressed: в представление FB. Думаю, это самый простой способ.


в моем случае я создал красивую кнопку в Photoshop и просто положил ее поверх кнопки faceBook. (Я знаю, что Apple не советует ставить view on button, но итерация на подвидах мне не нравится). Трудно понять, почему такая компания, как FB, не предоставила простой способ сделать это.

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

Если вы ссылаетесь на https://github.com/facebook/facebook-ios-sdk/blob/master/src/UI/FBLoginView.m, строка 299 вы увидите, что текст предоставляется методом экземпляра в FBLoginView. Поэтому вы можете изменить этот текст, получив свой собственный класс из FBLoginView и предоставив свою собственную реализацию logInText:

@interface CustomFBLoginView : FBLoginView

@end

@implementation CustomFBLoginView

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

@end

Это немного рискованно, поскольку это зависит от внутренних деталей реализации.


начиная с последней версии 4.X Facebook SDK,

пользовательский логин упрощен, используйте FBSDKLoginManager


согласно последнему логину Facebook для iOS версии 2.3.

вы можете использовать следующий фрагмент кода для входа в систему через любой пользовательский UIButton.

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

вот ссылка:https://developers.facebook.com/docs/facebook-login/ios/v2.3#login-apicalls


Простое Решение

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)