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.
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)
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:
_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