Fade in/Fade out for MAAttachedWindow - objective-c

I'm using Matt Gemmell's MAAttachedWindow (http://mattgemmell.com/source) with an NSStatusItem to display a custom view in the menu bar. I'm confused as to how to get it to fade in and fade out. Normally I'd do something like this:
[window makeKeyAndOrderFront:self];
[[window animator] setAlphaValue:1.0];
and to fade out:
[[window animator] setAlphaValue:0.0];
However this code seems to have no effect with MAAttachedWindow. Any ideas?
Thanks

Sorry to drudge up an old post, but I thought it worthwhile mentioning that it works just fine for me to set the alpha value directly, with no need to add accessors/getters.
Simply doing (depending on your setup, or course):
[[self window] addChildWindow:attachedWindow ordered:NSWindowAbove];
[attachedWindow setAlphaValue:0.0];
[NSAnimationContext beginGrouping];
[[NSAnimationContext currentContext] setDuration:0.5];
[attachedWindow makeKeyAndOrderFront:self];
[[attachedWindow animator] setAlphaValue:1.0];
[NSAnimationContext endGrouping];
Works just fine.

I'm not especially well versed in CoreAnimation and the usage of implicit animations. However, I was able to get the MAAttachedWindow to fade in by adding an explicit alphaValue property to the MAAttachedWindow class:
#interface MAAttachedWindow : NSWindow {
CGFloat _alphaValue;
...
}
-(CGFloat) alphaValue;
-(void) setAlphaValue:(CGFloat)windowAlpha;
...
#implementation MAAttachedWindow
- (CGFloat) alphaValue {
return _alphaValue;
}
- (void) setAlphaValue:(CGFloat)windowAlpha {
_alpha = windowAlpha;
[super setAlphaValue:windowAlpha];
}
...
By adding that, I was able to get the implicit animation for setAlphaValue to work:
(below code cribbed from Matt's Sample "NSStatusItemTest" code)
- (void)toggleAttachedWindowAtPoint:(NSPoint)pt
{
...
[attachedWindow makeKeyAndOrderFront:self];
[[attachedWindow animator] setAlphaValue:1.0];
I am not sure why explicitly defining the alphaValue property works. I would expect the inherited version from NSWindow would be invoked for the implicit animation. It doesn't appear to though.

Related

How do I stop a hidden UIView from making UITextFields unclickable?

I have a UITextfield dedicated to dates. When clicked I have a method that shows a UIView with a UIDatePicker as a subview and a method to hide it again. By default this UIView is hidden.
I've noticed that the textfields of my form are no longer clickable. However my UIButtons are still working.
The UIView is a subview of the superview that the UITextFields and UIButtons are also part of. The UIView also takes up the whole area of the window.
The UIView is an outlet also.
Does anyone have any idea what is happening here?
Kind regard
Code:
- (void) hidePickerView {
[UIView animateWithDuration:0.5
animations:^{
[[self datePickerView] setFrame:CGRectMake(0, -250, 320, 50)];
} completion:^(BOOL finished) {
[[self datePickerView] removeFromSuperview];
}];
}
I've also tried putting the following in my viewDidLoad method:
[[self datePickerView] removeFromSuperview];
I was returning NO in my - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField method. Setting this to yes solved the problem.

How can I hide/remove a subview by default when it's superview loaded but still have access to it?

I have a view which displays a UILabel and UITextField subviews as well as an UIImageView and 2 UIButtons. These all make up a form. One of the fields is dedicated to date entry in dd/mm//yyyy format.
I decided to create another view (called datePickerView) inside my main view which holds a UIDatePicker instance. When the date field on the form mentioned above is clicked this view with the datepicker is show. Upon clicking the done button the view is hidden/removed again.
I have methods that deal with the showing and hiding of this view:
#property (weak, nonatomic) IBOutlet UIView *datePickerView;
- (void) hidePickerView {
[UIView animateWithDuration:0.5
animations:^{
[[self datePickerView] setFrame:CGRectMake(0, -250, 320, 50)];
} completion:^(BOOL finished) {
[[self datePickerView] removeFromSuperview];
}];
}
- (void) showPickerView {
[[self view] addSubview:[self datePickerView]];
[[self datePickerView] setFrame: CGRectMake(0, -250, 320, 50)];
[UIView animateWithDuration:1.0
animations:^{
[[self datePickerView] setFrame: CGRectMake(0, 152, 320, 260)];
}];
}
I call these methods in my textFieldDidEndEditing and textFieldShouldBeginEditing UITextField delegate methods.
My problem is the the view with the datepicker is visible when it's superview is first loaded. I tried dragging this datepicker view to the top of the hierarchy above all the textfields and buttons but this only shifts the view behind them.
I've also tried hiding the view through storyboard interface, tried adding a hide method to viewDidLoad, viewWillAppear. The methods I tested were:
[self datePickerView] removeFromSuperview];
[[self datePickerView] setHidden:YES];
[self hidePickerView];
These hide the datePickerView no problem but when I click the textfield the datePickerView doesn't show.
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
// missing since date field error checking
if (textField == [self missingSinceField]) {
[self showPickerView];
return NO;
}
return YES;
}
-(void)textFieldDidEndEditing:(UITextField *)textField {
if (textField == [self missingSinceField]) {
[self hidePickerView];
}
}
When I don't hide or remove the datePickerView in any way shape or form and tap it the datePickerView is loaded no problem.
** Just before posting this question I set a breakpoint in my showDatePicker method and when I uncomment [self datePickerView] removeFromSuperview]; I see that my datePickerView outlet is nil so this may explain why I'm having the issue I'm having. Commenting it again and trying again shows it as not being nil.
I think this is what's wrong but not sure how to make sure when viewDidLoad is run that my datePickerView isn't nil. I can't have it showing in the background of the form under the text fields and I don't think changing the colour of it to white so users can't see it isn't elegant.
Help would be appreciated.
Kind regards
I guess your IBOutlet property for datePickerView is weak, so, when you remove it from the superview it gets destroyed.
Either make it strong, or use the hidden property instead (remembering to set hidden to NO in showPickerView and YES in hidePickerView - where you currently add and remove the view).
You probably want to use the hidden property of the UIView subclass you are working with.
Source:
UIView reference
As far as your outlet being nil - make sure you have connected the IBOutlet to an actual element in the storyboard.

