Subclassing add: of NSArraycontroller
Subclassing add: of NSArraycontroller
- Subject: Subclassing add: of NSArraycontroller
- From: ALEXander <email@hidden>
- Date: Thu, 23 Apr 2009 13:17:47 +0100
Hello,
to implement the automatic support of drag reordering in all
NSTableViews of my Core Data based application, I subclassed
NSArrayController using the very good tutorial supplied at
http://www.timisted.net/blog/archive/core-data-drag-drop/
I just put all the functionality in the new array controller class, in
this way its most convenient for me, and I hope its also wise from a
MVC standpoint.
One problem arose: I wanted to override the add: method and just add
the renumbering of the objects in order to have a new object
integrated into my numbering scheme:
- (IBAction)add:(id)sender
{
[super add:sender];
[self renumberViewPositions];
}
My NSManagedObjects all have an attribute viewPosition, which (via a
SubClass) ist automaticall set to an appropriate Value upon
awakeFromInsert.
---> The problem <---
In the renumbering routine, when I access [self arrangedobjects], or
even if I do a new fetch on my managedObjectContext, the new object is
not there yet. I tried all this:
[[self managedObjectContext] processPendingChanges];
[self prepareContent];
[self fetch:sender];
[self rearrangeObjects];
But it does not help.
---> The question <---
Is there a way to find that newly added object in this subclass? I do
not think it depends on me subclassing NSArrayController, because
something like
NSError *error = nil;
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:[self entityName]
inManagedObjectContext:[self managedObjectContext]]];
NSArray *objects = [[self managedObjectContext]
executeFetchRequest:request error:&error];
executed after the [super add:] does not contain the new object either.
---> The code (the important parts) <---
-
header
-----------------------------------------------------------------------------
#import <Cocoa/Cocoa.h>
enum AWWiewPositionArrayControllerPostitionValueTag {
AWWiewPositionArrayControllerPostitionValueTemporary = -1,
AWWiewPositionArrayControllerPostitionValueTop = -2,
AWWiewPositionArrayControllerPostitionValueBottom = -3
} AWWiewPositionArrayControllerPostitionValue;
@interface AWViewPositionArrayController : NSArrayController
{
NSTableView* _viewPositionTableview;
IBOutlet NSArrayController* _boundToSelection;
}
@property (readwrite, retain) IBOutlet NSTableView*
viewPositionTableView;
@end
-
implementation
----------------------------------------------------------------------
#import "AWViewPositionArrayController.h"
#import "AWViewPositionManagedObject.h"
@implementation AWViewPositionArrayController
@synthesize viewPositionTableView = _viewPositionTableview;
- (NSArray *)viewPositionSortDescriptor
{
return [NSArray arrayWithObject:[[NSSortDescriptor alloc]
initWithKey:@"viewPosition" ascending:YES]];
}
- (void) awakeFromNib
{
[self.viewPositionTableView setDataSource:self];
[self setSortDescriptors:[self viewPositionSortDescriptor]];
[self.viewPositionTableView registerForDraggedTypes:[NSArray
arrayWithObjects:AWViewPositionArrayControllerDropType, nil]];
}
- (NSArray *)itemsUsingFetchPredicate:(NSPredicate *)fetchPredicate
{
//fetch the objects ourself from the managedobjectcontext.
//the arraycontrollers arrangeditems is only for syncing with the
view and is not supposed to be used for this
NSError *error = nil;
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:[self entityName]
inManagedObjectContext:[self managedObjectContext]]];
NSArray *objects = [[self managedObjectContext]
executeFetchRequest:request error:&error];
if (error) {
NSLog(@"Fetch error! In
AWViewPositionArrayController:itemsUseingFetchPredicate");
}
return [[objects filteredArrayUsingPredicate:fetchPredicate]
sortedArrayUsingDescriptors:[self viewPositionSortDescriptor]];
}
- (NSArray *)itemsWithViewPosition:(int)value
{
NSPredicate *fetchPredicate = [NSPredicate
predicateWithFormat:@"viewPosition == %i", value];
return [self itemsUsingFetchPredicate:fetchPredicate];
}
- (NSArray *)itemsWithNonTemporaryViewPosition
{
NSPredicate *fetchPredicate = [NSPredicate
predicateWithFormat:@"viewPosition >= 0"];
return [self itemsUsingFetchPredicate:fetchPredicate];
}
- (NSArray *)itemsWithViewPositionGreaterThanOrEqualTo:(int)value
{
NSPredicate *fetchPredicate = [NSPredicate
predicateWithFormat:@"viewPosition >= %i", value];
return [self itemsUsingFetchPredicate:fetchPredicate];
}
- (NSArray *)itemsWithViewPositionBetween:(int)lowValue and:
(int)highValue
{
NSPredicate *fetchPredicate = [NSPredicate
predicateWithFormat:@"viewPosition >= %i && viewPosition <= %i",
lowValue, highValue];
return [self itemsUsingFetchPredicate:fetchPredicate];
}
- (int)renumberViewPositionsOfItems:(NSArray *)array startingAt:
(int)value
{
int currentViewPosition = value;
int count = 0;
if( array && ([array count] > 0) )
{
for( count = 0; count < [array count]; count++ )
{
AWViewPositionManagedObject *currentObject = [array
objectAtIndex:count];
currentObject.viewPosition = [NSNumber
numberWithInt:currentViewPosition];
currentViewPosition++;
}
}
return currentViewPosition;
}
- (void)renumberViewPositions
{
NSArray *startItems = [self
itemsWithViewPosition:AWWiewPositionArrayControllerPostitionValueTop];
NSArray *existingItems = [self itemsWithNonTemporaryViewPosition];
NSArray *endItems = [self
itemsWithViewPosition:AWWiewPositionArrayControllerPostitionValueBottom
];
int currentViewPosition = 0;
if( startItems && ([startItems count] > 0) )
currentViewPosition = [self renumberViewPositionsOfItems:startItems
startingAt:currentViewPosition];
if( existingItems && ([existingItems count] > 0) )
currentViewPosition = [self
renumberViewPositionsOfItems:existingItems
startingAt:currentViewPosition];
if( endItems && ([endItems count] > 0) )
currentViewPosition = [self renumberViewPositionsOfItems:endItems
startingAt:currentViewPosition];
}
- (IBAction)add:(id)sender
{
[super add:sender]; [[self managedObjectContext]
processPendingChanges];
[self prepareContent];
[self fetch:sender];
[self rearrangeObjects];
[self renumberViewPositions];
}
- (IBAction)remove:(id)sender
{
[super remove:sender];
[self renumberViewPositions];
}
-
end
---------------------------------------------------------------------------------
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden