Tanner Bennett лет назад: 6
Родитель
Сommit
6cdb626d78

+ 37 - 34
Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.m

@@ -8,57 +8,60 @@
 
 #import "FLEXImageShortcuts.h"
 #import "FLEXImagePreviewViewController.h"
+#import "FLEXShortcut.h"
 #import "FLEXAlert.h"
 
-@interface FLEXImageShortcuts ()
-@property (nonatomic, readonly) UIImage *image;
+@interface UIAlertController (FLEXImageShortcuts)
+- (void)flex_image:(UIImage *)image disSaveWithError:(NSError *)error :(void *)context;
 @end
 
 @implementation FLEXImageShortcuts
 
-#pragma mark - Internal
-
-- (UIImage *)image {
-    return self.object;
-}
-
-
 #pragma mark - Overrides
 
 + (instancetype)forObject:(UIImage *)image {
     // These additional rows will appear at the beginning of the shortcuts section.
     // The methods below are written in such a way that they will not interfere
     // with properties/etc being registered alongside these
-    return [self forObject:image additionalRows:@[@"View Image", @"Save Image"]];
+    return [self forObject:image additionalRows:@[
+        [FLEXActionShortcut title:@"View Image" subtitle:nil
+            viewer:^UIViewController *(id image) {
+                return [FLEXImagePreviewViewController forImage:image];
+            }
+            accessoryType:^UITableViewCellAccessoryType(id image) {
+                return UITableViewCellAccessoryDisclosureIndicator;
+            }
+        ],
+        [FLEXActionShortcut title:@"Save Image" subtitle:nil
+            selectionHandler:^(UIViewController *host, id image) {
+                // Present modal alerting user about saving
+                UIAlertController *alert = [FLEXAlert makeAlert:^(FLEXAlert *make) {
+                    make.title(@"Saving Image…");
+                }];
+                [host presentViewController:alert animated:YES completion:nil];
+            
+                // Save the image
+                UIImageWriteToSavedPhotosAlbum(
+                    image, alert, @selector(flex_image:disSaveWithError::), nil
+                );
+            }
+            accessoryType:^UITableViewCellAccessoryType(id image) {
+                return UITableViewCellAccessoryDisclosureIndicator;
+            }
+        ]
+    ]];
 }
 
-/// View image
-- (UIViewController *)viewControllerToPushForRow:(NSInteger)row {
-    if (row == 0) {
-        return [FLEXImagePreviewViewController forImage:self.image];
-    }
-
-    return [super viewControllerToPushForRow:row];
-}
+@end
 
-/// Save image
-- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row {
-    if (row == 1) {
-        return ^(UIViewController *host) {
-            UIImageWriteToSavedPhotosAlbum(self.image, nil, nil, nil);
-        };
-    }
 
-    return [super didSelectRowAction:row];
-}
+@implementation UIAlertController (FLEXImageShortcuts)
 
-/// "Save Image" does not need a disclosure indicator
-- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row {
-    switch (row) {
-        case 0:  return UITableViewCellAccessoryDisclosureIndicator;
-        case 1:  return UITableViewCellAccessoryNone;
-        default: return [super accessoryTypeForRow:row];
-    }
+- (void)flex_image:(UIImage *)image disSaveWithError:(NSError *)error :(void *)context {
+    self.title = @"Image Saved";
+    flex_dispatch_after(1, dispatch_get_main_queue(), ^{
+        [self dismissViewControllerAnimated:YES completion:nil];
+    });
 }
 
 @end

+ 7 - 0
Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.m

@@ -90,6 +90,13 @@
         @"currentTitle", @"currentImage", @"enabled", @"frame",
         @"superview", @"subviews"
     ]).forClass(UIButton.class);
+    
+    // UIImageView
+    self.append.properties(@[
+        @"image", @"animationImages", @"frame", @"bounds", @"center",
+        @"transform", @"alpha", @"hidden", @"clipsToBounds",
+        @"userInteractionEnabled", @"layer", @"superview", @"subviews",
+    ]).forClass(UIImageView.class);
 }
 
 @end

