Trying to set `setNextKeyView` on `NSTextField`s in code - objective-c

I am having difficulties with setting a tab-order for my NSTextFields.
In my AppDelegate I add a NSViewController
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
CustomViewController *vc = [[CustomViewController alloc] init];
[_window.contentView addSubview:vc.view];
[_window setAutorecalculatesKeyViewLoop:NO];
[_window.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[view]|" options:0 metrics:nil views:#{#"view":vc.view}]];
[_window.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:#{#"view":vc.view}]];
}
Then in my NSViewController I add custom NSViews which contain a label and a text field.
- (void)viewDidLoad {
_customView = [[CustomView alloc] initWithLabel:#"Foo"];
[self.view addSubview_customView];
_customView1 = [[CustomView alloc] initWithLabel:#"Bar"];
[self.view addSubview_customView1];
_customView2 = [[CustomView alloc] initWithLabel:#"FooBar"];
[self.view addSubview_customView2];
}
And finally I have the CustomView which implements the label and text field as follows:
- (void)initWithLabel:(NSString *)label {
self = [super initWithFrame:NSZeroRect];
if (self) {
_label = [[NSTextField alloc] initWithFrame:NSZeroRect];
_label.stringValue = label;
_label.font = [NSFont fontWithName:#"HelveticaNeue-Light" size:12.0f];
_label.alignment = NSLeftTextAlignment;
_label.textColor = [NSColor grayColor];
_label.selectable = NO;
_label.editable = NO;
_label.drawsBackground = NO;
_label.bezeled = NO;
[self addSubview:_label];
_textField = [[NSTextField alloc] initWithFrame:NSZeroRect];
_textField.stringValue = #"";
_textField.alignment = NSRightTextAlignment;
_textField.font = [NSFont fontWithName:#"HelveticaNeue-Light" size:32.0f];
[self addSubview:_textField];
}
return self;
}
I do the positioning with NSLayoutConstraints and everything looks fine and works as expected, except when I try to implement setNextKeyView:.
I have tried to do it by using the exposed textField in the viewDidLoad of the view controller like:
...
[_customView.textField setNextKeyView:_customView1.textField];
[_customView1.textField setNextKeyView:_customView3.textField];
[_customView2.textField setNextKeyView:_customView.textField];
...
But that did not work. When pressing tab-key from a NSTextField the current field loses focus, but the next one does not gain it.
I also tried calling [[[self view] window] recalculateKeyViewLoop] afterwards but that didn't help either.
How do I go about doing this?
I also played around with setting NSWindow setAutorecalculatesKeyViewLoop: to YES but that also did not haven an effect.
Thanks
PS: this is pseudo-code to simplify things. If a brace is missing or there is a typo, then that is not my problem. It compiles fine and works too. Just the tabbing is not behaving as expected. ;-)

As #Ken mentioned in his comment try like this:-
if ([_customView1.textField acceptsFirstResponder])
{
[_customView1.window makeFirstResponder:_customView1.textField]
}

Related

Adding UISearchBar in UINavigationBar with constraints

All,
I want to add UISearchBar to UINavigationbar, I dont dont want to use UISearchController, Just UISearchbar programmatically and it must work in landscape as well.
I tried it is working well in Portrait well, but in Landscape, i have issues in iPhone X width. Can we use Constraints.
Below is the code
CGFloat width = [UIScreen mainScreen].bounds.size.width;
search = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, width - 2 * 44 - 2 * 15, 44)];
search.delegate = self; // search.tintColor = [UIColor redColor];
search.searchBarStyle = UISearchBarStyleMinimal;
search.placeholder = #"Search";
search.translucent = NO;
search.opaque = NO;
search.showsCancelButton = NO;
[search setBackgroundImage:[[UIImage alloc] init]];
//customize textfield inside UISearchBar
#try {
for (id object in [[[search subviews] firstObject] subviews])
{
if (object && [object isKindOfClass:[UITextField class]])
{
UITextField *textFieldObject = (UITextField *)object;
textFieldObject.backgroundColor = [UIColor whiteColor];
textFieldObject.borderStyle = UITextBorderStyleRoundedRect;
textFieldObject.layer.borderColor = (__bridge CGColorRef _Nullable)([brandingObj getValueForKey:navBarTitleColor]);
textFieldObject.layer.borderWidth = 1.0;
break;
}
}
}
#catch (NSException *exception) {
NSLog(#"Error while customizing UISearchBar");
}
#finally {
}
I don't understand why you want to use UISearchDisplayController, its highly configurable and recommended by apple, working with geometry (CGRecr, CGFrame, etc.) to adjust UIKit objects layout could be a pain, use auto layout avoiding UIKits convenience initializers, to adjust later constraints.
Anyway if you want explicitly do with this way, this should work.
#import "ViewController.h"
#interface ViewController ()<UISearchBarDelegate>
#property UISearchBar *searchbar;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
_searchbar = [UISearchBar new];
_searchbar.delegate = self;
_searchbar.searchBarStyle = UISearchBarStyleMinimal;
self.navigationItem.titleView = self.searchbar;
// Do any additional setup after loading the view, typically from a nib.
}
Maybe you should need configure appearance , take a look here
Cheers.

