ios 如何自定义FBLoginVIew?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12280850/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to customize FBLoginVIew?
提问by ozba
In order to connect to facebook in my ios app i'm using FBLoginVIew from Facebook SDK for iOS.
为了在我的 ios 应用程序中连接到 facebook,我正在使用Facebook SDK for iOS 中的FBLoginVIew 。
It shows a nice FB Login Button, but I want to use my own image and text for the login button. The problem is that I don't see anywhere how to customize that.
它显示了一个不错的 FB 登录按钮,但我想使用我自己的图像和文本作为登录按钮。问题是我在任何地方都看不到如何自定义它。
I've managed to change the login button background image by overriding the images in FacebookSDKResources.bundle/FBLoginView/images, but I couldn't find where to change the login button text and position, so it's stays "Log in"...
我设法通过覆盖 FacebookSDKResources.bundle/FBLoginView/images 中的图像来更改登录按钮背景图像,但我找不到更改登录按钮文本和位置的位置,因此它保持“登录”...
Solution, anyone?
解决方案,有人吗?
Thank you
谢谢
回答by ozba
The answer is to go over the FBLoginView subviews, find the button and the label and customize them.
答案是查看 FBLoginView 子视图,找到按钮和标签并对其进行自定义。
Here is the 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];
回答by dreampowder
I wanted to be FBLoginview shows as a UIBarbutton, So i have made a simple approach:
我想将 FBLoginview 显示为 UIBarbutton,所以我做了一个简单的方法:
First i've added FBLoginView as a property:
首先,我添加了 FBLoginView 作为属性:
@property (nonatomic, strong) FBLoginView* loginView;
And then i've added the login view outside the view:
然后我在视图之外添加了登录视图:
self.loginView = [[FBLoginView alloc] init];
self.loginView.frame = CGRectMake(-500, -500, 0, 0);
[self.view addSubview:self.loginView];
self.loginView.delegate = self;
And then, i've added a standard system UIbarbuttonItem
然后,我添加了一个标准系统 UIbarbuttonItem
UIBarButtonItem* fbButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(fireFbLoginView)];
[self.navigationItem setRightBarButtonItem:fbButton];
And then i set the bar button to fire click action of the FBLoginView ;)
然后我设置栏按钮来触发 FBLoginView 的点击动作;)
-(void)fireFbLoginView{
for(id object in self.loginView.subviews){
if([[object class] isSubclassOfClass:[UIButton class]]){
UIButton* button = (UIButton*)object;
[button sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}
}
回答by Bogdan Raducan
When I'm writing this, Facebook has already released version 3.0 of their SDK for iOS.
在我写这篇文章的时候,Facebook 已经发布了他们的 iOS SDK 3.0 版。
ozba's answer is sort of working but, from my opinion, it shouldn'tbe used.
ozba 的答案是有效的,但在我看来,不应该使用它。
- Firstly, and most important, it's a general rule that it's bad practice to iterate through the subviews/superviews of an SDK component because the hierarchy can change between the SDK versions, causing errors that will be hard to track and, then, repair.
- Secondly, when the button is clicked, for a second or two, it comes back to the original text.
- 首先,也是最重要的一点是,循环访问 SDK 组件的子视图/超级视图是一种不好的做法,因为SDK 版本之间的层次结构可能会发生变化,从而导致难以跟踪和修复的错误。
- 其次,当单击按钮时,一两秒钟,它会返回到原始文本。
My solution is really simple. In Facebook's downloaded folder, FacebookSDK, you have a folder named Samples. There, you must look in the SessionLoginSample. You can see that they have an ordinary Round Rect Button, which, through the ViewController that owns it, that has the FBLoginViewDelegate, it can change text depending on the FBSession state. Trust me, it's really simple.
我的解决方案非常简单。在 Facebook 的下载文件夹FacebookSDK 中,您有一个名为Samples的文件夹。在那里,您必须查看SessionLoginSample。你可以看到他们有一个普通的Round Rect Button,它通过拥有它的 ViewController 拥有FBLoginViewDelegate,它可以根据 FBSession 状态更改文本。相信我,这真的很简单。
回答by Damien Romito
Or read the documentation of Facebook to build Your Own Button:
或者阅读 Facebook 的文档来构建你自己的按钮:
https://developers.facebook.com/docs/ios/login-tutorial/#login-apicalls
https://developers.facebook.com/docs/ios/login-tutorial/#login-apicalls
like this:
像这样:
- (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];
}];
}
}];
}
回答by Luca Rocchi
change text in the Facebook resource bundle en.lproj Localizable.strings ... i suppose it works
更改 Facebook 资源包中的文本 en.lproj Localizable.strings ... 我想它可以工作
回答by htafoya
I am creating a custom FB button class in case I need to recycle it for other projects, It is still a first-version but works to change the button image depending on logged state and easily manage its size.
我正在创建一个自定义 FB 按钮类,以防我需要为其他项目回收它,它仍然是第一个版本,但可以根据记录状态更改按钮图像并轻松管理其大小。
Some methods are for just-in-case.
有些方法是为了以防万一。
As a note, you can also place the button view from the NIB file by setting its class to FBCustomLoginView and its delegate, but whatever size you set will always be reseted to FBLoginView's default size, so you must always set the specific size in code. (I don't know how to get frame's size from NSCoder to avoid this)
请注意,您还可以通过将其类设置为 FBCustomLoginView 及其委托来放置 NIB 文件中的按钮视图,但是无论您设置什么大小,都将始终重置为 FBLoginView 的默认大小,因此您必须始终在代码中设置特定大小。(我不知道如何从 NSCoder 获取框架的大小来避免这种情况)
Code is AS-IS, you may edit it and are responsible of any bugs in it, I will edit this answer as I find any. I hope it is useful to someone.
代码是按原样的,您可以编辑它并对其中的任何错误负责,我会在发现任何错误时编辑此答案。我希望它对某人有用。
In case you add it from NIB, you just adapt it with desired text and images, the rest works as if it was a FBLoginView:
如果您从 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
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
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
回答by Matt Schwartz
I think I found a much easier way to customize the text, for example, of a FBSDKLoginButton without having to create a fully customized button from scratch that contains all the login functionality. This is nice because the FBSDKLoginButton does all the work - you just have to change the text. Sorry I only know Swift...here is the code:
我想我找到了一种更简单的方法来自定义文本,例如 FBSDKLoginButton 的文本,而无需从头开始创建一个包含所有登录功能的完全自定义按钮。这很好,因为 FBSDKLoginButton 完成了所有工作 - 您只需要更改文本。抱歉,我只知道 Swift ......这是代码:
var fbButton = FBSDKLoginButton()
var titleText = NSAttributedString(string: "Your new button title")
fbButton.setAttributedTitle(titleText, forState: UIControlState.Normal)
Enjoy!
享受!
回答by Amir Foghel
The answer to your all problems, including the label after log-in pressed is very simple:
It's like OZBA answer just remove completely the UILabel
(add: [loginLabel removeFromSuperview];
)
回答你的所有问题,包括登录后,在压制是非常简单的标签:这就像OZBA答案只是完全删除UILabel
(地址:[loginLabel removeFromSuperview];
)
This is the full working code:
这是完整的工作代码:
- (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];
}
}
}
回答by Mellaito
Please, read the README file in Facebook SDK. You have to add the Row - FacebookBundleName in info.plist and put it a name for your bundle. Then, add a bundle to your project with this name and put into folders named "lang.lproj": for example: en.lproj - it.lproj - fr.lproj - es.lproj.... Into this folders you have to add the Localizable.strings file, then you can localize a lot of phrases, like:
请阅读 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";
Hope it helps you!
希望对你有帮助!
回答by jmac
I just found an answer for the button text updating when pressing the login button. I suffered the same problem.
我刚刚找到了按下登录按钮时按钮文本更新的答案。我遇到了同样的问题。
How about try setting the frame of the button label to CGRectMake(0,0,0,0).
如何尝试将按钮标签的框架设置为 CGRectMake(0,0,0,0)。
I tried it and I think it worked.
我试过了,我认为它奏效了。
Add this code to ozba's answer:
将此代码添加到 ozba 的答案中:
[loginLabel setFrame:CGRectMake(0, 0, 0, 0)];
Hope this helps.
希望这可以帮助。