I have an NSTableView, with an "add" button below it. When I click on the button, a new row gets added to the table and is ready for user input.
The row appears in a white color. Can I set the color of the row to a transparent color? Is this possible? I cannot figure out how to do this.
My code for setting my table to be transparent:
[myTable setBackgroundColor:[NSColor clearColor]];
[[myTable enclosingScrollView] setDrawsBackground: NO];
Code for adding a row:
[myTableArray addObject:#""];
[myTable reloadData];
[myTable editColumn:0 row:[myTableArray count]-1 withEvent:nil select:YES];
try setting the cell's background color transparent
[cell setBackgroundColor:[UIColor clearColor]];
it works for me
I think you may have to do some subclassing to accomplish what you're trying to do.
By subclassing your NSTableView you can override the preparedCellAtColumn:row: method like so:
- (NSCell*) preparedCellAtColumn:(NSInteger)column row:(NSInteger)row {
NSTextFieldCell *edit_field;
edit_field = (NSTextFieldCell*) [super preparedCellAtColumn:column row:row];
if ( [self editedRow] == row && [self editedColumn] == column ) {
[edit_field setBackgroundColor:[NSColor clearColor]];
[edit_field setDrawsBackground:NO];
}
return edit_field;
}
However, the NSTableView documentation indicates that your cell has another method called, which seems to reset the color. (editWithFrame:inView:editor:delegate:event:) Creating a subclass of NSTextViewCell that overrides this method may do what you're looking for.
EDIT
Searching through the documentation I found this:
If the receiver isn’t a text-type NSCell object, no editing is performed. Otherwise, the field editor (textObj) is sized to aRect and its superview is set to controlView, so it exactly covers the receiver.
So what you need to customize in this case is the field editor, which is covering up any display changes you're performing on the NSTableView or the cell.
The field editor is returned by the window delegate's method windowWillReturnFieldEditor:toObject:
This should let you set the properties of the edited cell before returning it to the NSTableView
EDIT
Tried this to no avail but might help out:
-(id) windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client{
NSText *editor = [window fieldEditor:YES forObject:client];
[editor setBackgroundColor:[NSColor clearColor]];
[editor setDrawsBackground:NO];
return [editor autorelease];
}
Related
I am specifically looking for an iOS-7 answer. If I had an image, the answer would be
[mySearchBar setSearchFieldBackgroundImage:myImage forState:UIControlStateNormal];
But I just want to apply a color. Is there a simple way of doing this with just a color? Again, for iOS-7.
Note: I see a host of very complicated answers here on SO: with traversing, etc. I hoping for something simple and that won't cause my app to be rejected.
If I understand correctly, you are looking for the barTintColor property. You can set the barTintColor property as such,
mySearchBar.barTintColor = [UIColor blackColor];
or
[mySearchBar setBarTintColor:[UIColor blackColor];
Hope that helps!
First you need to find the UITextField inside the search bar and then change its color. Here is the code to get the text field:
for (UIView *subView in searchBar.subviews)
{
for (UIView *secondLevelSubview in subView.subviews){
if ([secondLevelSubview isKindOfClass:[UITextField class]])
{
UITextField *searchBarTextField = (UITextField *)secondLevelSubview;
return searchBarTextField;
}
}
}
return nil;
There seems to be a bug in NSTextField. When the application launches it all draws correctly. But as soon as I click in the textField the view gets all messed up. To more specific, whenever I type drawRect: gets called but with a smaller rect causing all the problems.
When I select the text it draws correctly again. The only solution is to set the FocusRingType to visible (example: NSFocusRingTypeDefault). But I would like to have it without the ring. Is this possible?
Here is the code I am using:
-(id)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if(self)
{
// Add a label
NSTextField *textField = [[NSTextField alloc] initWithFrame:CGRectMake(0, 0, frameRect.size.width, frameRect.size.height)];
[[textField cell] setPlaceholderString:#"URL or search term..."];
[textField setTextColor:[NSColor greyColor]];
[textField setBackgroundColor:[NSColor clearColor]];
[textField setFont:[NSFont fontWithName:#"Open Sans" size:20]];
[textField setDrawsBackground:FALSE];
[textField setBordered:FALSE];
[textField setFocusRingType:NSFocusRingTypeNone];
[self addSubview:textField];
}
return self;
}
-(void)drawRect:(NSRect)dirtyRect
{
NSInteger borderWdith = 2;
// Create the path to the button
NSBezierPath *aPath = [NSBezierPath bezierPathWithRoundedRect:CGRectMake(borderWdith, borderWdith,
dirtyRect.size.width-(borderWdith*2),
dirtyRect.size.height-(borderWdith*2))
xRadius:3 yRadius:3];
// Fill the button with white
[[NSColor whiteColor] set];
[aPath fill];
}
Tricks like setting editable to TRUE/FALSE in drawRect did not work. Also setting to different focusRingTypes in the method failed.
Okay, so I managed to sort of fix this drawing problem. In the view init method I set a global CGRect variable which was set to the initial frame.
Each time -(void)drawRect:(CGRect)dirtyRect was called, I overwrote dirtyRect with the global variable.
Hope this helps anyone. I guess this isn't the best solution, but works :)
For each cell in the TableView I basically have a Boolean variable that stores if the data is being loaded for that cell. So tapping on a cell will cause the accessory type to change to a UIActivityIndicator. The TableView loads fine, but when I pop back to the TableView one or two of the cells randomly do not have the default DisclosureIndicator... it has nothing
The code I am using is inside cellForRowAtIndexPath
NSLog([entry isLoading] ? #"Yes" : #"No");
if ([entry isLoading]) {
UIActivityIndicatorView *activityView =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityView startAnimating];
[cell setAccessoryView:activityView];
}
else{
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
I have stepped through the code and the cells that do not show the DisclosureIndicator are still running the code that is setting it to a AccessoryDisclosureIndicator... I'm not sure what's going on since the cells missing the indicatory is triggering the else statement causing the setAccessoryType
Thanks!
Try this,
if ([entry isLoading]) {
UIActivityIndicatorView *activityView =
[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[activityView startAnimating];
[cell setAccessoryView:activityView];
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
else{
[cell setAccessoryView:nil];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
As per documentation,
accessoryView
If the value of this property is not nil, the UITableViewCell class
uses the given view for the accessory view in the table view’s normal
(default) state; it ignores the value of the accessoryType property.
The provided accessory view can be a framework-provided control or
label or a custom view. The accessory view appears in the right side
of the cell.
So you need to set accessoryView to nil show the accessoryType or else it will ignore it.
When I addSubview: nothing shows up. I set text and color to see it. Also if I manually add the view to the custom view in the UI bulder in xcode it shows up just fine with the text and color.
.m file
- (void)displayString:(NSString *)title {
NSRect frame = NSMakeRect(10, 10, 200, 17);
NSTextfield *newfield = [[NSTextField alloc] initWithFrame:frame];
[newfield setBezeled:NO];
[newfield setDrawsBackground:NO];
[newfield setEditable:NO];
[newfield setSelectable:NO];
[newfield setStringValue:title];
[newfield setTextColor:[NSColor blueColor]];
[test addSubview:newfield];
if([test.subviews containsObject:newfield]){
NSLog(#"view there"); // i get this message
}
if([newfield isHidden]){
NSLog(#"view hidden"); //i dont get this message
}
NSLog(#"view set");
}
test is a NSView (Custom view is what xcode calls it) that I have properly linked in.
So when I create the text field and add it to the NSView manually and then run that same code by adding text and color all works fine, this issue arrises when I try programmatically setting the view. Also I made sure it wasn't my creating of the view, as I have tried creating the view in the builder and not placing it in the NSView and then trying addSubview: but that also does not work. Let me know if you need more code.
DEVELOPMENT:
If the nsview (custom view) has an element already in it (manually added and can be anything) and I add the text field it works (I get both views in the nsview)? The subview is tested for and there, just cant see it.
You have to call initWithFrame: instead of just init
- (void)displayString:(NSString *)title {
NSRect frame = NSMakeRect(10, 10, 200, 200);
NSTextField *newfield = [[NSTextField alloc] initWithFrame:frame];
[newfield setStringValue:title];
[newfield setTextColor:[NSColor blueColor]];
[test addSubview:newfield];
NSLog(#"view set");
}
What type of view is test? Also you need to do a:
newfield.frame = CGRectMake(x,y,width,height)
in order to specify the look of the view
Turns out I set the view too early. I was under the impression that whatever you do to the view after its been set will be reflected on the view, but that seemed to be the issue. After altering the view to be exactly they way I want then set the view of the NSStatuditem.
so I get
[newfield setStringValue:title];
[newfield setTextColor:[NSColor blueColor]];
[test addSubview:newfield];
[statusItem setView:test];//this is the key, setting it after he changes.
In my app I change the position of the standardWindowButtons close / miniturize / expand like so:
//Create the buttons
NSButton *minitButton = [NSWindow standardWindowButton:NSWindowMiniaturizeButton forStyleMask:window.styleMask];
NSButton *closeButton = [NSWindow standardWindowButton:NSWindowCloseButton forStyleMask:window.styleMask];
NSButton *fullScreenButton = [NSWindow standardWindowButton:NSWindowZoomButton forStyleMask:window.styleMask];
//set their location
[closeButton setFrame:CGRectMake(7+70, window.frame.size.height - 22 - 52, closeButton.frame.size.width, closeButton.frame.size.height)];
[fullScreenButton setFrame:CGRectMake(47+70, window.frame.size.height - 22 -52, fullScreenButton.frame.size.width, fullScreenButton.frame.size.height)];
[minitButton setFrame:CGRectMake(27+70, window.frame.size.height - 22 - 52, minitButton.frame.size.width, minitButton.frame.size.height)];
//add them to the window
[window.contentView addSubview:closeButton];
[window.contentView addSubview:fullScreenButton];
[window.contentView addSubview:minitButton];
Now when the window appears with the buttons there is two problems:
1. They are grey and not their correct color
2. when the mouse is over them they do not show the + - or x sign
can anyone tell me what I am doing wrong. Thanks.
Here is the mechanics of this hover magic: Before drawing itself standard circled button (such as NSWindowMiniaturizeButton) calls their superview undocumented method _mouseInGroup:. If this method returns YES circled button draws itself with icon inside. That's all.
If you place these buttons inside your own view, you can simply implement this method and control this mouse-hover-appearance as you want. If you just move or relayout these buttons and they still be subviews of NSThemeFrame (or something similar), you have to swizzle method _mouseInGroup: for this class, and probably it doesn't worth it because we have perfectly simple previous method.
In my case I have custom NSView that contains my standard buttons as subviews and this code makes all described above magic:
- (void)updateTrackingAreas
{
NSTrackingArea *const trackingArea = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways | NSTrackingInVisibleRect) owner:self userInfo:nil];
[self addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)event
{
[super mouseEntered:event];
self.mouseInside = YES;
[self setNeedsDisplayForStandardWindowButtons];
}
- (void)mouseExited:(NSEvent *)event
{
[super mouseExited:event];
self.mouseInside = NO;
[self setNeedsDisplayForStandardWindowButtons];
}
- (BOOL)_mouseInGroup:(NSButton *)button
{
return self.mouseInside;
}
- (void)setNeedsDisplayForStandardWindowButtons
{
[self.closeButtonView setNeedsDisplay];
[self.miniaturizeButtonView setNeedsDisplay];
[self.zoomButtonView setNeedsDisplay];
}
I'm fully aware that this question is old and Valentin Shergin's answer is correct. It prevents the utilize of any Private API, unlike Google did in Chrome. Just wanted to share a method for those who don't feel like subclass NSView just to put those buttons in an existed view (such as self.window.contentView).
As I just wanted to reposition the NSWindowButtons via setFrame:, I found out that once the window was resized, the tracking areas seems to "fix" themselves automagically, without any Private API usage (at least in 10.11).
Thus, you can do things like the following to apply "fake resize" to the window that you repositioned your buttons:
NSRect frame = [self.window frame];
frame.size = NSMakeSize(frame.size.width, frame.size.height+1.f);
[self.window setFrame:frame display:NO animate:NO];
frame.size = NSMakeSize(frame.size.width, frame.size.height-1.f);
[self.window setFrame:frame display:NO animate:YES];
(I did it within my main window's NSWindowDelegate windowDidBecomeMain:. Should work as long as the window is loaded and visible.)
You're not adding them again. You're moving them to contentView. The buttons are originally in window.contentView.superview.
[window.contentView.superview addSubview:closeButton];
[window.contentView.superview addSubview:fullScreenButton];
[window.contentView.superview addSubview:minitButton];
Should get you the correct behaviour without requiring a trackingArea.
Call [button highlight:yes] for each button.