为了在我的ios应用程序中连接到facebook,我正在使用来自Facebook SDK for iOS的FBLoginVIew。
它显示了一个不错的FB登录按钮,但我想使用我自己的图像和文本作为登录按钮。 问题是我没有在任何地方看到如何定制它。
我设法通过覆盖FacebookSDKResources.bundle / FBLoginView / images中的图像来更改登录按钮背景图像,但是我找不到更改登录按钮文本和位置的位置,所以它保持“登录” ...
解决方案,任何人?
谢谢
答案 0 :(得分:67)
答案是浏览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];
答案 1 :(得分:9)
我想成为一个UIBarbutton的FBLoginview节目,所以我做了一个简单的方法:
首先我将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];
}
}
}
答案 2 :(得分:8)
当我写这篇文章时,Facebook已经发布了适用于iOS的SDK 3.0版。
ozba的回答是有效的,但从我看来,不应该使用。
我的解决方案非常简单。在Facebook的下载文件夹 FacebookSDK 中,您有一个名为 Samples 的文件夹。在那里,你必须查看 SessionLoginSample 。您可以看到它们有一个普通的 Round Rect Button ,它通过拥有它的ViewController具有 FBLoginViewDelegate ,它可以根据FBSession状态更改文本。相信我,这很简单。
答案 3 :(得分:6)
或阅读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];
}];
}
}];
}
答案 4 :(得分:3)
更改Facebook资源包中的文本en.lproj Localizable.strings ...我认为它有效
答案 5 :(得分:3)
我正在创建一个自定义FB按钮类,以防我需要为其他项目回收它,它仍然是第一版,但是可以根据记录状态更改按钮图像并轻松管理其大小。
有些方法适用于实际情况。
作为注释,您还可以通过将其类设置为FBCustomLoginView及其委托来放置NIB文件中的按钮视图,但无论您设置的大小将始终重置为FBLoginView的默认大小,因此您必须始终设置特定大小在代码中。 (我不知道如何从NSCoder获取帧的大小以避免这种情况)
代码是AS-IS,你可以编辑它并对其中的任何错误负责,我会编辑这个答案,因为我发现任何。我希望它对某人有用。
如果您从NIB添加它,您只需使用所需的文本和图像进行调整,其余的就像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
答案 6 :(得分:3)
我认为我找到了一种更简单的方法来自定义文本,例如FBSDKLoginButton,而无需从头开始创建包含所有登录功能的完全自定义按钮。这很好,因为FBSDKLoginButton可以完成所有工作 - 您只需要更改文本即可。对不起,我只知道Swift ......这是代码:
var fbButton = FBSDKLoginButton()
var titleText = NSAttributedString(string: "Your new button title")
fbButton.setAttributedTitle(titleText, forState: UIControlState.Normal)
享受!
答案 7 :(得分:2)
您所有问题的答案,包括登录后的标签,非常简单:
就像OZBA回答完全删除UILabel
(添加:[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];
}
}
}
答案 8 :(得分:1)
我刚按下登录按钮时找到了按钮文本更新的答案。我遇到了同样的问题。
尝试将按钮标签的框架设置为CGRectMake(0,0,0,0)。
我试过了,我觉得它很有用。
将此代码添加到ozba的答案:
[loginLabel setFrame:CGRectMake(0, 0, 0, 0)];
希望这有帮助。
答案 9 :(得分:1)
请阅读Facebook SDK中的README文件。你必须在info.plist中添加Row - FacebookBundleName并为它添加一个名称。然后,使用此名称将捆绑包添加到项目中,并放入名为“lang.lproj”的文件夹中:例如:en.lproj - it.lproj - fr.lproj - es.lproj ....在此文件夹中,您必须添加Localizable.strings文件,然后您可以本地化很多短语,如:
"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";
希望它可以帮到你!
答案 10 :(得分: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
,因为该类可能会在将来自定义。
答案 11 :(得分:0)
将FB视图放在屏幕外,或者大小为0x0。然后,设置按钮的操作以将消息buttonPressed:发送到FB视图。我认为这是最简单的方法。
答案 12 :(得分:0)
在我的情况下,我在Photoshop中创建了一个漂亮的按钮,只需将它放在faceBook按钮的顶部。 (我知道Apple没有建议将视图放在按钮上但是迭代子视图对我来说并不好看)。很难理解为什么像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];
答案 13 :(得分:0)
如果您参考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
这有点冒险,因为它取决于内部实施细节。
答案 14 :(得分:0)
自最新版本4.X Facebook SDK,
自定义登录变得更加轻松,使用FBSDKLoginManager
答案 15 :(得分:0)
根据iOS版2.3的最新Facebook登录。
您可以使用以下代码段通过任何自定义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
答案 16 :(得分:0)
最简单的解决方案
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)