UITableView header disappears under the UINavigationBar using a standard UITableViewController

I have an UITableViewController inside an UINavigationController. I added a UISearchBar as the tableView.header:
UISearchBar *searchBar = [UISearchBar alloc] initWithFrame: CGRectMake(0,0,self.tableView.frame.size.width,44.0)];
self.tableView.tableHeaderView = searchBar;
The problem: When scrolling the tableHeader disappears under the navigationBar.
I already tried to set the navigationController.navigationBar.translucent = NO but it seems this trick doesn't work using a standard UITableViewController.
Is there a way to fix this problem using a standard UITableViewController? I want it to works exactly as it does in Contacts app. I target iOS7.
I gave up using the UITableViewController and I solved using a standard UIViewController with a UISearchBar on top and a UITableView under it. By setting self.edgesForExtendedLayout = UIRectEdgeNone the UISearchBar won't overlap the status bar when the search begins:
-(id) initWithTableViewStyle: (int) tableViewStyle
{
self = [super init];
if (self) {
//Set the UITableViewStyle
self.tableViewStyle = tableViewStyle;
//Be sure the searchBar won't overlap the status bar
self.edgesForExtendedLayout = UIRectEdgeNone;
//Add the subviews to the mainView
[self.view addSubview:self.searchBar];
[self.view addSubview:self.tableView];
//Autolayout
//Create the views dictionary
NSDictionary *viewsDictionary = #{#"searchBar":self.searchBar,
#"tableView": self.tableView};
//Create the constraints using the visual language format
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[searchBar]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat: #"H:|[tableView]|"
options:0
metrics:nil
views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint
constraintsWithVisualFormat:#"V:|[searchBar(==44)][tableView]|"
options:0
metrics:nil
views:viewsDictionary]];
}
return self;
}
-(UITableView*) tableView
{
if (!_tableView){
_tableView = [[UITableView alloc] initWithFrame:CGRectMake(0,0,0,0)
style:self.tableViewStyle];
_tableView.translatesAutoresizingMaskIntoConstraints=NO;
_tableView.delegate = self;
_tableView.dataSource=self;
}
return _tableView;
}
-(UISearchBar*) searchBar
{
if(!_searchBar){
_searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,0,0)];
_searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
_searchBar.translatesAutoresizingMaskIntoConstraints=NO;
_searchBar.translucent = NO;
_searchBar.delegate = self;
}
return _searchBar;
}
The UIViewController should be made:
UIViewController <NSFetchedResultsControllerDelegate,
UISearchBarDelegate,
UISearchDisplayDelegate,
UITableViewDataSource,
UITableViewDelegate>

replace layout manager of uitextview

