NSTextField doesn't show when I set AttributedString placeholder - objective-c

I'm trying to customize a little bit my NSTextFields and the first step is to customize the placeholder.
I want to change the placeholder color, and I'm trying it out by this way:
- (void)awakeFromNib {
// Color for placeholder in NSTextField - Color: #cdc9c1
NSColor *placeholderColor = [NSColor colorWithCalibratedRed:0.80f green:0.78f blue:0.75f alpha:1.0f];
NSDictionary *placeholderAttributeDict = [NSDictionary dictionaryWithObject:placeholderColor forKey:NSForegroundColorAttributeName];
NSAttributedString *emailPlaceholderString = [[NSAttributedString alloc] initWithString:#"Email" attributes:placeholderAttributeDict];
// NSAttributedString *passPlaceholderString = [[NSAttributedString alloc] initWithString:#"Password" attributes:placeholderAttributeDict];
// NSTextField Email attributes
[[self emailTextField] setDrawsBackground:NO];
[[self emailTextField] setBordered:NO];
[[[self emailTextField] cell] setPlaceholderAttributedString:emailPlaceholderString];
// NSTextField Password attributes
[[self passTextField] setDrawsBackground:NO];
[[self passTextField] setBordered:NO];
[[[self emailTextField] cell] setPlaceholderString:#"Password"];
}
As you may see, the first placeholder in the first NSTextField is established by an NSAttributedString where i try to specify color. The second placeholder in the second NSTextField is just a NSString.
When i run the application, it only shows the second NSTextField. First one doesn't appear anywhere.
What is happening?
Thanks in advanced.

You are setting the same emailTextField twice...
[[[self emailTextField] cell] setPlaceholderAttributedString:emailPlaceholderString];
[[[self emailTextField] cell] setPlaceholderString:#"Password"];
(Does that fix things or was it just an error in the question?)

Related

how to make NSTextField to fit NSMutableAttributedString contained

I have a NSTextField where I add NSMutableAttributedString. I want to set the size of that string to big number, however when I do that the text appears cut off. How can tell the NSTextField to get bigger?
This is what I have:
NSTextField* textField = [[NSTextField alloc] init];
NSMutableAttributedString* text = [[NSMutableAttributedString alloc]
initWithString:#"0"];
NSRange titleRange = NSMakeRange(0, [text length]);
[text addAttribute:NSFontAttributeName
value:[NSFont boldSystemFontOfSize:25]
range:titleRange];
[textField setAttributedStringValue:text];
Any advice?
Thanks in advance
Make a subclass of NSTextField
In implementation do override intrinsicContentSize
-(NSSize)intrinsicContentSize
{
if ( ![self.cell wraps] ) {
return [super intrinsicContentSize];
}
NSRect frame = [self frame];
CGFloat width = frame.size.width;
frame.size.height = CGFLOAT_MAX;
CGFloat height = [self.cell cellSizeForBounds: frame].height;
return NSMakeSize(width, height);
}
// Than invalidate the layout when text changes
- (void)textDidChange:(NSNotification *)notification
{
[super textDidChange:notification];
[self invalidateIntrinsicContentSize];
}
In attribute Inspector inside storyboard set NSTextField class to your customNSTextField class and change layout to wraps from scrolls.
You must add constraints to your textField to its superview, easier in storyboard.
After that you can also set font size directly :
[_textField setFont:[NSFont systemFontOfSize:25]];
[textField sizeToFit];
But using autolayout, is usually a better idea.

NSAlert not working with NSTextField

I have an NSAlert with a NSView accessory view that contains two NSTextField's. I can put the cursor in the NSTextField's but I cannot type in them. Instead, it will type in the last line I was typing on in Xcode. I am using Xcode 6.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSAlert *passRequest = [[NSAlert alloc] init];
[passRequest setMessageText:#"Finder wants to restart. Type your password to allow this."];
[passRequest addButtonWithTitle:#"OK"];
[passRequest addButtonWithTitle:#"Cancel"];
[passRequest setAccessoryView:[InputView inputViewWithUsername:#"James Pickering"]];
NSImage *lockImage = [[NSImage alloc] initWithContentsOfFile:#"LOCK_YOSEMITE.png"];
[passRequest setIcon:lockImage];
[passRequest runModal];
}
I did implement the LSUIElement key, but even before that it wasn't running properly. Otherwise, it's straight out of the box cocoa app.
Here is my code for InputView:
#import "InputView.h"
#interface InputView ()
#property (strong, nonatomic) NSString *username;
#end
#implementation InputView
+ (InputView *)inputViewWithUsername:(NSString *)username {
InputView *view = [[self alloc] initWithFrame:NSRectFromCGRect(CGRectMake(0, 0, 321, 52))];
[view setUsername:username];
return view;
}
- (void)drawRect:(NSRect)dirtyRect {
[super drawRect:dirtyRect];
NSTextField *usernameLabel = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(0, 32, 71, 17))];
[usernameLabel setStringValue:#"Username:"];
[[usernameLabel cell] setBordered:NO];
[[usernameLabel cell] setBezeled:NO];
[usernameLabel setEditable:NO];
[usernameLabel setSelectable:NO];
[usernameLabel setBackgroundColor:[NSColor clearColor]];
[usernameLabel setFont:[NSFont systemFontOfSize:13]];
[self addSubview:usernameLabel];
NSTextField *passwordLabel = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(2, 2, 69, 17))];
[passwordLabel setStringValue:#"Password:"];
[[passwordLabel cell] setBordered:NO];
[[passwordLabel cell] setBezeled:NO];
[passwordLabel setEditable:NO];
[passwordLabel setSelectable:NO];
[passwordLabel setBackgroundColor:[NSColor clearColor]];
[passwordLabel setFont:[NSFont systemFontOfSize:13]];
[self addSubview:passwordLabel];
NSTextField *usernameInput = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(77, 30, 206, 22))];
[usernameInput setStringValue:self.username];
[usernameInput setFont:[NSFont systemFontOfSize:13]];
[self addSubview:usernameInput];
NSTextField *passwordInput = [[NSTextField alloc] initWithFrame:NSRectFromCGRect(CGRectMake(77, 0, 206, 22))];
[passwordInput setFont:[NSFont systemFontOfSize:13]];
[self addSubview:passwordInput];
}
#end
I am calling this function in int main.
This is your problem. An alert needs a full application set up and running its event loop. In order for typing to go to it, it will need to be the active application.
You should probably create a normal app from Xcode's template. Start with that. Get things working there. You can present your alert in an action method that's connected to a menu item or a button in a window or whatever. (You could also present in the -applicationDidFinishLaunching: app delegate method, I suppose.)
After you've got that working, if there's some reason you need this to work in an unusual context (e.g. command-line tool), you can work on that.
You are modifying the view hierarchy inside of your -drawRect: method. You must not do this.
First, -drawRect: may be called many times over the life of the view and you would be adding subviews every time it draws. More and more subviews, over and over.
Second, even if you were careful to only add them the first time, -drawRect: is for drawing and not for changing the view hierarchy. (There's -viewWillDraw if you need to make such changes just before drawing, but I don't think that's appropriate for this case, either.)
You can add the subviews in an override of -initWithFrame: instead.
By the way, you should probably use NSMakeRect() instead of NSRectFromCGRect(CGRectMake(...)).

Accessory view in NSAlert doesn't render text with proper size

I'm trying to display an NSAlert with an accessory view so I can show a link in a block of text below the informative message. Here is my code.
#import "AppDelegate.h"
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSAlert *activateAlert = [NSAlert alertWithMessageText: #"Some message text"
defaultButton: #"OK"
alternateButton: nil
otherButton: nil
informativeTextWithFormat: #"Some informative text"];
NSTextView *accessory = [[NSTextView alloc] initWithFrame: NSMakeRect(0,0,300,15)];
NSFont *font = [NSFont systemFontOfSize:[NSFont smallSystemFontSize]];
NSDictionary *textAttributes = #{NSFontAttributeName: font};
[accessory insertText:[[NSAttributedString alloc] initWithString:#"Some text in an accessory view"
attributes: textAttributes]];
accessory.editable = NO;
accessory.drawsBackground = NO;
[accessory setAutomaticLinkDetectionEnabled: YES];
activateAlert.accessoryView = accessory;
[activateAlert beginSheetModalForWindow: self.window
modalDelegate: nil
didEndSelector: nil
contextInfo: nil];
}
#end
Apple documentation says "the informative text (which uses small system font)", so I'm using [NSFont smallSystemFontSize] but it doesn't render properly (see):
It's not aligned
It's not using a small font size (I've tried using other values, like 1.0) but it seems the font attribute is ignored.
Any hints? Should I create my own NSAlert component?
Thanks!
Have you tried creating an IBOutlet for the textView and using that as an accessory view for the NSAlert?

UILabel text not changing?

Unable to change text in lMenu_time (this is a UILabel) after it was initially set.
The call back is executed, I tested this, but the text won't change.
?? I am passing around the pointer and making adjustments to the UILabel. ??
lMenu_time and numerous others are defined in the header file. (not seen here)
UILabel *lMenu_time;
...
-(void) NewNumber: (UIButton*) btn {
if (btn.tag == 102){
iTime++;
[lbl setText:#"time"];
if(iTime > 20){iTime=1;}
[lMenu_time setText:[NSString stringWithFormat: #"Hold: %d", iTime]];
}
....
}
- (void) menuItem: (UIView*)vMenu menuButton:(UIButton*)bMenu menuLabel: (UILabel*)lMenu menuPosX: (double)posX menuLenX: (double)lenX menuTagNum: (int)tagNum menuText: (NSString*)txtMenu{
bMenu = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[bMenu setFrame:CGRectMake(posX,0,lenX,25)];
[bMenu setTag: tagNum];
[bMenu addTarget:self action:#selector(NewNumber:) forControlEvents:UIControlEventTouchUpInside];
[vMenu addSubview:bMenu];
lMenu = [[[UILabel alloc] initWithFrame:CGRectMake(posX,0,lenX,25)] retain];
[lMenu setBackgroundColor:[UIColor lightGrayColor]];
[lMenu setText:[NSString stringWithFormat: txtMenu]];
[lMenu setFont:[UIFont systemFontOfSize:14 ]];
[lMenu setTextAlignment:UITextAlignmentCenter];
[vMenu addSubview: lMenu];
}
- (void) menuBuild{
pSelf = self;
theString = #"";
UIView *vMenu = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,25)];
[pSelf.view addSubview:vMenu];
[vMenu setBackgroundColor:[UIColor grayColor]];
iTime = 2;
[self menuItem:vMenu menuButton:bMenu_time menuLabel:lMenu_time menuPosX:240+20 menuLenX:60 menuTagNum:102 menuText:[NSString stringWithFormat: #"Hold: %d", iTime]];
...
}
Just before you try to set the next, try adding
NSLog(#"My label is %#",lMenu_time);
Then, if your console outputs "My label is (nil)" you'll know that the problem is that the pointer to lMenu_time isn't being passed around properly.
Did you bind the label object to the controller in Interface builder? If not I would bet this is an retention issue. You do not post the code that builds the UILabel object, so if that is not done in IB, ensure you call retain or it will certainly be out of scope when you try and modify it.

NSTextField Color issues

I am dynamically adding a NSTextField to a window and I am having issues with rendering. I am setting the background color to be black and the text color to be white. These both work but their is what appears to be a rectangle that is part of the text that is always white. Does anyone know what I might be doing wrong? How can I get rid of the white background that is just around the text? Code is as follows:
//Create rectangle to size text field
NSRect textFieldRect = NSMakeRect(300, 300, 300, 54);
//Instantiate text field and set defaults
NSTextField* textField = [[NSTextField alloc] initWithFrame:textFieldRect];
[textField setFont:[NSFont fontWithName:#"Arial" size:48]];
[textField setTextColor:[NSColor whiteColor]];
[textField setStringValue:#"Some Text"];
[textField setBackgroundColor:[NSColor blackColor]];
[textField setDrawsBackground:YES];
[textField setBordered:NO];
[[window contentView] addSubview:textField];
I tried your code on Mac OS X 10.6.4.
Inside the application delegate:
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
NSRect textFieldRect = NSMakeRect(300, 300, 300, 54);
NSTextField* textField = [[NSTextField alloc] initWithFrame:textFieldRect];
[textField setFont:[NSFont fontWithName:#"Arial" size:48]];
[textField setTextColor:[NSColor whiteColor]];
[textField setStringValue:#"Some Text"];
[textField setBackgroundColor:[NSColor blackColor]];
[textField setDrawsBackground:YES];
[textField setBordered:NO];
[[window contentView] addSubview:textField];
}
And this is the result
alt text http://www.freeimagehosting.net/uploads/26c04b6b64.png
I can't see any white box.
Maybe you are using a different OS.
Or maybe you have some other views on top of each other that are causing the weird effect you are talking about.
Try setting refusesFirstResponder = TRUE property of your NSTextField object. I have come across behavior you described in 10.7, in 10.6 everything works as expected.
Ok,
The mystery is partially solved. In conjunction with my NSTextField, I am also setting some NSApplicationPresentationOptions to put the application into Kiosk mode. It appears that something with that is causing the problem I am seeing. If I do not set the PresentationOptions the NSTextField displays exactly the way I want it to. I will track down what specific PresentationOption is to blame and post here.