• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Subclassing add: of NSArraycontroller
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


  • Follow-Ups:
    • Re: Subclassing add: of NSArraycontroller
      • From: Kyle Sluder <email@hidden>
  • Prev by Date: Dividing NSView to subviews
  • Next by Date: Strange problem with NSNotificationCenter and NPAPI plugin
  • Previous by thread: Re: Dividing NSView to subviews
  • Next by thread: Re: Subclassing add: of NSArraycontroller
  • Index(es):
    • Date
    • Thread