NSTextContainer on Mac OS X has a method replaceLayoutManager: to replace the NSLayoutManager of NSTextView with a subclass of NSLayoutManager.
Unfortunately iOS doesn't have such a function.
I tried a combination of these lines of code, but it keeps crashing.
THLayoutManager *layoutManager = [[THLayoutManager alloc] init];
[layoutManager addTextContainer:[self textContainer]];
// [[self textStorage] removeLayoutManager:[self layoutManager]];
//[[self textStorage] addLayoutManager:layoutManager];
[[self textContainer] setLayoutManager:layoutManager];
What is the correct procedure to replace the NSLayoutManager of an UITextview?
Since iOS9, NSTextContainer has the same method as macOS. So now you can replace the layout manager on your storyboard UITextView with your own subclass:
textView.textContainer.replaceLayoutManager(MyLayoutManager())
Have a look at the WWDC2013 Intro To Text Kit video and sample code where they show how to do it.
https://developer.apple.com/downloads/index.action?name=WWDC%202013
https://developer.apple.com/wwdc/videos/
Below is an extract from the code
-(void)viewDidLoad
{
[super viewDidLoad];
// our auto layout views use a design spec that calls for
// 8 pts on each side except the bottom
// since we scroll at the top here, only inset the sides
CGRect newTextViewRect = CGRectInset(self.view.bounds, 8., 0.);
self.textStorage = [[TKDInteractiveTextColoringTextStorage alloc] init];
NSLayoutManager *layoutManager = [[NSLayoutManager alloc] init];
NSTextContainer *container = [[NSTextContainer alloc] initWithSize:CGSizeMake(newTextViewRect.size.width, CGFLOAT_MAX)];
container.widthTracksTextView = YES;
[layoutManager addTextContainer:container];
[_textStorage addLayoutManager:layoutManager];
UITextView *newTextView = [[UITextView alloc] initWithFrame:newTextViewRect textContainer:container];
newTextView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
newTextView.scrollEnabled = YES;
newTextView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
[self.view addSubview:newTextView];
self.textView = newTextView;
self.textStorage.tokens = #{ #"Alice" : #{ NSForegroundColorAttributeName : [UIColor redColor] },
#"Rabbit" : #{ NSForegroundColorAttributeName : [UIColor orangeColor] },
TKDDefaultTokenName : #{ NSForegroundColorAttributeName : [UIColor blackColor] } };
}

UIRefreshControl incorrect title offset during first run and sometimes title missing