Can't programmatically move label in viewDidLoad

I'm trying to move a uiLabel down a drop if it's an iPhone 5 (4" display). But it's not working when the code is in viewDidLoad. If I call the code from clicking a uiButton, it works. Here's the code:
-(void) viewDidLoad {
if(CGSizeEqualToSize([[UIScreen mainScreen] preferredMode].size,CGSizeMake(640, 1136))) {
CGRect frame = [self.timeOnCurrentQuestion frame];
frame.origin.y += 40; // change the location
[self.timeOnCurrentQuestion setFrame:frame];
nslog(#"This DOES get logged");
}
}
Jonah, have you tried your code in viewWillAppear method? Possibly, it'll sort-out your issue.
Maybe that are something you need to beware of.
- (void)viewDidLoad
It is a method that when the controller juz created its view.
for example:
maybe in your init method, you call something like:
[self.view setBackground:[UIColor redColor]];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
In this case the work flow will be like this:
[self.view setBackground:[UIColor redColor]];
[self viewDidload];
self.timeOnCurrentQuestion = [[UIView alloc] initWithFrame:kFrame];
Th reason for this work flow is because the self.view is called, then its view is needed before the normal view cycle, so , in this case, self.timeOnCurrentQuestion is still nil in the viewDidload method.
I don't know if my practice is the best or not.
I always init the subView in the controller's init method.
and do the [self.view addSubview:_subview] (//or everything method call that require the self.view) in [self viewDidload];
viewDidAppear worked for me. The life cycle seems to be
LoadView()
viewDidLoad()
viewWillAppear()
viewDidAppear()

Setting background color in drawRect of NSSearchField subclass

I have a custom subclass of NSSearchField that I would like to set the background color of.
#interface CustomNSSearchField : NSSearchField
#end
So far, I have tried:
Attempt #1
#implementation CustomNSSearchField
- (void)drawRect:(NSRect)rect
{
[super drawRect:rect];
[self setDrawsBackground:YES];
[self setBackgroundColor:[NSColor redColor]];
}
which resulted in no visual changes at all:
I then followed the suggestions here and also tried:
Attempt #2
- (void)drawRect:(NSRect)rect
{
[super drawRect:rect];
[[NSColor redColor] setFill];
NSRectFill(rect);
}
Which results in this:
How do I set the background color inside the bounds and behind the text of the search field?
You have to redraw the entire thing.
There is no property, to specifically change the background-color of the NSSearchField.
Check out this example:
Custom NSSearchField
Edit:
Also what's worth to point out.
You should never override the controls drawRect method.
You should rather make a subclass of NSSearchFieldCell.

Window Fade in and Out

how do I fade a window in when it's opened and out when closed?
This should probably be done in Objective C. This has to be part of an AppleScript-Objective-C project. I'm using a property linked to the window, and doing makeKeyAndOrderFront on it...
Any help would be appreciated!
Subclass (or add a category to) NSWindow and add:
- (void)fadeInAndMakeKeyAndOrderFront:(BOOL)orderFront {
[self setAlphaValue:0.0];
if (orderFront) {
[self makeKeyAndOrderFront:nil];
}
[[self animator] setAlphaValue:1.0];
}
- (void)fadeOutAndOrderOut:(BOOL)orderOut {
if (orderOut) {
NSTimeInterval delay = [[NSAnimationContext currentContext] duration] + 0.1;
[self performSelector:#selector(orderOut:) withObject:nil afterDelay:delay];
}
[[self animator] setAlphaValue:0.0];
}
This allows you to fade in/out windows programmatically.
To have a window fade out when its close button gets pushed, add this to the window's delegate:
- (BOOL)windowShouldClose:(id)sender {
[window fadeOutAndOrderOut:YES];
return NO;
}
To show a window with fade-in call [window fadeInAndMakeKeyAndOrderFront:YES]; instead of what you'd call otherwise.