How to make NSTableView transparent? - macos

I want to make transparent NSTableView.
I am using WindowController class here.
I was trying this:
- (void)windowDidLoad
{
[super windowDidLoad];
[[self enclosingScrollView] setDrawsBackground: NO];
[[self enclosingScrollView] setBorderType:NSNoBorder];
}
- (BOOL)isOpaque {
return NO;
}
- (void)drawRect:(NSRect)drawRect
{
[super drawRect: drawRect];
}
But when i was writing this code i can't found enclosingScrollView in help window.
you can see here..
Any help?? Please remember me or correct me if i am doing something wrong.
Thank you.

If you have an NSScrollView enclosing your NSTableView, you can set the scroll view's drawsBackground property to NO like this:
yourScrollView.drawsBackground = NO;

Got Answer..!!! I just tried this
[tableview setBackgroundColor:[NSColor clearColor]];
[tableview setHeaderView:nil];
and its working fine.. – – Snehal
Copied from comment in question, as its a bit buried...

If your app needs to display a transparent table view, set the background color of the table view to be clear and set the enclosing scroll view to not draw its background. The following code snippet shows one way to display a transparent table:
Swift:
yourTableView.backgroundColor = NSColor.clear
yourTableView.enclosingScrollView?.drawsBackground = false
Objective-C
[theTableView setBackgroundColor:[NSColor clearColor];
[[theTableView enclosingScrollView] setDrawsBackground:NO];
Apple - Modifying a Table’s Visual Attributes

Related

My NSScrollView is not scrolling my NSTextView (document)

So I've been burned by this a few times. I'm trying to create an NSTextView that can be scrolled.
The only way I've gotten it to work is by having a Xib—but right now that stopped working after I added a Stack View in an adjacent Split View for God-knows-what-reason.
So what have I done?
I have code for code copied down the Apple Docs like for Text in Scroll View like so:
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/TextUILayer/Tasks/TextInScrollView.html
BOOL deviateFromAppleScrollDoc = NO;
_scrollView = [[NSScrollView alloc]
initWithFrame:[[self view] frame]];
// Apple Has
// [[theWindow contentView] frame]];
// but we are in a sub-View-Controller
NSSize contentSize = [_scrollView contentSize];
[_scrollView setBorderType:NSNoBorder];
[_scrollView setHasVerticalScroller:YES];
[_scrollView setHasHorizontalScroller:NO];
[_scrollView setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
_editorView = [[EditorView alloc]
initWithFrame:NSMakeRect(
0, 0,
contentSize.width, contentSize.height)];
[_editorView setMinSize:NSMakeSize(0.0, contentSize.height)];
[_editorView setMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)];
[_editorView setVerticallyResizable:YES];
[_editorView setHorizontallyResizable:NO];
if (deviateFromAppleScrollDoc)
{
[_editorView setAutoresizesSubviews:YES];
[_editorView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
}
else
{
[_editorView setAutoresizingMask:NSViewWidthSizable];
}
[[_editorView textContainer]
setContainerSize:NSMakeSize(contentSize.width, FLT_MAX)];
[[_editorView textContainer] setWidthTracksTextView:YES];
if (deviateFromAppleScrollDoc)
{
[[_editorView textContainer] setHeightTracksTextView:YES];
}
if (deviateFromAppleScrollDoc)
{
NSClipView *clipView = [[NSClipView alloc] init];
[clipView setDocumentView:_editorView];
[_scrollView setContentView:clipView];
}
else
{
[_scrollView setDocumentView:_editorView];
}
[[self view] addSubview:_scrollView];
What does that get me?
As you can tell, there is an NSTextView. It does not fill the Container as I would like it to.
There is also a Scroll View and I can tell it is active. You can pull down and get a rebound effect—but it does not scroll the document as I would like. This text is cut off mid-sentence and when I add to it, the View does not scroll with my typing—and even if I scroll I can't get to it.
The Scroll View is "stuck".
I can make it fill the entire window if I change the Autoresizing mask to inlcude NSViewHeightSizable like so:
[_editorView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
See here:
Unfortunatley, it still does not scroll and the "Scroll View" is still "Stuck".
I don't know what to change.
I have tried to add a "NSClipView" and set the Content View instead like so:
NSClipView *clipView = [[NSClipView alloc] init];
[clipView setDocumentView:_editorView];
[_scrollView setContentView:clipView];
This does not work either.
Moreover it does something funky to the width and some of the letters get cut off. Not acceptable. No solution yet.
What am I missing?
What do I need to try / set / do?
Thank you!
UPDATE:
The Scroll View does scroll the document when I activate the find menu in the NSTextView.
Still mystified.
See here:

How to change color of divider in NSSplitView?

Can we change the color of the divider?
Apple documentations says, that we can override -dividerColor in subclass of NSSplitView for this, but it doesn't works for me, or my understanding isn't correct. Also I've try create color layer over divider, e.g.:
colorLayer = [CALayer layer];
NSRect dividerFrame = NSMakeRect([[self.subviews objectAtIndex:0] frame].size.width, [[self.subviews objectAtIndex:0] frame].origin.y, [self dividerThickness], self.frame.size.height);
[colorLayer setBackgroundColor:[color coreGraphicsColorWithAlfa:1]];
[colorLayer setFrame:NSRectToCGRect(dividerFrame)];
[self.layer addSublayer:colorLayer];
Not works.
This answer may be late but:
If you are using Interface Builder, it is possible to change the property by going to the Identity Inspector of the NSSplitView (cmd+alt+3) and adding a User Defined Runtime Attribute for dividerColor of the type Color.
Actually, simply subclassing NSSplitView and overriding -(void)dividerColor works, but works only for thin or thick divider.
I've created simple configurable split view like this:
#interface CustomSplitView : NSSplitView
#property NSColor* DividerColor
#end
#implementation CustomSplitView
- (NSColor*)dividerColor {
return (self.DividerColor == nil) ? [super dividerColor] : self.DividerColor;
}
#end
Then in Interface Builder specify custom class for your split view to be CustomSplitView and add new user defined runtime attribute with key path = DividerColor, type = Color and select desired splitter color.
I've tried subclassing - (void)dividerColor too and I'm not sure why it doesn't work even though I know it's being called (and it's in the documentation).
One way to change the color of the divider is to subclass - (void)drawDividerInRect:(NSRect)aRect. However, for some reason, this method isn't called and I've checked all over the web for answers, but couldn't find anything, so I ended up calling it from drawRect. Here is the code for the subclassed NSSplitView:
-(void) drawRect {
id topView = [[self subviews] objectAtIndex:0];
NSRect topViewFrameRect = [topView frame];
[self drawDividerInRect:NSMakeRect(topViewFrameRect.origin.x, topViewFrameRect.size.height, topViewFrameRect.size.width, [self dividerThickness] )];
}
-(void) drawDividerInRect:(NSRect)aRect {
[[NSColor redColor] set];
NSRectFill(aRect);
}
Based on Palle's answer, but with the possibility to change the color dynamically in code, I'm currently using this solution (Swift 4):
splitView.setValue(NSColor.red, forKey: "dividerColor")
If your splitview control is part of a NSSplitViewController, you should use something like this:
splitViewController?.splitView.setValue(NSColor.red, forKey: "dividerColor")
In Swift and on macOS 11 I was able to achieve this by simply subclassing the NSSPlitView and only override drawDivider()
import Foundation
import AppKit
class MainSplitView: NSSplitView {
override func drawDivider(in rect: NSRect) {
NSColor(named: "separatorLinesColor")?.setFill()
rect.fill()
}
}
I had previously tried some of the other way, listed in here and what used to work stopped working with macOS 11... but it seems that this works.
One important point I haven't seen mentioned anywhere is that if you are overriding drawRect in a split view then you must call super -- otherwise drawDividerInRect: is never called. So, it should go something like this:
- (void)drawRect:(NSRect)dirtyRect {
// your other custom drawing
// call super last to draw the divider on top
[super drawRect:dirtyRect];
}
- (void)drawDividerInRect:(NSRect)aRect {
[[NSColor blueColor] set];
NSRectFill(aRect);
}

cocoa objective c pdfview not loaded

I am a newbie for MAC development, I have a simple Cocoa Application using NSViewController where I have a main view and 2 NSViewController and dynamically flipping them. I have added PDFView on NSViewController view to show pdf pages flipping at run time. but my problem when the views are added dynamically then on PDFView I can see the pdf page after resizing the window. I tried using [[pdfViewOutlet1 view] setNeedsDisplay:YES]; for both the views.
FirstView *FirstViewController = [[FirstView alloc] initWithNibName:kFirstView bundle:nil];
[FirstViewController setPdfDoc:pdfDoc];
[FirstViewController setPageCnt:pageCnt];
self.myCurrentViewController = FirstViewController;
[[_myCurrentViewController view] setNeedsDisplay:YES];
[transition setSubtype:kCATransitionFromLeft];
[[_myTargetView animator] addSubview: [_myCurrentViewController view]];
and in the awakeFromNib: method of first view I have:
if(pdfDoc==nil )
return;
[pdfViewOutlet1 setDisplayMode: kPDFDisplaySinglePageContinuous]; //kPDFDisplaySinglePage or kPDFDisplayTwoUp;
[pdfViewOutlet1 setDocument:pdfDoc];
NSRect myRect = { { 0,0 }, { 450, 200 } };
[pdfViewOutlet1 setFrame: myRect];
[pdfViewOutlet1 goToPage: [[pdfViewOutlet1 document] pageAtIndex: pageCnt]];
[pdfDoc release];
[[pdfViewOutlet1 view] setNeedsDisplay:YES];
How can I see the pdf pages without resizing the views using mouse?
the issue is solved, i was using setWantsLayer on my Parent view which was creating the issue.

How to create NSTextField programmatically?

I want to create NSTextField programmatically. I am new to Mac App Development.
Can anyone help me in this ?
Update :
I tried this code
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSView *myView = [[NSView alloc] init];
NSRect frameRect = NSMakeRect(20,20,100,140);
NSTextField *myTextField = [[NSTextField alloc] initWithFrame:frameRect];
[myView addSubview:myTextField];
}
This does nothing. Please correct me if i'm wrong anywhere.
Thank you.
Creating UI elements programmatically is very simple in Cocoa.
It involves two steps:
Create the view and set a frame to it.
Add it as a subview to any super view.
Following snippet will you help you understand better.
NSRect frameRect = NSMakeRect(20,20,40,40); // This will change based on the size you need
NSTextField *myTextField = [[NSTextField alloc] initWithFrame:frameRect];
[myView addSubview:myTextField];
It looks like you're creating an NSTextField OK, but you're not adding it to anywhere visible in the view hierarchy. Your app probably contains one or more NSWindow instances; if you want a view to appear in a particular window, you should add it as a subview of that window's content view.

Displaying NSProgressIndicatorSpinningStyle in NSStatusItem and then hiding it

I'm working on NSStatusItem. I've managed to use the setImage and setAlternateImage to work.
When user selects something, it takes a while for it to accomplish whatever it is doing. While it is doing something, I tried changing from the usual Image to a spinner. The way that I am doing it now is that I created a view, set the NSProgressIndicator to it, and then use
[statusItem setView: viewWithSpinner];
It seems to work until I try to remove it and display the original image. The only way I can hide it is to do
[statusItem setView: nil];
but that breaks everything, the original images don't come back. I guess cause there's no more view. I can't seem to save the original view before setting the viewWithSpinner.
Can someone advise me of a way of accomplishing this?
So...
NSStatusItem *myStatusItem;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[myStatusItem setImage:statusImage];
[myStatusItem setHighlightMode:YES];
[myStatusItem setAlternateImage:statusImageSel];
[myStatusItem setMenu:myStatusMenu];
etc...
[self createSpinner];
}
-(void)createSpinner
{
//to overcome the white border problem
NSView *progressIndicatorHolder = [[NSView alloc] init];
NSProgressIndicator *progressIndicator = [[NSProgressIndicator alloc] init];
[progressIndicator setBezeled: NO];
[progressIndicator setStyle: NSProgressIndicatorSpinningStyle];
[progressIndicator setControlSize: NSSmallControlSize];
[progressIndicator sizeToFit];
[progressIndicator setUsesThreadedAnimation:YES];
[progressIndicatorHolder addSubview:progressIndicator];
[progressIndicator startAnimation:self];
//for testing purposes
[[myStatusItem view] addSubview:progressIndicatorHolder];
spinnerView = progressIndicatorHolder;
}
I suggest save old view using [statusItem view] before setting to any other view. Before coming back to normal menu, set old saved view to statusItem using setView method.
If you're looking to just hide the NSStatusItem view, just call [yourStatusItem setLength:0].

Resources