Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.进行iOS系统的适配 #1638

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
3 changes: 2 additions & 1 deletion TZImagePickerController/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ - (void)useNavControllerAsRoot {
- (void)pushTZImagePickerController {
TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount:9 columnNumber:4 delegate:nil pushPhotoPickerVc:YES];
imagePickerVc.modalPresentationStyle = UIModalPresentationFullScreen;
UINavigationController *nav = (UINavigationController *)[UIApplication sharedApplication].keyWindow.rootViewController;
UIWindow *keyWindow = [TZCommonTools currentKeyWindow];
UINavigationController *nav =(UINavigationController *)keyWindow.rootViewController;
[nav.topViewController presentViewController:imagePickerVc animated:YES completion:nil];
}

Expand Down
5 changes: 2 additions & 3 deletions TZImagePickerController/FLAnimatedImage/FLAnimatedImage.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Flipboard
//
// Created by Raphael Schaad on 7/8/13.
// Copyright (c) 2013-2015 Flipboard. All rights reserved.
// Copyright (c) Flipboard. All rights reserved.
//


Expand All @@ -12,7 +12,6 @@
// Allow user classes conveniently just importing one header.
#import "FLAnimatedImageView.h"


#ifndef NS_DESIGNATED_INITIALIZER
#if __has_attribute(objc_designated_initializer)
#define NS_DESIGNATED_INITIALIZER __attribute((objc_designated_initializer))
Expand All @@ -34,7 +33,7 @@ extern const NSTimeInterval kFLAnimatedImageDelayTimeIntervalMinimum;
@property (nonatomic, strong, readonly) UIImage *posterImage; // Guaranteed to be loaded; usually equivalent to `-imageLazilyCachedAtIndex:0`
@property (nonatomic, assign, readonly) CGSize size; // The `.posterImage`'s `.size`

@property (nonatomic, assign, readonly) NSUInteger loopCount; // 0 means repeating the animation indefinitely
@property (nonatomic, assign, readonly) NSUInteger loopCount; // "The number of times to repeat an animated sequence." according to ImageIO (note the slightly different definition to Netscape 2.0 Loop Extension); 0 means repeating the animation forever
@property (nonatomic, strong, readonly) NSDictionary *delayTimesForIndexes; // Of type `NSTimeInterval` boxed in `NSNumber`s
@property (nonatomic, assign, readonly) NSUInteger frameCount; // Number of valid frames; equal to `[.delayTimes count]`

Expand Down
115 changes: 69 additions & 46 deletions TZImagePickerController/FLAnimatedImage/FLAnimatedImage.m

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions TZImagePickerController/FLAnimatedImage/FLAnimatedImageView.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Flipboard
//
// Created by Raphael Schaad on 7/8/13.
// Copyright (c) 2013-2015 Flipboard. All rights reserved.
// Copyright (c) Flipboard. All rights reserved.
//


Expand Down Expand Up @@ -31,6 +31,6 @@

// The animation runloop mode. Enables playback during scrolling by allowing timer events (i.e. animation) with NSRunLoopCommonModes.
// To keep scrolling smooth on single-core devices such as iPhone 3GS/4 and iPod Touch 4th gen, the default run loop mode is NSDefaultRunLoopMode. Otherwise, the default is NSDefaultRunLoopMode.
@property (nonatomic, copy) NSString *runLoopMode;
@property (nonatomic, copy) NSRunLoopMode runLoopMode;

@end
60 changes: 39 additions & 21 deletions TZImagePickerController/FLAnimatedImage/FLAnimatedImageView.m
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Flipboard
//
// Created by Raphael Schaad on 7/8/13.
// Copyright (c) 2013-2015 Flipboard. All rights reserved.
// Copyright (c) Flipboard. All rights reserved.
//


