ReactiveCocoaLayout
ReactiveCocoaLayout copied to clipboard
A signal equivalent to AVMakeRectWithAspectRatioInsideRect ?
I've been constructing my own signal to pass a CGSize through AVFoundation's very useful AVMakeRectWithAspectRatioInsideRect function. Example:
self.videoScaledSizeSignal = [[RACSignal combineLatest:@[
[RACAbleWithStart(self,player.currentItem.tracks) distinctUntilChanged] ,
[RACAbleWithStart(self.maxSize) distinctUntilChanged]]
reduce:^(NSArray *array,NSValue *maxSize){
// If maxSize hasn't been set, just return a zero rect
CGSize videoScaledSize = CGSizeZero;
if (CGSizeEqualToSize(maxSize.med_sizeValue, CGSizeZero)) {
return MEDBox(videoScaledSize);
}
for (AVPlayerItemTrack *itemTrack in array) {
if ([itemTrack.assetTrack.mediaType isEqualToString:AVMediaTypeVideo]) {
CGSize naturalSize = itemTrack.assetTrack.naturalSize;
videoScaledSize = AVMakeRectWithAspectRatioInsideRect(naturalSize, CGRectWithSize(maxSize.med_sizeValue)).size;
}
}
return MEDBox(videoScaledSize);
}] filter:^BOOL(NSValue *videoScaledSize) {
return !CGSizeEqualToSize(videoScaledSize.med_sizeValue, CGSizeZero);
}];
I was going to submit a pull request for a RACSignal category containing a simplified version of my above signal, but there's a problem. AVMakeRectWithAspectRatioInsideRect requires AVFoundation, and I'm not sure it's a good idea to add a big dependency like that to RCL.
What would the best way be to add this functionality to RCL (or RAC)?
I want to add something like this as a RAC extension:
- (RACSignal *)resizeWithAspect:(RACSignal *)maxSize
{
return [[self combineLatestWith:maxSize] map:^id(RACTuple *tuple) {
RACTupleUnpack_(NSValue *oldSize,NSValue *maxSize) = tuple;
CGSize newSize = AVMakeRectWithAspectRatioInsideRect(oldSize.med_sizeValue, CGRectWithSize(maxSize.med_sizeValue)).size;
return MEDBox(newSize);
}];
}
edit here's another possibility:
- (RACSignal *)resizeWithAspect:(RACSignal *)maxSize
{
return [RACSignal combineLatest:@[self,maxSize] reduce:^id(NSValue *currentSize,NSValue *maxSize) {
CGSize newSize = AVMakeRectWithAspectRatioInsideRect(currentSize.med_sizeValue, CGRectWithSize(maxSize.med_sizeValue)).size;
return MEDBox(newSize);
}];
}
Thoughts?
A method like that would be useful, but we can't introduce a dependency on AVFoundation.
If you're willing to rewrite the sizing algorithm from scratch, I'd be happy to review a PR.
Yeah, I tried to find the actual implementation, but of course avfoundations m files are a tightly guarded secret. I'll try to come up with something equivalent.
In that case, let's leave this open until a PR is merged that completes it.
Instead of targeting CGSize, perhaps a better approach would be to mirror the syntax of UIViews contentMode. A signal with a name similar to UIViewContentModeScaleAspectFit like -(RACSignal *)scaleAspectFit:(RACSignal *)maxRect]. I'll push something based on that concept.
First things first. Submitting pull request to Archimedes for the functions themselves.
https://github.com/github/Archimedes/pull/14
Then a special RACSignal should be added to use them.