NSTextView fails when used as contentView - objective-c

I am programmatically creating a NSTextView to be the contentView for a window. When I create a WebView using the following code, it displays scrollbars, and the resizing thumb, and resizing the window works flawlessly.
When I comment out the WebView and attempt to use a NSTextView as the contentView, it does not "work" when the window is resized: Resizing the window using the thumb causes the content of the text view to not repaint correctly, it also paints over the title of the window, and the resizing thumb is also not repainted.
-(void)applicationDidFinishLaunching:(NSNotification*)aNotification{
NSTextView* view = [[NSTextView alloc] initWithFrame:[window frame]];
// WebView* view = [[WebView alloc] initWithFrame:[window frame]];
[window setContentView:view];
[window makeFirstResponder:view];
[window makeKeyAndOrderFront:view];
}
Edit: Working code. Creates a NSScrollView to be the windows new contentView, and adds an NSTextView as its document.
-(void)applicationDidFinishLaunching:(NSNotification*)aNotification{
NSScrollView* scrollView = [[NSScrollView alloc] initWithFrame:[window frame]];
NSTextView* view = [[NSTextView alloc] initWithFrame:[scrollView bounds]];
[window setContentView:scrollView];
[scrollView setDocumentView:view];
[scrollView setHasVerticalScroller:YES];
[scrollView setHasHorizontalScroller:YES];
[window makeFirstResponder:view];
[window makeKeyAndOrderFront:view];
}

A web view makes and manages its own scrollers and is a special case rather than the norm. An NSTextView does not. It's just the text view. This is the norm - scrollable views come pre-wrapped in an NSScrollView only in the convenience of Interface Builder. In code, you must create an NSScrollView as well, then wrap the view in it. It's the scroll view that would be your top-level view in that case.

Related

Adding subviews in NSWindow while resizing the windows, the UI gets jumbled

I have a window and a subview is added, this subview is the container of another view(accessed and added using NSViewController).
I have disabled autolayout and doing resizing from springs. The subviews gets resize correctly on window resize.
If I add / remove subviews keeping the window size same it works fine. But if I add subview and maximize it and then remove and then add, it gets jumbled.
Some time it happens straight forward as :
Open the main window (it opens in small size). Maximize it, then add the subview, the subview is added to its original size as drawn in xib. Expected behavior is the subview should get expand and cover the main window.
I am not able to find the solution. Please help me to fix this. The sample code and sample project is attached here.
//In AppDelegate
- (IBAction)buttonClicked:(id)sender {
if (!self.myVC) {
self.myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
[self.containerView addSubview:self.myVC.view];
}
- (IBAction)clearClicked:(id)sender {
for (NSView *view in self.containerView.subviews) {
[view removeFromSuperview];
}
}
I got the answer,
Before adding the view to container view, I get the container's rect and set the frame for child view.
- (IBAction)buttonClicked:(id)sender {
if (!self.myVC) {
self.myVC = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
}
NSRect rect = NSMakeRect(0, 0, self.containerView.frame.size.width, self.containerView.frame.size.height);
[self.myVC.view setFrame:rect];
[self.containerView addSubview:self.myVC.view];
}

Invisible Fullscreen View with Cocoa

I'm trying to create an application which change the mouse cursor, but to do that the cursor must be inside a NSView. To do this all the time, I would need to have an intangible and invisible fullscreen view.
I've created a subclass of NSView which implement the following code to became full screen in initWithFrame:
[self enterFullScreenMode:[NSScreen mainScreen] withOptions:nil];
And using that code, I can change the cursor inside the view:
- (void)resetCursorRects{
[self addCursorRect:[self bounds] cursor:appCursor];
}
The cursor changed successfully, but here comes the first problem: the view is in fullscreen, but it's visible, like a gray background. I've tried this method:
[[self window] setOpaque:NO];
And this one:
[[self window] setBackgroundColor:[NSColor colorWithWhite:1.0 alpha:0.0]];
But both of them just change the view color to black instead of gray. How can I fix that?

Visible buttons with transparent navigation bar

I've seen several apps that have completely transparent navigation bars but with visible buttons, I cant seem to find anything that wont make the button invisible as well. I'm sure they were using UINavigationController for the navbar because it had the same animations with fade and what not.
Im currently using this code in ViewDidLoad and ViewDidAppear to either hide or show the nav bar because it's not supposed to be on the first page-
[self.navigationController setNavigationBarHidden:NO animated:YES];
and this code for its transparency:
[self.navigationController.navigationBar setAlpha:0.0];
Create a subclass of UINavigationBar containing no methods except drawRect:. Put custom drawing code there if you need to, otherwise leave it empty (but implement it).
Next, set the UINavigationController's navigation bar to this subclass. Use initWithNavigationBarClass:toolBarClass: in code, or just change it in the Interface Builder if you're using storyboards/nibs (it's a subclass of your UINavigationController in the hierarchy at the side).
Finally, get a reference to your navigation bar so we can configure it using self.navigationController.navigationBar in the loadView of the contained view controller. Set the navigation bar's translucent to YES and backgroundColor to [UIColor clearColor]. Example below.
//CustomNavigationBar.h
#import <UIKit/UIKit.h>
#interface CustomNavigationBar : UINavigationBar
#end
//CustomNavigationBar.m
#import "CustomNavigationBar.h"
#implementation CustomNavigationBar
- (void)drawRect:(CGRect)rect {}
#end
//Put this in the implementation of the view controller displayed by the navigation controller
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.translucent = YES;
[self navigationController].navigationBar.backgroundColor = [UIColor clearColor];
}
Here's a screen shot of the result, mimicking Plague.
The blue border was drawn in drawRect: to show you that a UINavigationBar is there and not just a button and a label. I implemented sizeThatFits: in the subclass to make the bar taller. Both the button and label are UIView's containing the correct UI element that were placed in the bar as UIBarButtonItems. I embedded them in views first so that I could change their vertical alignment (otherwise they "stuck" to the bottom when I implemented sizeThatFits:).
self.navigationController.navigationBar.translucent = YES; // Setting this slides the view up, underneath the nav bar (otherwise it'll appear black)
const float colorMask[6] = {222, 255, 222, 255, 222, 255};
UIImage *img = [[UIImage alloc] init];
UIImage *maskedImage = [UIImage imageWithCGImage: CGImageCreateWithMaskingColors(img.CGImage, colorMask)];
[self.navigationController.navigationBar setBackgroundImage:maskedImage forBarMetrics:UIBarMetricsDefault];
//remove shadow
[[UINavigationBar appearance] setShadowImage: [[UIImage alloc] init]];
To make the Navigation Bar transparent, use the below code:
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.tintColor = [UIColor clearColor];
self.navigationController.navigationBar.translucent = YES;
After this set the background image of the Navigation Bar the same as the view behind it using the below property:
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"SAMPLE.jpg"] forBarMetrics:UIBarMetricsDefault];

