views:

298

answers:

2

Hi,

I am trying to implement TTPhotoViewController in a sample iPad application. I have implemented properly TTPhotoSource and TTPhoto protocols. The TTPhotoViewController does show image, but not until swiped.

The right and left button in the tab bar below doesnt seem to work at all, they never change the image displayed. The UIActivityIndicatorView is never put up, nor the right and left buttons are validated when last or first images are reached.

I am initializing the subclass of TTPhotoViewController as a rootViewController of a UINavigationController object which I am adding it onto a view.

This rules out the possibility of the problem faced here: http://three20.stackexchange.com/questions/78/ttphotoviewcontroller-not-loading-images-immediately

What else am I missing? Anybody faced similar problems and found a way around?

Thanks, Raj

A: 

After some debugging, I found out the problem, this is just a quick fix:

In TTModelViewController class of Three20UI project, find the method

-refresh

and comment the if condition:

if (_isViewAppearing)

Eventually -updateView method will be called which was not being called previously.

This is a quick fix, have to investigate about the bool: _isViewAppearing later.

Raj
Anybody else with a clear solution can add your answers . . .
Raj
+1  A: 

Had the same problem. The TTPhotoSource needs to send modelDidFinishLoad: to its delegates when it has finished loading... otherwise, TTPhotoViewController assumes it's not ready yet.

That's not all, however. Especially when loading local images, your photo source will probably finish loading before the TTPhotoViewController is registered as a delegate. So, you need to check for delegates added to your TTPhotoSource and send them a modelDidFinishLoad: message if you're done loading when they're added.

And that's easier said than done if you inherit from TTModel, because there's no way to register with an NSMutableArray to find out when it's changed.

So... add the following code to your TTPhotoViewController subclass...

// superDelegates KVO Mutator Methods

- (NSMutableArray*)delegates {
 return [self mutableArrayValueForKey:@"superDelegates"];
}

- (void)insertObject:(id)object inSuperDelegatesAtIndex:(NSUInteger)index {
 [super.delegates insertObject:object atIndex:index];

 if ([self isLoaded]) {
  if ([object respondsToSelector:@selector(modelDidFinishLoad:)]) {
   [object performSelector:@selector(modelDidFinishLoad:) withObject:self];
  }
 }
}

- (void)removeObjectFromSuperDelegatesAtIndex:(NSUInteger)index {
    [super.delegates removeObjectAtIndex:index];
}

- (NSArray*) superDelegates {
 return super.delegates;
}

This creates a "virtual" property named superDelegates, which is merely an NSArray, not an NSMutableArray. The insertObject:inSuperDelegatesAtIndex: and removeObjectFromSuperDelegatesAtIndex: methods, because their names include the name of the "superDelegates" property, allow the Key-Value Coding function (which you automatically have because it's an informal protocol) mutableArrayValueForKey: to synthesize a proxy object conforming to NSMutableArray, which allows edits to the superDelegates property by translating mutation operations into calls to the insertObject:inSuperDelegatesAtIndex: and removeObjectFromSuperDelegatesAtIndex: methods.

Then, all you have to do is override the "delegates" method to return such a generated proxy, and poof, all array changes run through you, allowing you to send off the proper load notification when the TTPhotoViewController attaches itself.

MrNerdHair
Looks like a perfect approach. I will try to code it later and see how well it suits to my implementation.
Raj