Make View and Sub View Programmatically - objective-c

I have the following code to create my window, my view and my sub view programmatically. The problem is my subview "filterView2" when it is added [filterView addSubview:filterView2]; crashes on that line. Is there something I forgot to include or did wrong? thanks!
NSRect mainFrame = [[NSScreen mainScreen] frame];
NSRect helpFrame = NSZeroRect;
float width = 600;
float height = 400;
helpFrame.origin.x = (mainFrame.size.width - width) / 2.0;
helpFrame.origin.y = 260.0;
helpFrame.size.width = width;
helpFrame.size.height = height;
helpWindow2 = [[BrightnessView windowWithFrame:helpFrame] retain];
// Configure window.
[helpWindow2 setReleasedWhenClosed:YES];
[helpWindow2 setHidesOnDeactivate:NO];
[helpWindow2 setCanHide:NO];
[helpWindow2 setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[helpWindow2 setIgnoresMouseEvents:YES];
[helpWindow2 setBackgroundColor:[NSColor clearColor]];
[helpWindow2 setOpaque:NO];
// Configure contentView.
NSView *filterView = [helpWindow2 contentView];
[filterView setWantsLayer:YES];
//add subview
NSView *filterView2 = [helpWindow2 contentView];
[filterView addSubview:filterView2];
//CALayer for filterView
CALayer *theLayer = [CALayer layer];
theLayer.opacity = 0;
[filterView setLayer:theLayer];
CGColorRef bgColor = CGColorCreateGenericRGB(0, 200, 255, 1);
theLayer.backgroundColor = bgColor;
CGColorRelease(bgColor);
theLayer.borderColor = CGColorGetConstantColor(kCGColorWhite);
theLayer.cornerRadius = 8.0;
float helpOpacity = (([NSApp isActive] ? 1 : 0));
[[[helpWindow2 contentView] layer] setOpacity:helpOpacity];
[window addChildWindow:helpWindow2 ordered:NSWindowAbove];

I think filterView and filterView2 are the same object, which causes an exception. You cannot add a view as a subview of itself.

Related

Horizontal UIScrollView with multiple textfields to display

I'm new to Xcode. I want to make a UIScrollView with multiple pages and each page having multiple UITextFields which vary on each page. I made UIScrollView with paging enabled. Now I'm stuck at displaying textfield's on scroll pages.
Here is my code so far:
//set the paging to yes
self.scrollview.pagingEnabled = YES;
// create 5 pages
NSUInteger numberOfViews = 5;
for (int i = 0; i < numberOfViews; i++)
{
//set the origin of the sub view
CGFloat myOrigin = i * self.view.frame.size.width;
//create the sub view and allocate memory
myView = [[UIView alloc] initWithFrame:CGRectMake(myOrigin, 0, self.view.frame.size.width, self.view.frame.size.height)];
//create a label and add to the sub view
CGRect myFrame = CGRectMake(10.0f, 10.0f, 200.0f, 25.0f);
textLabel = [[UILabel alloc] initWithFrame:myFrame];
textLabel.font = [UIFont boldSystemFontOfSize:16.0f];
textLabel.textAlignment = NSTextAlignmentLeft;
[myView addSubview:textLabel];
//create a text field and add to the sub view
myFrame.origin.y += myFrame.size.height + 10.0f;
textField = [[UITextField alloc] initWithFrame:myFrame];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.tag = i+1;
[myView addSubview:textField];
//set the background to different color
//set the scroll view delegate to self so that we can listen for changes
self.scrollview.delegate = self;
//add the subview to the scroll view
[self.scrollview addSubview:myView];
}
//scroll horizontally
self.scrollview.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews,
self.scrollview.frame.size.height);
//we set the origin to the 1rd page
CGPoint scrollPoint = CGPointMake(self.view.frame.size.width * 0, 0);
//change the scroll view offset the the 1rd page so it will start from there
[scrollview setContentOffset:scrollPoint animated:YES];
[self.view addSubview:self.scrollview];
}
Use This code here textfieldCount is
for (int j=0; j < textFieldCount; j++)
{
myFrame.origin.y += myFrame.size.height + 10.0f*(j+1);
UITextField *textField = [[UITextField alloc] initWithFrame:myFrame];
textField.borderStyle = UITextBorderStyleRoundedRect;
textField.tag = j+1;
[myView addSubview:textField];
}
Hope you got your answer.