how to pop a drawing uiview as a model view only half of the screen

I create new viewcontroller class with xib then created uiview inherited class and in xib file custom class I wrote the uiview inherited class name(PaintView).
I am trying to implement a simple drawing feature in my app, I created a simple drawing code which paints on uiview using touchbegain, thouchmoves, drawrect methods in PaintView class.
Till here its all working fine now I want to pop a model of this view, but I want it to display half of the screen, I resize it in interface builder but it is still showing on full screen.
Other posts says create a transparent view add contents at bottom half thats how you will get half model view, but this is not a solution for my problem.
How to properly pop model view but only half of the screen.
Simple, don't present it modally.
UIViewController *controller = [[UIViewController alloc] initWithNibName:#"myXib" bundle:[NSBundle mainBundle]];
[controller.view setFrame:CGRectMake(0, 480, 320, 320)];
[self.view addSubview:controller.view];
[UIView animateWithDuration:0.5 animations:^{
[controller.view setTransform:CGAffineTransformMakeTranslation(0, -320)];
}];
To change the color's I recommend you store the integer values of your color's hues into an array, that way you can stably assign the hue from the integer value of some object in the array:
arrayOfColors = [[NSArray alloc] initWithObjects:#"0.0", #"0.1", #"0.2", #"0.3", #"0.4", #"0.5", #"0.6", #"0.7", #"0.8", #"0.9", nil];
[[UIColor colorWithHue:[[arrayOfColors objectAtIndex:someIndex]floatValue] saturation:1.0 brightness:1.0 alpha:1.0]setStroke];

UIProgressView+Activity Indicator View on a UITableView during data upload

I have a uitableview.
I saw this "effect" and I would replay it:
When the user taps on a button to upload some data on a server, I would a gray (transparent) view with a progress bar (maybe with also an activity indicator) appears on the table.
The table is disabled and can be viewed through the gray view (that is the gray transparent view covers all the table).
How can I achieve this?
Have I create a view with a progressive view on it and then put it in the same xib of the table, disabling it properly programmatically? Or?
Lay a large black UIView over top of the UITableView with an alpha value of 0.5. Then put a spinner (UIActivityIndicatorView) on top of that.
Something like this:
UIView *view = [[UIView alloc] init];
view.frame = myTableView.frame;
// save this view somewhere
UIActivityIndicatorView *ac = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
CGRect frame = view.frame;
ac.center = CGPointMake(frame.size.width/2, frame.size.height/2);
[view addSubview:ac];
[ac startAnimating];
[ac release];
[myTableView addSubview:view];
[view release];
Then remove it later with [view removeFromSuperview]