The text is offset wrong by the first launch of UIRefreshControl... later sometimes the refresh text doesn't show up at all and just the spiny is visible
I don't think i had this issue with iOS6... might be related to iOS7
Is in a UITableViewController added as a child to a VC, which resides in a modal presented UINavigationController
- (void)viewDidLoad {
[super viewDidLoad];
[self setRefreshControlText:#"Getting registration data"];
[self.refreshControl beginRefreshing];
}
- (void)setRefreshControlText:(NSString *)text {
UIFont * font = [UIFont fontWithName:#"Helvetica-Light" size:10.0];
NSDictionary *attributes = #{NSFontAttributeName:font, NSForegroundColorAttributeName : [UIColor blackColor]};
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attributes];
}
This is definitely an iOS 7 bug, but I haven't figured out exactly what caused it. It appears to have something to do with the view hierarchy — adding my UITableViewController as a child view to a wrapper view controller appeared to fix it for me at first, although the bug is back since iOS 7 GM.
It looks like adding the following code to your UITableViewController after creating the refresh view fixes the positioning issue for good:
dispatch_async(dispatch_get_main_queue(), ^{
[self.refreshControl beginRefreshing];
[self.refreshControl endRefreshing];
});
calling endRefreshing under viewWillAppear did it for me:
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.refreshControl endRefreshing];
}
Under iOS7 with a custom UITableViewController inside a UINavigationController
I had the same problem and for me it worked with layoutIfNeeded after setting the attributedTitle:
- (void)setRefreshControlText:(NSString *)text
{
UIColor *fg = [UIColor colorWithWhite:0.4 alpha:1.0];
NSDictionary *attrsDictionary = #{NSForegroundColorAttributeName: fg};
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attrsDictionary];
[self.refreshControl layoutIfNeeded];
}
Cédric suggested to use [self.refreshControl setNeedsLayout], but this does not force an immediate update of the view, so you must use layoutIfNeeded.
I finally found the holy grail on this, which looks working in all cases
note : UIRefreshControl is added to a UITableViewController (note, never add UIRefreshControl just as subview to a normal UIVIewController's UITableView) (best to add UITableViewController as a child VC inside a UIViewController if you must)
note : that this also fixes the problem, that the UIRefreshControl is not vissible at first refresh (link)
Add to you .h
#interface MyViewController ()
#property (nonatomic, assign) BOOL refreshControlFixApplied;
- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;
#end
Add to you .m
////////////////////////////////////////////////////////////////////////
#pragma mark - UIRefreshControl Fix (peter#min60.com) https://stackoverflow.com/questions/19121276/uirefreshcontrol-incorrect-title-offset-during-first-run-and-sometimes-title-mis/
////////////////////////////////////////////////////////////////////////
- (void)beginRefreshingWithText:(NSString *)text {
[self setRefreshControlText:text];
[self beginRefreshing];
}
- (void)endRefreshingWithText:(NSString *)text {
[self setRefreshControlText:text];
[self.refreshControl endRefreshing];
}
- (void)beginRefreshing {
if (self.refreshControl == nil) {
return;
}
if (!self.refreshControlFixApplied) {
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.refreshControl.attributedTitle length] == 0) {
[self setRefreshControlText:#" "];
}
[self.refreshControl beginRefreshing];
dispatch_async(dispatch_get_main_queue(), ^{
[self.refreshControl endRefreshing];
dispatch_async(dispatch_get_main_queue(), ^{
// set the title before calling beginRefreshing
if ([self.refreshControl.attributedTitle length] == 0) {
[self setRefreshControlText:#" "];
}
if (self.tableView.contentOffset.y == 0) {
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
}
[self.refreshControl beginRefreshing];
self.refreshControlFixApplied = YES;
});
});
});
} else {
if (self.tableView.contentOffset.y == 0) {
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
}
[self.refreshControl beginRefreshing];
}
}
- (void)endRefreshing {
if (self.refreshControl == nil) {
return;
}
if (!self.refreshControlFixApplied) {
dispatch_async(dispatch_get_main_queue(), ^{
[self endRefreshing];
});
} else {
if (self.tableView.contentOffset.y < 0) {
self.tableView.contentOffset = CGPointMake(0, 0);
}
[self.refreshControl endRefreshing];
}
}
- (void)setRefreshControlText:(NSString *)text {
UIFont * font = [UIFont fontWithName:#"Helvetica-Light" size:10.0];
NSDictionary *attributes = #{NSFontAttributeName : font, NSForegroundColorAttributeName : [UIColor colorWithHex:0x00B92E]};
self.refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:text attributes:attributes];
}
Use only methods
- (void)beginRefreshing;
- (void)beginRefreshingWithText:(NSString *)text;
- (void)endRefreshing;
- (void)endRefreshingWithText:(NSString *)text;
UIRefreshControl seems to still be broken on IOS9.3 when you change the attributedTitle while the tableView is pulled down. What seems to work is to subclass UIRefreshControl and force update its layout once the (attributed) title is changed.
The core fix is to trigger a change to the tableView contentOffset (causing some hidden magic in the _update method which layouts the spinner and text subviews) and additionally forcing the frame height to its expected value ensuring the background color fills up the pulled down region.
#implementation MEIRefreshControl
{
__weak UITableView* _tableView;
}
- (instancetype)initWithTableView:(UITableView*)tableView
{
self = [super initWithFrame:CGRectZero];
if (self)
{
_tableView = tableView;
}
return self;
}
#synthesize title = _title;
- (void)setTitle:(NSString *)title
{
if (!PWEqualObjects(_title, title))
{
_title = title;
self.attributedTitle = [[NSAttributedString alloc] initWithString:_title ? _title : #""];
[self forceUpdateLayout];
}
}
- (void)forceUpdateLayout
{
CGPoint contentOffset = _tableView.contentOffset;
_tableView.contentOffset = CGPointZero;
_tableView.contentOffset = contentOffset;
CGRect frame = self.frame;
frame.size.height = -contentOffset.y;
self.frame = frame;
}
#end
This is the code that seems to fix all the issues. Many of the others that involved beginning or ending refreshing where interfering with other parts of the control.
//This chunk of code is needed to fix an iOS 7 bug with UIRefreshControls
static BOOL refreshLoadedOnce = NO;
if (!refreshLoadedOnce) {
__weak typeof(self) weakself = self;
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self.tableView.contentOffset = CGPointMake(0, -weakself.refreshControl.frame.size.height);
} completion:^(BOOL finished) {
weakself.refreshControl.attributedTitle = self.refreshControl.attributedTitle;
[weakself.refreshControl setNeedsUpdateConstraints];
[weakself.refreshControl setNeedsLayout];
refreshLoadedOnce = YES;
}];
}
//End of bug fix
I had the same problem, I did solve it by setting attributed text with space string to refresh control directly after init refresh control
_refreshControl = [[UIRefreshControl alloc]init];
[_refreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:#" "]];
After that, setting new attributed text to refresh control was without any problems.
[[self refreshControl] setAttributedTitle:[[NSAttributedString alloc]initWithString:[NSString stringWithFormat:#"Последнее обновление: %#", [dateFormat stringFromDate:[_post dateUpdated]]]]];
UPDATE
I noticed that problem come back when I use attrsDictionary:
this code works fine
NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string];
[[self refreshControl] setAttributedTitle: attributedString];
and this make refreshControl's title appear directly after view loaded
NSAttributedString* attributedString = [[NSAttributedString alloc]initWithString:string attributes:attrsDictionary];
[[self refreshControl] setAttributedTitle: attributedString];
I didn't find solution yet.
UPDATE
Finally found solution, after refreshcontrol init set attributed string also with attributes:attrsDictionary
NSDictionary *attrsDictionary = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:[UIColor appDarkGray], [UIFont fontWithName:#"OpenSans-CondensedLight" size:14.0f], nil] forKeys:
[NSArray arrayWithObjects:NSForegroundColorAttributeName, NSFontAttributeName, nil]];
[_refreshControl setAttributedTitle:[[NSAttributedString alloc]initWithString:#" " attributes:attrsDictionary]];
so after that there is no problem to set new refreshcontrol's title.
The solution for me was to set a text in viewDidAppear, no need to call
beginRefreshing or endRefreshing on the mainQueue
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"d MMM, HH:mm"];
NSString *lastUpdated = [NSString stringWithFormat:NSLocalizedString(#"refresh_last_updated", nil),[formatter stringFromDate:[NSDate dateWithTimeIntervalSince1970:[[[DatabaseController sharedInstance] getCurrentSettings].lastTimeStamp doubleValue]]]];
UIFont *font = [UIFont fontWithName:FONT_LATO_LIGHT size:12.0f];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:lastUpdated attributes:#{NSFontAttributeName:font}];
_refreshControl.attributedTitle = attrString;
}

UITabbarItem BadgeValue Text Color

I have a problem in my App. I set a badge value at one of the tabs in the UITabBar. The Badge value is correctly red and the circle around the badge value is correctly in white. The problem is, that the color of the text is gray (160, 160, 160). It is the same color like the normal state tabbaritem text is, but I set this color nowhere in the app code and I do not know where this color come from.
I searched for that issue in the whole net since weeks but I cannot find any solution. The only answer I found everywhere is, that it is not possible to change the color of the text of the badge value. But if it is not possible, why is it changed in my app?
I hope, that somebody can help me with that issue...
http://www.luventas-webdesign.de/stackoverflow/screenshot_badgevalue.png
Like the color is in my app
http://www.luventas-webdesign.de/stackoverflow/screenshot_like_it_should.png
Like the color should normally be...
Edit 02.11.2012 - Code
Creation of TabBarController:
#import "ExtendedTabBarController.h"
#import "configuration.h"
#implementation ExtendedTabBarController
- (void)viewDidLoad {
[super viewDidLoad];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:207.0/255.0 green:70.0/255.0 blue:61.0/255.0 alpha:1], UITextAttributeTextColor, [UIFont fontWithName:#"KievitPro-Regular" size:10.0], UITextAttributeFont, nil] forState:UIControlStateSelected];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1], UITextAttributeTextColor, [UIFont fontWithName:#"KievitPro-Regular" size:10.0], UITextAttributeFont, nil] forState:UIControlStateNormal];
[self.tabBar sizeToFit];
UIView *tabbarBackgroundColorView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0, self.view.bounds.size.width, 49)];
[tabbarBackgroundColorView setBackgroundColor:[UIColor colorWithRed:233.0/255.0 green:233.0/255.0 blue:233.0/255.0 alpha:1]];
[self.tabBar insertSubview:tabbarBackgroundColorView atIndex:0];
}
- (void)viewDidUnload {
[super viewDidUnload];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return UIInterfaceOrientationIsPortrait(interfaceOrientation); // only portrait orientation
}
/**
* orientation for iOS6
**/
-(NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait;
}
#end
Call in AppDelegate:
ExtendedTabBarController *tabBarController = [[ExtendedTabBarController alloc] init];
[self setTabBarController:tabBarController];
[[UITabBar appearance] setBackgroundImage:[UIImage imageNamed:#"menu_bg"]];
// code for initialize View- and NavigationControllers...
self.tabBarController.viewControllers = #[highlightsNavigationController, categoryNavigationController, searchNavigationController, favoritesNavigationController, imprintNavigationController];
self.window.rootViewController = self.tabBarController;
[[UITabBar appearance] setSelectionIndicatorImage:[[UIImage alloc] init]];
Set the badge value:
int viewCount = 0;
NSUserDefaults * defs = [NSUserDefaults standardUserDefaults];
NSDictionary * dict = [defs dictionaryRepresentation];
for (id key in dict) {
if([key rangeOfString:#"_highlighted"].location != NSNotFound && [[[dict objectForKey:key] objectAtIndex:0] isEqualToString:#"YES"]) {
viewCount++;
}
}
UITabBarItem *tbi = (UITabBarItem *)[self.tabBarController.tabBar.items objectAtIndex:3];
if(viewCount <= 0) {
tbi.badgeValue = nil;
} else {
tbi.badgeValue = nil;
tbi.badgeValue = [NSString stringWithFormat:#"%d", viewCount];
}
Code for overwritten UILabel:
// -- file: UILabel+VerticalAlign.h
#pragma mark VerticalAlign
#interface UILabel (VerticalAlign)
- (void)alignTop;
- (void)alignBottom;
- (void)awakeFromNib;
-(id)initWithFrame:(CGRect)frame;
#end
#import "UILabel+VerticalAlign.h"
// -- file: UILabel+VerticalAlign.m
#implementation UILabel (VerticalAlign)
- (void)alignTop {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i<newLinesToPad; i++)
self.text = [self.text stringByAppendingString:#"\n "];
}
- (void)alignBottom {
CGSize fontSize = [self.text sizeWithFont:self.font];
double finalHeight = fontSize.height * self.numberOfLines;
double finalWidth = self.frame.size.width; //expected width of label
CGSize theStringSize = [self.text sizeWithFont:self.font constrainedToSize:CGSizeMake(finalWidth, finalHeight) lineBreakMode:self.lineBreakMode];
int newLinesToPad = (finalHeight - theStringSize.height) / fontSize.height;
for(int i=0; i<newLinesToPad; i++)
self.text = [NSString stringWithFormat:#" \n%#",self.text];
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setFont:[UIFont fontWithName:#"KievitPro-Regular" size:12.0]];
}
-(id)initWithFrame:(CGRect)frame
{
id result = [super initWithFrame:frame];
if (result) {
[self setFont:[UIFont fontWithName:#"KievitPro-Regular" size:12.0]];
}
return result;
}
#end
I found a solution for my problem on my own:
I must remove the following lines from the overwritten UILabel:
- (void)awakeFromNib
{
[super awakeFromNib];
[self setFont:[UIFont fontWithName:#"KievitPro-Regular" size:12.0]];
}
-(id)initWithFrame:(CGRect)frame
{
id result = [super initWithFrame:frame];
if (result) {
[self setFont:[UIFont fontWithName:#"KievitPro-Regular" size:12.0]];
}
return result;
}
Maybe someone can explain me, why this lines change the text color of the badge value, before we can close this post?
Instead of setting the default UILabel font using a category, use the UILabel's appearance method to set the font:
[[UILabel appearance] setFont:[UIFont fontWithName:#"KievitPro-Regular" size:12.0]];
When I tested this the text for the badge appeared as the normal white color.