Create a temporary HUD popup notification in Cocoa App

Im trying to have a window pop up to notify the user of an action, kind of like how the Flutter app shows a play/pause notification when a gesture is received.
This comes up for about two seconds and vanishes. The app itself is run from the menu bar so this pop up doesn't take control from whatever application is currently in focus but rather just shows on top of it and cannot be interacted with. I basically want to recreate exactly this. Say in the body of
- (void)popup:(id)sender {}
This is essentially very similar to a toast on android.
Edit: I looked closer at the flutter app and all it does is display two images (.png) one for the huge pause and another to indicate what application its in (in this case iTunes). Question now is how do I display an image like this.
You should take a look at this:
https://github.com/Foxnolds/MBProgressHUD-OSX
or Growl:
http://growl.info/documentation/developer/
To replicate this I added a 'HUD Window" from the interface builder which is just an NSPanel. I then added a image view to the panel and set the panel's colour to clear. I was then able to position the panel where I wanted and overlay the appropriate image.
I'm using this code:
static void showHud(NSString* text, int width, int height, CGFloat duration, int fontSize) {
NSWindow* window = [NSWindow new];
[window setFrame:NSMakeRect(0,0,width,height) display:NO];
[window center];
window.titleVisibility = NSWindowTitleHidden;
window.styleMask = NSWindowStyleMaskBorderless;
window.alphaValue = 0.9;
window.movableByWindowBackground = YES;
[window setLevel: NSStatusWindowLevel];
[window setBackgroundColor: [NSColor clearColor]];
[window setOpaque:NO];
//[window setHasShadow:NO];
[window makeKeyAndOrderFront:NSApp];
NSVisualEffectView *view = [[NSVisualEffectView new] initWithFrame:window.contentView.bounds];;
view.translatesAutoresizingMaskIntoConstraints = NO;
[view setBlendingMode:NSVisualEffectBlendingModeBehindWindow];
[view setMaterial:NSVisualEffectMaterialDark];
[view setState:NSVisualEffectStateActive];
//[view setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
//[view setWantsLayer:NO];
[view setWantsLayer:YES];
view.layer.cornerRadius = 16.;
//view.layer.shouldRasterize = YES;
//view.layer.rasterizationScale = 0.45;
view.layer.shadowOpacity = 0.1; //0.01;
view.layer.edgeAntialiasingMask = kCALayerTopEdge | kCALayerBottomEdge | kCALayerRightEdge | kCALayerLeftEdge;
[window.contentView addSubview:view];
//window.contentView = view;
NSTextField *label = [[NSTextField alloc] initWithFrame:view.bounds];
[label setBezeled:NO];
[label setDrawsBackground:NO];
[label setEditable:NO];
[label setSelectable:NO];
label.stringValue = text;
label.alignment = NSTextAlignmentCenter;
label.textColor = [NSColor whiteColor];
label.backgroundColor = [NSColor clearColor];
label.font = [NSFont fontWithName:#"Arial-BoldMT" size:fontSize];
//NSRect titleRect = [label titleRectForBounds:view.bounds];
NSSize cellSize = [label.cell cellSizeForBounds:view.bounds];
NSSize strSize = cellSize; // [label.attributedStringValue size];
NSRect frame = view.frame;
frame.origin.y = frame.size.height / 2 - strSize.height / 2;
frame.size.height = strSize.height;
label.frame = frame;
[view addSubview:label];
[NSAnimationContext runAnimationGroup:^(NSAnimationContext *context) {
context.duration = duration;
window.animator.alphaValue = 0.;
} completionHandler:^{
[window close];
}];
}

Remove Multiple instances of NSView

I have this code which draws a Window and NSView, and have set up tracking to when mouse entered and exits it increases/decreases the size of my window. The problem is when the mouse events are called and the int value of the width and height are increased, the window redraws itself to the new hight and leaves the old one there, how can I remove the old one and just draw the new one? thanks!
- (void)toggleHelpDisplay:(int)value
{
// Create helpWindow.
NSRect mainFrame = [[NSScreen mainScreen] frame];
NSRect helpFrame = NSZeroRect;
float width = 90;
float height = 90;
helpFrame.origin.x = (mainFrame.size.width - width) / 2.0;
helpFrame.origin.y = 200.0;
helpFrame.size.width = width + value;
helpFrame.size.height = height + value;
helpWindow = [[BrightnessView windowWithFrame:helpFrame] retain];
// Configure window.
[helpWindow setReleasedWhenClosed:YES];
[helpWindow setHidesOnDeactivate:NO];
[helpWindow setCanHide:NO];
[helpWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[helpWindow setIgnoresMouseEvents:NO];
// Configure contentView.
NSView *contentView = [helpWindow contentView];
[contentView setWantsLayer:YES];
CATextLayer *layer = [CATextLayer layer];
layer.opacity = 0;
[contentView setLayer:layer];
CGColorRef bgColor = CGColorCreateGenericGray(0.0, 0.6);
layer.backgroundColor = bgColor;
CGColorRelease(bgColor);
layer.string = (shadyEnabled) ? HELP_TEXT : HELP_TEXT_OFF;
layer.contentsRect = CGRectMake(0, 0, 1, 1);
layer.fontSize = 40.0;
layer.foregroundColor = CGColorGetConstantColor(kCGColorWhite);
layer.borderColor = CGColorGetConstantColor(kCGColorWhite);
layer.borderWidth = 4.0;
layer.cornerRadius = 4.0;
layer.alignmentMode = kCAAlignmentCenter;
[window addChildWindow:helpWindow ordered:NSWindowAbove];
float helpOpacity = (([NSApp isActive] ? 1 : 0));
[[[helpWindow contentView] layer] setOpacity:helpOpacity];
//track mouse so that once hovered make larger.
self.helpView = contentView;
trackingArea = [[[NSTrackingArea alloc] initWithRect:[self.helpView bounds]
options:NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways
owner:self
userInfo:nil] autorelease];
[self.helpView addTrackingArea:trackingArea];
}
- (void)mouseEntered:(NSEvent *)event;
{
NSLog(#"entered");
[self toggleHelpDisplay:+100];
}
- (void)mouseExited:(NSEvent *)event;
{
NSLog(#"exited");
[self toggleHelpDisplay:-100];
}
It looks like you're recreating your help window every time your mouse enters or exits, when all you want to do is change its frame. Why not use the code you have to create the window once, and in your mouseDown method just change the frame with setFrame:display:
[helpWindow setFrame:NSMakeRect(helpWindow.frame.origin.x,helpWindow.frame.origin.y,helpWindow.size.width +100,helpWindow.size.height +100) display:YES];

Using NSPoint Mouse Tracking on NSView

I have this method in App Delegate that makes a window and content view but I want to be able to track the mouse using an NSPoint on entered and exiting the view. The problem is I do not want to make a NSView Custom class and want to do it all within my AppDelegate. The mouse tracking (at the bottom) does not work, any suggestions?
- (void)toggleHelpDisplay
{
// Create helpWindow.
NSRect mainFrame = [[NSScreen mainScreen] frame];
NSRect helpFrame = NSZeroRect;
float width = 75;
float height = 75;
helpFrame.origin.x = (mainFrame.size.width - width) / 2.0;
helpFrame.origin.y = 200.0;
helpFrame.size.width = width;
helpFrame.size.height = height;
helpWindow = [[BrightnessView windowWithFrame:helpFrame] retain];
// Configure window.
[helpWindow setReleasedWhenClosed:YES];
[helpWindow setHidesOnDeactivate:NO];
[helpWindow setCanHide:NO];
[helpWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[helpWindow setIgnoresMouseEvents:NO];
// Configure contentView.
NSView *contentView = [helpWindow contentView];
[contentView setWantsLayer:YES];
CATextLayer *layer = [CATextLayer layer];
layer.opacity = 0;
[contentView setLayer:layer];
CGColorRef bgColor = CGColorCreateGenericGray(0.0, 0.6);
layer.backgroundColor = bgColor;
CGColorRelease(bgColor);
layer.string = ? HELP_TEXT : HELP_TEXT_OFF;
layer.contentsRect = CGRectMake(0, 0, 1, 1.2);
layer.fontSize = 40.0;
layer.foregroundColor = CGColorGetConstantColor(kCGColorWhite);
layer.borderColor = CGColorGetConstantColor(kCGColorWhite);
layer.borderWidth = 4.0;
layer.cornerRadius = 4.0;
layer.alignmentMode = kCAAlignmentCenter;
[window addChildWindow:helpWindow ordered:NSWindowAbove];
float helpOpacity = (([NSApp isActive] ? 1 : 0));
[[[helpWindow contentView] layer] setOpacity:helpOpacity];
//track mouse so that once hovered make larger.
NSPoint mouseLocation = [[self window] mouseLocationOutsideOfEventStream];
if (NSPointInRect(mouseLocation, helpFrame)) {
NSLog(#"mouse over");
}
else
{
NSLog(#"mouse not over");
}
}
You should be able to do this using NSTrackingArea; You'd do something like this (typed in the browser, not tested):
self.helpView = contentView; // Need to store a reference to the view if you want to convert from its coordinate system
// Set up a tracking area
NSTrackingArea *trackingArea = [[[NSTrackingArea alloc] initWithRect:[self.helpView bounds]
options:NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved
owner:self
userInfo:nil] autorelease];
[self.helpView addTrackingArea:trackingArea];
- (void)mouseEntered:(NSEvent *)event;
{
NSPoint location = [self.helpView convertPoint:[event locationInWindow] fromView:nil];
// Do whatever you want to do in response to mouse entering
}
- (void)mouseExited:(NSEvent *)event;
{
NSPoint location = [self.helpView convertPoint:[event locationInWindow] fromView:nil];
// Do whatever you want to do in response to mouse exiting
}
- (void)mouseMoved:(NSEvent *)event;
{
NSPoint location = [self.helpView convertPoint:[event locationInWindow] fromView:nil];
// Do whatever you want to do in response to mouse movements
}

Extending UIScrollView when it fills up with more content

Ok, so i got a scrollview to load when an user logs in to my application. When the user is authenticated, i need to create a scrollview programmatically. To do so, i have the following code:
[scrollView removeFromSuperview];
UIScrollView *view = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, applicationFrame.size.width, self.view.frame.size.height)];
view.backgroundColor = [UIColor greenColor];
//-- get the y-coordinate of the view
CGFloat viewCenterY = self.view.center.y;
//--calculate how much visible space is left
CGFloat freeSpaceHeight = applicationFrame.size.height - keyboardBounds.size.height;
//-- calculate how much the scrollview must scroll
CGFloat scrollAmount = viewCenterY - freeSpaceHeight / 2.0;
if(scrollAmount < 0) scrollAmount = 0;
//set the new scrollsize contentview
view.contentSize = CGSizeMake(applicationFrame.size.width, applicationFrame.size.height + keyboardBounds.size.height);
//scroll the scrollview
[view setContentOffset:CGPointMake(0, scrollAmount) animated:YES];
for(int v = 0; v < 15; v++){
CGFloat yCoord = v * 100;
UILabel *mijnLabel = [[UILabel alloc] initWithFrame:CGRectMake(50, yCoord, 200, 50)];
mijnLabel.text = #"1337";
mijnLabel.font = [UIFont fontWithName:#"Verdana" size:20];
mijnLabel.textColor = [UIColor redColor];
[view addSubview:mijnLabel];
[mijnLabel release];
}
[self.view addSubview:view];
[view release];
}
How do i extend my view according to the amount of labels i added? I also want to know how i can make my scrollview fill up the entire screen.. My scrollview is now only filling up the screen when in portrait mode.
This is the login screen that gets removed:
[scrollView removeFromSuperview];
you need to keep track of numbers of label that you are adding into the scroll view. suppose if your label's height is 50 then take a variable and make a total of all label's height and give a new frame to your scroll view. like :
view.frame = CGRectmake(0,0,applicationFrame.size.width,totalHeightOfLabel);
[self.view addSubview:view];
[view release];
hope this will give a idea...