Expand Down Expand Up @@ -101,8 +101,16 @@ - (void)setAnimatedImage:(FLAnimatedImage *)animatedImage
{
if (![_animatedImage isEqual:animatedImage]) {
if (animatedImage) {
// Clear out the image.
super.image = nil;
if (super.image) {
// UIImageView's `setImage:` will internally call its layer's `setContentsTransform:` based on the `image.imageOrientation`.
// The `contentsTransform` will affect layer rendering rotation because the CGImage's bitmap buffer does not actually take rotation.
// However, when calling `setImage:nil`, this `contentsTransform` will not be reset to identity.
// Further animation frame will be rendered as rotated. So we must set it to the poster image to clear the previous state.
// See more here: https://github.com/Flipboard/FLAnimatedImage/issues/100
super.image = animatedImage.posterImage;
// Clear out the image.
super.image = nil;
}
// Ensure disabled highlighting; it's not supported (see `-setHighlighted:`).
super.highlighted = NO;
// UIImageView seems to bypass some accessors when calculating its intrinsic content size, so this ensures its intrinsic content size comes from the animated image.
Expand Down Expand Up @@ -213,7 +221,6 @@ - (CGSize)intrinsicContentSize
return intrinsicContentSize;
}

#pragma mark Smart Invert Colors

#pragma mark - UIImageView Method Overrides
#pragma mark Image Data
Expand Down Expand Up @@ -249,7 +256,7 @@ - (NSTimeInterval)frameDelayGreatestCommonDivisor
// Presision is set to half of the `kFLAnimatedImageDelayTimeIntervalMinimum` in order to minimize frame dropping.
const NSTimeInterval kGreatestCommonDivisorPrecision = 2.0 / kFLAnimatedImageDelayTimeIntervalMinimum;

NSArray *delays = self.animatedImage.delayTimesForIndexes.allValues;
NSArray *const delays = self.animatedImage.delayTimesForIndexes.allValues;

// Scales the frame delays by `kGreatestCommonDivisorPrecision`
// then converts it to an UInteger for in order to calculate the GCD.
Expand All @@ -259,7 +266,7 @@ - (NSTimeInterval)frameDelayGreatestCommonDivisor
}

// Reverse to scale to get the value back into seconds.
return scaledGCD / kGreatestCommonDivisorPrecision;
return (double)scaledGCD / kGreatestCommonDivisorPrecision;
}


Expand All @@ -273,7 +280,7 @@ static NSUInteger gcd(NSUInteger a, NSUInteger b)
}

while (true) {
NSUInteger remainder = a % b;
const NSUInteger remainder = a % b;
if (remainder == 0) {
return b;
}
Expand All @@ -298,18 +305,21 @@ - (void)startAnimating
[self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.runLoopMode];
}

// Note: The display link's `.frameInterval` value of 1 (default) means getting callbacks at the refresh rate of the display (~60Hz).
// Setting it to 2 divides the frame rate by 2 and hence calls back at every other display refresh.
const NSTimeInterval kDisplayRefreshRate = 60.0; // 60Hz
self.displayLink.frameInterval = MAX([self frameDelayGreatestCommonDivisor] * kDisplayRefreshRate, 1);

if (@available(iOS 10.0, *)) {
// Adjusting preferredFramesPerSecond allows us to skip unnecessary calls to displayDidRefresh: when showing GIFs
// that don't animate quickly. Use ceil to err on the side of too many FPS so we don't miss a frame transition moment.
self.displayLink.preferredFramesPerSecond = ceil(1.0 / [self frameDelayGreatestCommonDivisor]);
} else {
const NSTimeInterval kDisplayRefreshRate = 60.0; // 60Hz
self.displayLink.frameInterval = MAX([self frameDelayGreatestCommonDivisor] * kDisplayRefreshRate, 1);
}
self.displayLink.paused = NO;
} else {
[super startAnimating];
}
}

