Reloading NSTableView on re-focus - objective-c

In my application, I have a NSWindow that has a NSTableView object and a few buttons. When the user presses the "new" button, an "ItemAdd" NSWindowController is activated where the user types in attributes for the item to be added to the NSTableView.
My question is this: since NSTableView requires reloadDatato update its view, how do I call reloadData after the ItemAdd window closes and focus shifts back to the NSWindow with the NSTableView.
Thanks for the help!

You could put reload data in a notification handler:
Put this in an initialization method of an object that you want the notification to get called on:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didBecomeMainWindow) name:#"NSWindowDidBecomeKeyNotification" object:nil];
Then make a method something like this:
- (void) didBecomeMainWindow
{
[tableView reloadData];
}

You can subclass the NSWindow and override the following method:
- (void)becomeKeyWindow

Related

Objective-C: Pass data between two not connected View Controllers

I have a ViewController A with a UILabel and a ViewController B with a button, so I want to update the label once I press the button. I could use delegates for this, but my ViewControllers are not connected and I can't use something like setDelegate, I don't create any instance of one in another. So basically they are created somewhere else. Is there any way to do that?
Variant 1: if ControllerA and ControllerB life-time differs
Use NSUserDefaults. On ControllerB button click store data into NSUserDefaults, in ControllerA read data from NSUserDefaults and show in label (NSUserDefaults is also observable, so can track changes in run-time)
Variant 2: if ControllerA and ControllerB both currently in run-time
Use NSNotificationCenter. On ControllerB button click post a NSNotification with data in userInfo, and ControllerA in notification handler extracts data from userInfo and assign to label.
Use Coordinator pattern.
Class that will create/get the 2 instances of both VCs,
and with delegates will move the data between them.
The advantage of Coordinator pattern is that your VCs can be re-used on others places (same or other project), and also the code is cleaner.
To expand on Apsperi's answer:
Notification method of changing the view controller:
In the view controller with the button on button press call:
[[NSNotificationCenter defaultCenter] postNotificationName:#"refresh"
object:self userInfo:nil];
Then in the viewdidload or viewdidappear method of the label view controller place the "receiver" for the notification:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(mymethotochangetext) name:#"refresh" object:nil];
The NSUserDefault method:
In the view controller with the button save a NSUserDefualt:
[[NSUserDefaults standardUserDefaults] setObject:somestring
forKey:#"myuniquekeyname"];
[[NSUserDefaults standardUserDefaults] synchronize];
Then in the view controller with the label you can get the saved string when the view loads and place it in the text field:
self.label.text=[[NSUserDefaults standardUserDefaults]
stringForKey:#"myuniquekeyname"];

Collapsing A Collection View Cell

I have a scroll view, inside a collection view cell. The scroll view has a class of its own (ClassA), as does the collection view (ClassB). When you tap the index row, it expands. Sweet, works just fine. Only problem is, you have to tap on the index row to collapse the cell. Since there is a UIScrollView hanging out in the cell, tapping on it won't collapse the cell. So, what I did was create tap detection in the scroll view. The tap detections selector then handles collapsing the cell via notifications:
Class A:
- (void)singleTap:(UITapGestureRecognizer *)gesture {
// Post a notification to collapse
[[NSNotificationCenter defaultCenter] postNotificationName:#"collapseCell" object:nil];
}
Class B:
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(deselectItemAtIndexPath:animated:)
name:#"collapseCell" object:nil];
}
Error: 'NSInvalidArgumentException', reason: '-[CollectionViewController deselectItemAtIndexPath:animated:]: unrecognized selector sent to instance 0x7caa
That NSNotificationis not doing what you think it's doing. Its not calling or trying to call the UICollectionView's delegate method, deselectItemAtIndexPath:animated:. Its actually looking for a different method, but with the same signature as the UICollectionViews delegate method.
Make a test method, call it something simple and see if that works to confirm what I think is happening.

Get rid of the keyboard from applicationDidEnterBackground in the AppDelegate.m

I have an application with Textfields in my MainViewController.m file. There is also a scrollview in that file, so when the keyboard comes up, the view scrolls so the user can see the textfield. The keyboard is dismissed when the user taps on the screen. Everything is working well EXCEPT in the case that the user hits the home button to put the app in the background and then comes back to it. In this case, the keyboard is still up, but my scrollview is down with textfields hidden. Ideally I would like to have the keyboard be dismissed as well.
Having looked into it, the methods that are called are all in the AppDelegate.m file (unfortunately it does not go into ViewDidLoad or any of the View lifecycle methods). How do I dismiss the keyboard from applicationDidEnterBackground in the AppDelegate.m file?
I am kind of a newbie - I have tried making a +dismisskeyboard function in my MainViewController file and calling it from the Appdelegate, but my Textfields are all instance variables and that does not work. I have also tried to create a textfield in my AppDelegate file and then do this -
[_someField becomeFirstResponder];
[_someField resignFirstResponder];
but this also does not work... I can't figure out how to link anything on my storyboard to the AppDelegate property of someField.
Can anyone suggest the correct approach to tackle this problem?
Just register a method for UIApplicationDidEnterBackgroundNotification in your MainViewController class and dismiss your keyboard there. e.g.
Register for the notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(receivedNotification:) name:UIApplicationDidEnterBackgroundNotification object:nil];
then add this method
- (void) receivedNotification:(NSNotification *) notification
{
[txtFld resignFirstResponder];
}

Dismiss a UIPopoverController from another view

I have a UIPopoverController named popover in another view. What I would like to know is, how can I dismiss the popover if a UIButton was pressed in the current popover view? Thanks in advance.
I always found it odd that a UIViewController knows how big it should be in a popover through it's "contentSizeForViewInPopover" property, but doesn't keep a pointer to the UIPopoverController itself. I always end up adding:
#property (nonatomic,assign) UIPopoverController* popover;
to my UIViewController classes, and set that when creating the popover. Then from anything in that UIViewController, I can do this to dismiss the popover:
[popover dismissPopoverAnimated:YES];
You could use an NSNotification to tell the other view to dismiss it's popover view.
Example usage:
// Add an observer that will respond to our notification.
[[NSNotificationCenter defaultCenter] addObserver:self // <- This is the object that will has the selector that we want to run (the same one we use in the next line).
selector:#selector(doSomething:) // <- This is the selector we want to run.
name:#"doSomethingNow" // <- This is notification name we will send to activate our observer's selector.
object:nil]; // Don't worry about this for now.
// Post the notification. This has the same name as our observer above, so our 'doSomething' selector should be run.
[[NSNotificationCenter defaultCenter] postNotificationName:#"doSomethingNow" object:nil];
// the function specified in the same class where we defined the addObserver
- (void)doSomething:(NSNotification *)pNotification {
NSLog(#"Received Notification...");
}

Refresh NSView content when the view is displayed with MAAttachedWindow

Im my application, I display a NSView when a user click on an icon in the systemstatusbar.
This NSView is displayed with MAAttachedWindow.
My question is : how to refresh the NSView content when the attachedWindow is displayed (makeKeyandorderFront)
I've tried to refresh the content in the awakeFromNib method,but it works only once.
Could anyone help me?
thanks
The solution I've found:
I've added a observer in my view:
I've set the object to [selft window] to listen the NSWindowDidBecomeKeyNotification notification of the MAAttachedwindow.
-(void)awakeFromNib
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:[self window]];
}
-(void) windowDidBecomeKey:(NSNotification *)note
{
// Do refresh here
}
The reason -awakeFromNib only works once is presumably because you're only loading the assembly from the xib once and keeping it around.
Presumably whatever action actually shows your view in the MAAttachedWindow instance is the ideal place to "refresh" it before display, ie your own call to -makeKeyAndOrderFront:.
So: What have you tried?