+ 1 - 1
Classes/Utility/Categories/NSUserDefaults+FLEX.m

@@ -17,7 +17,7 @@ NSString * const kFLEXDefaultsNetworkHostBlacklistKey = @"com.flipboard.FLEX.net
 
 #define FLEXDefaultsPathForFile(name) ({ \
     NSArray *paths = NSSearchPathForDirectoriesInDomains( \
-        NSLibraryDirectory, NSUserDomainMask, NO \
+        NSLibraryDirectory, NSUserDomainMask, YES \
     ); \
     [paths[0] stringByAppendingPathComponent:@"Preferences"]; \
 })

+ 4 - 0
Classes/Utility/FLEXMacros.h

@@ -71,4 +71,8 @@ NS_INLINE CGRect FLEXRectSetHeight(CGRect r, CGFloat height) {
     stringWithFormat:(count == 1 ? singularFormat : pluralFormat), @(count)  \
 ]
 
+#define flex_dispatch_after(nSeconds, onQueue, block) \
+    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, \
+    (int64_t)(nSeconds * NSEC_PER_SEC)), onQueue, block)
+
 #endif /* FLEXMacros_h */

+ 7 - 5
Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.m

@@ -34,21 +34,23 @@ typedef struct FLEXTypeInfo {
     /// so we need to track whenever a type contains a union
     /// so that we can clean it out of pointer types.
     BOOL containsUnion;
+    /// size can only be 0 if not void
+    BOOL isVoid;
 } FLEXTypeInfo;
 
 /// Type info for a completely unsupported type.
-static FLEXTypeInfo FLEXTypeInfoUnsupported = (FLEXTypeInfo){ -1, 0, NO, NO, NO };
+static FLEXTypeInfo FLEXTypeInfoUnsupported = (FLEXTypeInfo){ -1, 0, NO, NO, NO, NO };
 /// Type info for the void return type.
-static FLEXTypeInfo FLEXTypeInfoVoid = (FLEXTypeInfo){ 0, 0, YES, NO, NO };
+static FLEXTypeInfo FLEXTypeInfoVoid = (FLEXTypeInfo){ 0, 0, YES, NO, NO, YES };
 
 /// Builds type info for a fully or partially supported type.
 static inline FLEXTypeInfo FLEXTypeInfoMake(ssize_t size, ssize_t align, BOOL fixed) {
-    return (FLEXTypeInfo){ size, align, YES, fixed, NO };
+    return (FLEXTypeInfo){ size, align, YES, fixed, NO, NO };
 }
 
 /// Builds type info for a fully or partially supported type.
 static inline FLEXTypeInfo FLEXTypeInfoMakeU(ssize_t size, ssize_t align, BOOL fixed, BOOL hasUnion) {
-    return (FLEXTypeInfo){ size, align, YES, fixed, hasUnion };
+    return (FLEXTypeInfo){ size, align, YES, fixed, hasUnion, NO };
 }
 
 BOOL FLEXGetSizeAndAlignment(const char *type, NSUInteger *sizep, NSUInteger *alignp) {
@@ -119,7 +121,7 @@ BOOL FLEXGetSizeAndAlignment(const char *type, NSUInteger *sizep, NSUInteger *al
     while (!parser.scan.isAtEnd) {
         FLEXTypeInfo info = [parser parseNextType];
         
-        if (!info.supported || info.containsUnion || info.size == 0) {
+        if (!info.supported || info.containsUnion || (info.size == 0 && !info.isVoid)) {
             return NO;
         }
     }

+ 2 - 0
Example/FLEXample/Supporting Files/Info.plist

@@ -25,6 +25,8 @@
 		<key>NSAllowsArbitraryLoads</key>
 		<true/>
 	</dict>
+	<key>NSPhotoLibraryAddUsageDescription</key>
+	<string>NSPhotoLibraryAddUsageDescription</string>
 	<key>UIApplicationSceneManifest</key>
 	<dict>
 		<key>UIApplicationSupportsMultipleScenes</key>