- (void)setRunLoopMode:(NSString *)runLoopMode
- (void)setRunLoopMode:(NSRunLoopMode)runLoopMode
{
if (![@[NSDefaultRunLoopMode, NSRunLoopCommonModes] containsObject:runLoopMode]) {
NSAssert(NO, @"Invalid run loop mode: %@", runLoopMode);
Expand Down Expand Up @@ -359,7 +369,7 @@ - (void)setHighlighted:(BOOL)highlighted
// Just update our cached value whenever the animated image or visibility (window, superview, hidden, alpha) is changed.
- (void)updateShouldAnimate
{
BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alpha > 0.0;
const BOOL isVisible = self.window && self.superview && ![self isHidden] && self.alpha > 0.0;
self.shouldAnimate = self.animatedImage && isVisible;
}

Expand All @@ -373,12 +383,12 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink
return;
}

NSNumber *delayTimeNumber = [self.animatedImage.delayTimesForIndexes objectForKey:@(self.currentFrameIndex)];
NSNumber *_Nullable const delayTimeNumber = [self.animatedImage.delayTimesForIndexes objectForKey:@(self.currentFrameIndex)];
// If we don't have a frame delay (e.g. corrupt frame), don't update the view but skip the playhead to the next frame (in else-block).
if (delayTimeNumber) {
NSTimeInterval delayTime = [delayTimeNumber floatValue];
if (delayTimeNumber != nil) {
const NSTimeInterval delayTime = [delayTimeNumber floatValue];
// If we have a nil image (e.g. waiting for frame), don't update the view nor playhead.
UIImage *image = [self.animatedImage imageLazilyCachedAtIndex:self.currentFrameIndex];
UIImage *_Nullable const image = [self.animatedImage imageLazilyCachedAtIndex:self.currentFrameIndex];
if (image) {
FLLog(FLLogLevelVerbose, @"Showing frame %lu for animated image: %@", (unsigned long)self.currentFrameIndex, self.animatedImage);
self.currentFrame = image;
Expand All @@ -387,7 +397,11 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink
self.needsDisplayWhenImageBecomesAvailable = NO;
}

self.accumulator += displayLink.duration * displayLink.frameInterval;
if (@available(iOS 10.0, *)) {
self.accumulator += displayLink.targetTimestamp - CACurrentMediaTime();
} else {
self.accumulator += displayLink.duration * (NSTimeInterval)displayLink.frameInterval;
}

// While-loop first inspired by & good Karma to: https://github.com/ondalabs/OLImageView/blob/master/OLImageView.m
while (self.accumulator >= delayTime) {
Expand All @@ -414,7 +428,11 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink
FLLog(FLLogLevelDebug, @"Waiting for frame %lu for animated image: %@", (unsigned long)self.currentFrameIndex, self.animatedImage);
#if defined(DEBUG) && DEBUG
if ([self.debug_delegate respondsToSelector:@selector(debug_animatedImageView:waitingForFrame:duration:)]) {
[self.debug_delegate debug_animatedImageView:self waitingForFrame:self.currentFrameIndex duration:(NSTimeInterval)displayLink.duration * displayLink.frameInterval];
if (@available(iOS 10.0, *)) {
[self.debug_delegate debug_animatedImageView:self waitingForFrame:self.currentFrameIndex duration:displayLink.targetTimestamp - CACurrentMediaTime()];
} else {
[self.debug_delegate debug_animatedImageView:self waitingForFrame:self.currentFrameIndex duration:displayLink.duration * (NSTimeInterval)displayLink.frameInterval];
}
}
#endif
}
Expand All @@ -423,7 +441,7 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink
}
}

+ (NSString *)defaultRunLoopMode
+ (NSRunLoopMode)defaultRunLoopMode
{
// Key off `activeProcessorCount` (as opposed to `processorCount`) since the system could shut down cores in certain situations.
return [NSProcessInfo processInfo].activeProcessorCount > 1 ? NSRunLoopCommonModes : NSDefaultRunLoopMode;
Expand Down
7 changes: 7 additions & 0 deletions TZImagePickerController/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict/>
</dict>
<key>CFBundleDevelopmentRegion</key>
<string>en_US</string>
<key>CFBundleExecutable</key>
Expand Down
6 changes: 5 additions & 1 deletion TZImagePickerController/LxGridViewFlowLayout.m
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,11 @@ - (void)longPressGestureRecognizerTriggerd:(UILongPressGestureRecognizer *)longP
{
if (_displayLink == nil) {
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(displayLinkTriggered:)];
_displayLink.frameInterval = 6;
if (@available(iOS 10.0, *)) {
_displayLink.preferredFramesPerSecond = 6;
} else {
_displayLink.frameInterval = 6;
}
[_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

_remainSecondsToBeginEditing = MIN_PRESS_TO_BEGIN_EDITING_DURATION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ @implementation TZGifPhotoPreviewController

- (void)viewDidLoad {
[super viewDidLoad];
self.needShowStatusBar = ![UIApplication sharedApplication].statusBarHidden;
self.needShowStatusBar = ![TZCommonTools currentStatusBarHidden];
self.view.backgroundColor = [UIColor blackColor];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (tzImagePickerVc) {
Expand All @@ -44,16 +44,11 @@ - (void)viewDidLoad {

- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
_originStatusBarStyle = [UIApplication sharedApplication].statusBarStyle;
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
_originStatusBarStyle = [TZCommonTools currentStatusBarStyle];
}

- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.needShowStatusBar) {
[UIApplication sharedApplication].statusBarHidden = NO;
}
[UIApplication sharedApplication].statusBarStyle = _originStatusBarStyle;
}

- (void)configPreviewView {
Expand Down Expand Up @@ -101,6 +96,10 @@ - (void)configBottomToolBar {
}
}

- (BOOL)prefersStatusBarHidden {
return !self.needShowStatusBar;
}

- (UIStatusBarStyle)preferredStatusBarStyle {
TZImagePickerController *tzImagePicker = (TZImagePickerController *)self.navigationController;
if (tzImagePicker && [tzImagePicker isKindOfClass:[TZImagePickerController class]]) {
Expand Down Expand Up @@ -132,12 +131,6 @@ - (void)viewDidLayoutSubviews {
- (void)signleTapAction {
_toolBar.hidden = !_toolBar.isHidden;
[self.navigationController setNavigationBarHidden:_toolBar.isHidden];
TZImagePickerController *tzImagePickerVc = (TZImagePickerController *)self.navigationController;
if (_toolBar.isHidden) {
[UIApplication sharedApplication].statusBarHidden = YES;
} else if (tzImagePickerVc.needShowStatusBar) {
[UIApplication sharedApplication].statusBarHidden = NO;
}
}

- (void)doneButtonClick {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed;
- (PHImageRequestID)getPhotoWithAsset:(PHAsset *)asset photoWidth:(CGFloat)photoWidth completion:(void (^)(UIImage *photo,NSDictionary *info,BOOL isDegraded))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler networkAccessAllowed:(BOOL)networkAccessAllowed;
- (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset completion:(void (^)(NSData *imageData, NSString *dataUTI, UIImageOrientation orientation, NSDictionary *info))completion progressHandler:(void (^)(double progress, NSError *error, BOOL *stop, NSDictionary *info))progressHandler;
//适配iOS13
- (PHImageRequestID)requestImageDataFitSystemForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options completion:(void (^_Nonnull)(NSData *_Nullable imageData, NSString *_Nullable dataUTI, UIImageOrientation orientation, NSDictionary *_Nullable info))completion;

/// Get full Image 获取原图
/// 如下两个方法completion一般会调多次,一般会先返回缩略图,再返回原图(详见方法内部使用的系统API的说明),如果info[PHImageResultIsDegradedKey] 为 YES,则表明当前返回的是缩略图,否则是原图。
Expand Down
Loading