Reputation: 3545
I need to place an image view next to the title label (on the right side), so I've created a category with following method:
- (void)updateInsetsToMoveImageRightToText:(NSString *)text {
CGFloat textWidth = [text sizeWithAttributes:[self.titleLabel.attributedText attributesAtIndex:0 effectiveRange:NULL]].width;
CGFloat newXPosition = (self.frame.size.width - (self.frame.size.width - textWidth) / 2);
self.imageEdgeInsets = UIEdgeInsetsMake(0., newXPosition, 0., 0.);
self.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., self.imageView.image.size.width);
}
I'm using it like this:
- (void)quizzesFilterView:(QuizzesFilterView *)filterView didSelectFilter:(QuizFilterType)type {
self.filterType = type;
NSString *newTitle = [QuizzesFilterView filterNameByType:type];
[self.filterButton setTitle:newTitle forState:UIControlStateNormal];
[self.filterButton updateInsetsToMoveImageRightToText:newTitle];
[self removeFilterView];
[self updateSearchedQuizzesWithSearchText:nil quizFilterType:type];
[self updateTableUi];
}
But it doesn't work for smaller titles:
What am I doing wrong?
Upvotes: 2
Views: 817
Reputation: 13300
I know this might be an old question and tagged with Objective-C, but for those guys (like me) who search on Google without specifying the language of the iOS, here's the Swift 3.0 version.
func setupButton(button: UIButton) {
if let title: NSString = button.currentTitle as NSString?,
let attribute = button.titleLabel?.attributedText?.attributes(at: 0, effectiveRange: nil) {
let textWidth = title.size(attributes: attribute).width
// place here the remaining configurations
}
}
Upvotes: 0
Reputation: 526
I have written a custom UIButton that supports flexible alignment in just few lines of code.
It's available here : https://github.com/namanhams/FlexibleAlignButton
Example :
self.btn.alignment = kButtonAlignmentLabelLeft
self.btn.gap = 5; // horizontal gap between image and text
Upvotes: 1
Reputation: 104092
The following code worked for me. I put some code in didMoveToSuperview to get the layout correct when the view first appears (I didn't make any changes to the button in the storyboard, other than to set the title and the image).
@implementation RDButton
-(void)didMoveToSuperview {
CGFloat textWidth = [self.currentTitle sizeWithAttributes:[self.titleLabel.attributedText attributesAtIndex:0 effectiveRange:NULL]].width;
self.titleEdgeInsets = UIEdgeInsetsMake(0, - (self.imageView.frame.size.width + textWidth), 0, 0);
self.imageEdgeInsets = UIEdgeInsetsMake(0, textWidth, 0, 0);
self.contentEdgeInsets = UIEdgeInsetsMake(0, 5, 0, 0);
}
- (void)updateInsetsToMoveImageRightToText:(NSString *)text {
CGFloat textWidth = [text sizeWithAttributes:[self.titleLabel.attributedText attributesAtIndex:0 effectiveRange:NULL]].width;
self.imageEdgeInsets = UIEdgeInsetsMake(0, textWidth, 0, 0);
}
After Edit:
Another way that doesn't require any adjustment when you change the title, is to flip the button's layer 180 degrees around the y axis, and do the same to the title label's layer to flip it back to reading correctly. This can be done in the button's code, or you can do it in viewDidLoad
of the controller with no need to subclass the button.
- (void)viewDidLoad {
[super viewDidLoad];
self.filterButton.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
self.filterButton.titleLabel.layer.transform = CATransform3DMakeRotation(M_PI, 0, 1, 0);
}
Upvotes: 1
Reputation: 6899
Seems your calculation may be wrong, give this a try.
- (void)updateInsetsToMoveImageRightToText:(NSString *)text {
CGFloat textWidth = [text sizeWithAttributes:[self.titleLabel.attributedText attributesAtIndex:0 effectiveRange:NULL]].width;
CGFloat newXPosition = (self.frame.size.width / 2) + (width / 2); //left offset
self.imageEdgeInsets = UIEdgeInsetsMake(0.0, newXPosition, 0.0, 0.0);
self.titleEdgeInsets = UIEdgeInsetsMake(0., 0., 0., self.imageView.image.size.width);
}
If that doesn't solve the problem, you can add the image as a subview of the button and position it easier according to the width of the text.
Add an image inside UIButton as an accesory
Upvotes: 1