Compare commits

..

86 Commits

Author SHA1 Message Date
Tanner Bennett 258ec8697b Bump version 2021-03-30 14:20:02 -05:00
Tanner Bennett 8f9a6e88ec Fix toolbar appearing when empty 2021-03-30 14:20:02 -05:00
Tanner Bennett c37270e6ac Add shortcuts for NSString and NSData 2021-03-30 14:20:02 -05:00
Tanner Bennett ce10d45c29 Fix "hide likely private methods" behavior
Hide relevant private properties too, also class properties and methods
2021-03-30 14:20:02 -05:00
Tanner Bennett b2716c4b2e Catch potential exceptions thrown from descriptions 2021-03-30 14:20:02 -05:00
Tanner Bennett ab135ba94e Remove uninclusive terms
Blacklist → exclude[d] / denylist
Whitelist → allow[ed] / unexcluded
2021-03-30 14:20:02 -05:00
Tanner Bennett bcc04f4113 Make FLEXMacros.h private 2021-03-30 14:20:02 -05:00
Tanner Bennett 470b3fa3b3 Add tintColor as real property 2021-03-30 14:20:02 -05:00
Tanner Bennett e84dfeae5c Fix object explorer class pan gesture… again… 2021-03-30 14:20:02 -05:00
Tanner Bennett 44e86e59b7 Fix Xcode 12 compile errors 2021-03-30 14:20:02 -05:00
Tanner Bennett ac6d9cfa3f Misc refactoring 2021-03-30 14:20:02 -05:00
Tanner Bennett 1a59711760 Fix a crash, add some missing nullabilities 2021-03-30 14:20:01 -05:00
Tanner Bennett b60ce7a057 Add UIAlertController shortcuts
Fix alert controller
2021-03-30 14:20:01 -05:00
Tanner Bennett b4ac210bef Use likely ivar to determine matching property 2021-03-29 13:55:52 -05:00
Tanner Bennett 9360c58975 Add likely ivar data to FLEXProperty 2021-03-29 13:55:52 -05:00
Tanner Bennett 43d9a460ce Make the keyboard seem to appear faster
On screens where the keyboard is set to appear right away, make it appear faster—or at least, make it look like it appears faster…

Also add a property to make the search bar appear initially instead of duplicating becomeFirstResponder code across several classes
2021-03-29 13:55:51 -05:00
ray 15fee5a8a5 Fix keychain viewer crash (#521) 2021-03-23 10:36:29 -05:00
Alexey Salangin fad038392b Don't show toolbar when tapping on a nav bar button (#517) 2021-03-11 13:45:23 -06:00
Tanner Bennett 558d65a0b0 Update license 2021-02-02 14:18:09 -06:00
Tanner Bennett 077fca36c0 Bump deployment targets (oops?) 2021-01-27 23:24:39 -06:00
Tanner Bennett 947769f6f9 Bump version 2021-01-27 17:10:26 -06:00
Tanner Bennett 7c480c5faf Mention tvOS fork in README 2021-01-27 17:09:41 -06:00
Tanner Bennett fa6c72cb08 Fix memory leak 2021-01-27 16:49:10 -06:00
Tanner Bennett 9af2926ec1 Use weakify/strongify throughout project 2021-01-26 12:46:53 -06:00
Tanner Bennett 366a8266bd Add weakify/strongify macros 2021-01-26 12:46:53 -06:00
Tanner Bennett 713fbac54a Move 't' simulator shortcut to the example project
This demonstrates how to register a shortcut from a project with the new pubilc APIs for presenting tools.

I put it in the commit list screen because I didn't feel like rewriting it in Swift.
2021-01-26 12:46:53 -06:00
Tanner Bennett 8198fba689 Add public API to dismiss/present FLEX tools
This API will allow you to present a tool in front of the FLEX toolbar and will automatically dismiss any existing FLEX tool
2021-01-26 12:46:53 -06:00
Tanner Bennett 20e14a36c9 Add -[NSMutableArray flex_filter:] 2021-01-26 11:18:43 -06:00
Tanner Bennett 176e98518d Add context menu item to view references to object 2021-01-20 17:00:37 -06:00
Tanner Bennett 31440056c1 Add option to hide potentially private methods 2021-01-20 17:00:10 -06:00
Tanner Bennett 6c7b39ed03 Fix object explorer swipe gesture precedence 2021-01-20 15:31:25 -06:00
Tanner Bennett 96989f7e0c Refactor FLEXample's AppDelegate.swift 2021-01-20 15:08:06 -06:00
Tanner Bennett 22a23b3b12 Add the Person class back to the example project 2021-01-20 14:59:09 -06:00
Tanner Bennett 90a855a289 Allow registration of global entries with actions
This was previously a private API
2021-01-20 14:37:44 -06:00
matrush fd67373995 Revise object reference section titles logic 2021-01-20 14:37:13 -06:00
Tanner Bennett 3b5e095f74 Add some tests, fix some tests
- Test safeClassNameForObject:
- Test safeObject:respondsToSelector:
- Fix testAssumptionsAboutClasses: which was incorrectly written
2020-12-30 20:06:49 -06:00
Tanner Bennett c7850df186 Add safeClassNameForObject: and use it 2020-12-30 20:06:49 -06:00
Tanner Bennett 6bbcc55cf6 Improve safeObject:respondsToSelector:
The old code assumes the object at least responds to respondsToSelector: which may not always be true. I also I think the old code was not quite correct for all cases anyway.

Using the runtime functions ensures no methods are ever called on the object, and properly handles metaclass objects, in theory.
2020-12-30 20:06:49 -06:00
Tanner Bennett e63ea4bbff Group FLEX objects together in the object refs list 2020-12-30 20:06:49 -06:00
Tanner Bennett 5a760fb1ac Update issue templates 2020-12-30 20:06:49 -06:00
Tanner Bennett e63f2ee3ad Prefix some categories, fix #496 2020-12-30 20:06:49 -06:00
Tanner Bennett 46c6dcb7e6 Fix bug introduced in cb2e0789 2020-12-30 17:31:37 -06:00
Alexey Salangin bf42bbe27b Fix bug with navbar tap gesture
Tap gesture in FLEXNavigationController's navigation bar causes buttons to reportedly become unresponsive on iOS 11 and 12 unless `cancelsTouchesInView` is turned off
2020-12-30 15:27:04 -08:00
Tanner Bennett e89fec4b2d Bump version 2020-12-17 01:57:25 -06:00
Tanner Bennett 715bb92929 Add confirm dialog for clearing the keychain 2020-12-17 01:35:03 -06:00
Tanner Bennett 109074f98e Show service AND account in keychain rows 2020-12-17 01:34:44 -06:00
Tanner Bennett 45fbdb7914 Move keychain buttons to toolbar 2020-12-17 01:34:33 -06:00
Tanner Bennett cb2e0789d8 Fix several memory leaks, fix #483
Also move a bunch of globals related to FLEXShortcutsFactory into ivars of a FLEXShortcutsFactory singleton so that it is easier to trace the origin of the global storage of FLEX[Property|Ivar|Method] objects in a memory graph
2020-12-17 01:17:40 -06:00
vvveiii de1ca783b6 Fix flex_copy: crash when object is nil 2020-12-16 22:30:11 -08:00
vvveiii 3a9c24b784 Add missing else for flex_copy method 2020-12-16 22:30:11 -08:00
Tanner Bennett b57a333fc9 Fix #491, close #473
Remove (most) uses of +[NSString stringWithCString:encoding:]
2020-12-17 00:20:17 -06:00
matrush 288bf1343e Add ability to toggle bg color for image previews
Also fix availability warning
2020-12-15 16:35:27 -08:00
matrush a0b1caed54 Use UITableViewCellAccessoryNone instead of 0 in FLEX[Layer/View]Shortcuts 2020-12-14 18:38:04 -08:00
Tanner Bennett 9282c61183 Allow scrubbing between selected views
Instead of a singular swipe gesture to navigate between views in the view hierarchy at the tap point, we can now pan or drag along that same area to "srub" the hierarchy.
2020-12-14 18:36:44 -06:00
Tanner Bennett ee6677ee08 Add GUI shortcut for initializeWebKitLegacy
We call initializeWebKitLegacy automatically before you search all bundles just to be safe (since touching some classes before WebKit is initialized will initialize it on a thread other than the main thread), but sometimes you can encounter this crash without searching through all bundles, of course.

In this case, you can now long press on the navigation bar to call initializeWebKitLegacy
2020-12-14 17:10:48 -06:00
Tanner Bennett 3276eb3516 Automatically activate search bar in heap explorer
2f952c38 apparently didn't do this, oops
2020-12-14 17:10:48 -06:00
Chaoshuai Lü a3fa7bbadc Fix view/controller preview image issue (#493) 2020-12-14 16:08:58 -06:00
matrush 637074b354 Use id<NSCopying> as key instead of Class<NSCopying> in FLEXObjectExplorerFactory 2020-12-01 16:56:08 -08:00
Tanner Bennett 547bfbaec0 Disallow preview of views with no rect 2020-11-02 20:42:10 -06:00
Tanner Bennett 4e1fcf4682 Bump version, 4.2.2 2020-11-02 19:36:15 -06:00
Tanner Bennett 4d50fd2020 Revert "Use NSString as key …" in d7786449
We NEED to use the class as a key, because you cannot differentiate a class's name from the metaclass's name.
2020-11-02 19:36:15 -06:00
Tanner Bennett 2c510c8ca1 Fix log timer in example app not firing 2020-11-02 17:45:21 -06:00
Tanner Bennett 8283e2a8e7 Fix #415, restore ability to copy log messages 2020-11-02 17:32:29 -06:00
Tanner Bennett 3f82631a95 Fix bug introduced in 4.2.0, unable to edit members
Oopsie
2020-11-02 17:03:37 -06:00
matrush d77864494d Use NSString as key instead of Class<NSCopying> in FLEXObjectExplorerFactory 2020-11-02 16:58:59 -06:00
matrush c5ed6d4ece Add void to function definition of FLEXConstructorsShouldRun 2020-11-02 16:58:59 -06:00
matrush 9412f6eccf Add a clear global entries method for FLEXManager 2020-11-02 16:58:59 -06:00
Tanner Bennett d9aa102e77 Bump version 2020-10-23 16:42:44 -05:00
Oleg 6f80476135 Fix crash on flex_withTintColor (#476) 2020-10-23 16:23:39 -05:00
Tanner Bennett e18a854a9f Bump version, close #465 #466 2020-10-22 18:18:26 -05:00
Tanner Bennett 0d676e2504 Add FLEX_DISABLE_CTORS, close #471 2020-10-22 18:16:18 -05:00
Tanner Bennett fcca09e74a Fix #428, not scrolling to selected view 2020-10-22 17:57:25 -05:00
Tanner Bennett 107e44a399 Fix #410, prefix all categories 2020-10-22 17:57:21 -05:00
Tanner Bennett e79a3db255 Fix #426
Move explicit FLEXCollection protocol conformances to the .m file to prevent protocol methods from overriding the methods in their headers
2020-10-21 22:55:32 -05:00
Tanner Bennett bec9ffd981 Allow inspecting non-NSObject classes 2020-10-21 21:02:49 -05:00
Tanner Bennett d4070ed9b7 Reverse view snapshot slider ends, fix #429 2020-10-21 21:02:49 -05:00
Tanner Bennett 01e4af47e2 Fix #433, refresh explorer after edits 2020-10-21 21:02:49 -05:00
Tanner Bennett 220af5c350 Table sections can update themselves 2020-10-21 21:02:49 -05:00
Tanner Bennett 15fd16d395 FLEXample project Xcode 12 update
Fix warning in FLEXample
2020-10-21 21:02:49 -05:00
Tanner Bennett af87ea14e0 Update copyright 2020-10-20 18:18:47 -05:00
Tanner Bennett 5c8b334a84 Fix #450: broken search on NSUserDefaults 2020-10-18 17:44:04 -05:00
Tanner Bennett d3c3c61ab1 FLEXMethod.imagePath should use the method's IMP
We can already tell which image the class comes from, and that is usually the same as the original method implementation. What is more useful to know is the image of the _current_ implementation.
2020-10-18 17:17:06 -05:00
Tanner Bennett c28952f6e9 Silence new weird documentation warning… 2020-10-18 17:17:06 -05:00
Tanner Bennett aaf7ffec85 Commit FLEXTests scheme 2020-10-18 17:17:06 -05:00
Tanner Bennett 3ef55eac62 Xcode 12 upgrade check for main scheme 2020-10-18 17:17:06 -05:00
Tanner Bennett 515806e194 Add FLEX_EXIT_IF_NO_CTORS, fix #470 2020-10-18 17:17:06 -05:00
296 changed files with 1979 additions and 1054 deletions
+27
View File
@@ -0,0 +1,27 @@
---
name: Bug report
about: Report a bug in FLEX
title: ''
labels: bug
assignees: ''
---
### Environment
- Platform+version: **iOS 14** <!--- Change to match your platform and version -->
- FLEX version: **9.9.9** <!--- Change to the version of FLEX you're using -->
<!--- FLEXing / libFLEX users: please include FLEXing and libFLEX versions separately -->
### Bug Report
Here, you can provide a description of the bug. Some tips:
- Please do not paste an entire crash log. Upload the crash log to something like [ghostbin.co](https://ghostbin.co/) or another paste service. Alternatively, you can cut out the relevant stack trace and paste that inside a ` ```code block``` `
- If the bug is more complex than "this button is broken" or a crash, consider including a sample project. For example, if your app's requests aren't showing up in the network history page.
- Providing steps to reproduce is always helpful!
- If you want to include a screenshot or GIF, consider modifying the default markdown for uploaded images to use this code to make the image smaller on desktop:
```
<img width="50%" src=your-image-url >
```
This template is a suggestion. You may format your issue however you want, but generally you should at least include your iOS version and FLEX version.
+10
View File
@@ -0,0 +1,10 @@
---
name: Feature request
about: Suggest a new feature for FLEX
title: ''
labels: enhancement
assignees: ''
---
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/9/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/9/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
@@ -111,9 +111,18 @@
- (void)setAllSections:(NSArray<FLEXTableViewSection *> *)allSections {
_allSections = allSections.copy;
// Only display nonempty sections
self.sections = self.nonemptySections;
}
- (void)setSections:(NSArray<FLEXTableViewSection *> *)sections {
// Allow sections to reload a portion of the table view at will
[sections enumerateObjectsUsingBlock:^(FLEXTableViewSection *s, NSUInteger idx, BOOL *stop) {
[s setTable:self.tableView section:idx];
}];
_sections = sections.copy;
}
#pragma mark - UITableViewDataSource
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 1/30/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 1/30/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXNavigationController.h"
@@ -20,6 +20,7 @@
@interface FLEXNavigationController ()
@property (nonatomic, readonly) BOOL toolbarWasHidden;
@property (nonatomic) BOOL waitingToAddTab;
@property (nonatomic, readonly) BOOL canShowToolbar;
@property (nonatomic) BOOL didSetupPendingDismissButtons;
@property (nonatomic) UISwipeGestureRecognizer *navigationBarSwipeGesture;
@end
@@ -36,10 +37,13 @@
self.waitingToAddTab = YES;
// Add gesture to reveal toolbar if hidden
self.navigationBar.userInteractionEnabled = YES;
[self.navigationBar addGestureRecognizer:[[UITapGestureRecognizer alloc]
UITapGestureRecognizer *navbarTapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(handleNavigationBarTap:)
]];
];
// Don't cancel touches to work around bug on versions of iOS prior to 13
navbarTapGesture.cancelsTouchesInView = NO;
[self.navigationBar addGestureRecognizer:navbarTapGesture];
// Add gesture to dismiss if not presented with a sheet style
if (@available(iOS 13, *)) {
@@ -96,6 +100,10 @@
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
- (BOOL)canShowToolbar {
return self.topViewController.toolbarItems.count;
}
- (void)addNavigationBarItemsToViewController:(UINavigationItem *)navigationItem {
if (!self.presentingViewController) {
return;
@@ -145,8 +153,15 @@
}
- (void)handleNavigationBarTap:(UIGestureRecognizer *)sender {
// Don't reveal the toolbar if we were just tapping a button
CGPoint location = [sender locationInView:self.navigationBar];
UIView *hitView = [self.navigationBar hitTest:location withEvent:nil];
if ([hitView isKindOfClass:[UIControl class]]) {
return;
}
if (sender.state == UIGestureRecognizerStateRecognized) {
if (self.toolbarHidden) {
if (self.toolbarHidden && self.canShowToolbar) {
[self setToolbarHidden:NO animated:YES];
}
}
@@ -162,7 +177,7 @@
- (void)_gestureRecognizedInteractiveHide:(UIPanGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateRecognized) {
BOOL show = self.topViewController.toolbarItems.count;
BOOL show = self.canShowToolbar;
CGFloat yTranslation = [sender translationInView:self.view].y;
CGFloat yVelocity = [sender velocityInView:self.view].y;
if (yVelocity > 2000) {
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 7/5/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -67,6 +67,10 @@ extern CGFloat const kFLEXDebounceForExpensiveIO;
/// Setting this to YES will make the search bar appear whenever the view appears.
/// Otherwise, iOS will only show the search bar when you scroll up.
@property (nonatomic) BOOL showSearchBarInitially;
/// Defaults to NO.
///
/// Setting this to YES will make the search bar activate whenever the view appears.
@property (nonatomic) BOOL activatesSearchBarAutomatically;
/// nil unless showsSearchBar is set to YES.
///
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 7/5/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -124,18 +124,15 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
_showsCarousel = showsCarousel;
if (showsCarousel) {
_carousel = ({
__weak __typeof(self) weakSelf = self;
_carousel = ({ weakify(self)
FLEXScopeCarousel *carousel = [FLEXScopeCarousel new];
carousel.selectedIndexChangedAction = ^(NSInteger idx) {
__typeof(self) self = weakSelf;
carousel.selectedIndexChangedAction = ^(NSInteger idx) { strongify(self);
[self.searchDelegate updateSearchResults:self.searchText];
};
// UITableView won't update the header size unless you reset the header view
[carousel registerBlockForDynamicTypeChanges:^(FLEXScopeCarousel *carousel) {
__typeof(self) self = weakSelf;
[carousel registerBlockForDynamicTypeChanges:^(FLEXScopeCarousel *_) { strongify(self);
[self layoutTableHeaderIfNeeded];
}];
@@ -224,10 +221,10 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
_shareToolbarItem = FLEXBarButtonItemSystem(Action, self, @selector(shareButtonPressed:));
_bookmarksToolbarItem = [UIBarButtonItem
itemWithImage:FLEXResources.bookmarksIcon target:self action:@selector(showBookmarks)
flex_itemWithImage:FLEXResources.bookmarksIcon target:self action:@selector(showBookmarks)
];
_openTabsToolbarItem = [UIBarButtonItem
itemWithImage:FLEXResources.openTabsIcon target:self action:@selector(showTabSwitcher)
flex_itemWithImage:FLEXResources.openTabsIcon target:self action:@selector(showTabSwitcher)
];
self.leftmostToolbarItem = UIBarButtonItem.flex_fixedSpace;
@@ -241,7 +238,7 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
// Toolbar
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbarHidden = self.toolbarItems.count > 0;
self.navigationController.hidesBarsOnSwipe = YES;
// On iOS 13, the root view controller shows it's search bar no matter what.
@@ -259,12 +256,17 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
// When going back, make the search bar reappear instead of hiding
if (@available(iOS 11.0, *)) {
// When going back, make the search bar reappear instead of hiding
if ((self.pinSearchBar || self.showSearchBarInitially) && !self.didInitiallyRevealSearchBar) {
self.navigationItem.hidesSearchBarWhenScrolling = NO;
}
}
// Make the keyboard seem to appear faster
if (self.activatesSearchBarAutomatically) {
[self makeKeyboardAppearNow];
}
[self setupToolbarItems];
}
@@ -286,6 +288,17 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
}];
}
}
if (self.activatesSearchBarAutomatically) {
// Keyboard has appeared, now we call this as we soon present our search bar
[self removeDummyTextField];
// Activate the search bar
dispatch_async(dispatch_get_main_queue(), ^{
// This doesn't work unless it's wrapped in this dispatch_async call
[self.searchController.searchBar becomeFirstResponder];
});
}
// We only want to reveal the search bar when the view controller first appears.
self.didInitiallyRevealSearchBar = YES;
@@ -525,6 +538,30 @@ CGFloat const kFLEXDebounceForExpensiveIO = 0.5;
#pragma mark - Search Bar
#pragma mark Faster keyboard
static UITextField *kDummyTextField = nil;
/// Make the keyboard appear instantly. We use this to make the
/// keyboard appear faster when the search bar is set to appear initially.
/// You must call \c -removeDummyTextField before your search bar is to appear.
- (void)makeKeyboardAppearNow {
if (!kDummyTextField) {
kDummyTextField = [UITextField new];
kDummyTextField.autocorrectionType = UITextAutocorrectionTypeNo;
}
kDummyTextField.inputAccessoryView = self.searchController.searchBar.inputAccessoryView;
[UIApplication.sharedApplication.keyWindow addSubview:kDummyTextField];
[kDummyTextField becomeFirstResponder];
}
- (void)removeDummyTextField {
if (kDummyTextField.superview) {
[kDummyTextField removeFromSuperview];
}
}
#pragma mark UISearchResultsUpdating
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 9/25/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewSection.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 9/25/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSingleRowSection.h"
+16 -2
View File
@@ -3,11 +3,10 @@
// FLEX
//
// Created by Tanner on 1/29/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "FLEXMacros.h"
#import "NSArray+FLEX.h"
@class FLEXTableView;
@@ -24,6 +23,10 @@ NS_ASSUME_NONNULL_BEGIN
@protected
/// Unused by default, use if you want
NSString *_title;
@private
__weak UITableView *_tableView;
NSInteger _sectionIndex;
}
#pragma mark - Data
@@ -57,6 +60,17 @@ NS_ASSUME_NONNULL_BEGIN
/// \c setFilterText: to call \c super and call \c reloadData.
- (void)reloadData;
/// Like \c reloadData, but optionally reloads the table view section
/// associated with this section object, if any. Do not override.
/// Do not call outside of the main thread.
- (void)reloadData:(BOOL)updateTable;
/// Provide a table view and section index to allow the section to efficiently reload
/// its own section of the table when something changes it. The table reference is
/// held weakly, and subclasses cannot access it or the index. Call this method again
/// if the section numbers have changed since you last called it.
- (void)setTable:(UITableView *)tableView section:(NSInteger)index;
#pragma mark - Row Selection
/// Whether the given row should be selectable, such as if tapping the cell
+16 -3
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 1/29/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewSection.h"
@@ -22,6 +22,19 @@
- (void)reloadData { }
- (void)reloadData:(BOOL)updateTable {
[self reloadData];
if (updateTable) {
NSIndexSet *index = [NSIndexSet indexSetWithIndex:_sectionIndex];
[_tableView reloadSections:index withRowAnimation:UITableViewRowAnimationNone];
}
}
- (void)setTable:(UITableView *)tableView section:(NSInteger)index {
_tableView = tableView;
_sectionIndex = index;
}
- (NSDictionary<NSString *,Class> *)cellRegistrationMapping {
return nil;
}
@@ -99,13 +112,13 @@
}
UIMenu *copyMenu = [UIMenu
inlineMenuWithTitle:@"Copy…"
flex_inlineMenuWithTitle:@"Copy…"
image:copyIcon
children:actions
];
if (collapseMenu) {
return @[[copyMenu collapsed]];
return @[[copyMenu flex_collapsed]];
} else {
return @[copyMenu];
}
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCarouselCell.h"
@@ -77,7 +77,7 @@
self.selectionIndicatorStripe.translatesAutoresizingMaskIntoConstraints = NO;
UIView *superview = self.contentView;
[self.titleLabel pinEdgesToSuperviewWithInsets:UIEdgeInsetsMake(10, 15, 8 + stripeHeight, 15)];
[self.titleLabel flex_pinEdgesToSuperviewWithInsets:UIEdgeInsetsMake(10, 15, 8 + stripeHeight, 15)];
[self.selectionIndicatorStripe.leadingAnchor constraintEqualToAnchor:superview.leadingAnchor].active = YES;
[self.selectionIndicatorStripe.bottomAnchor constraintEqualToAnchor:superview.bottomAnchor].active = YES;
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -3,12 +3,13 @@
// FLEX
//
// Created by Tanner Bennett on 7/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXScopeCarousel.h"
#import "FLEXCarouselCell.h"
#import "FLEXColor.h"
#import "FLEXMacros.h"
#import "UIView+FLEX_Layout.h"
const CGFloat kCarouselItemSpacing = 0;
@@ -72,15 +73,14 @@ NSString * const kCarouselCellReuseIdentifier = @"kCarouselCellReuseIdentifier";
self.sizingCell.title = @"NSObject";
// Dynamic type
__weak __typeof(self) weakSelf = self;
weakify(self);
_dynamicTypeObserver = [NSNotificationCenter.defaultCenter
addObserverForName:UIContentSizeCategoryDidChangeNotification
object:nil queue:nil usingBlock:^(NSNotification *note) {
object:nil queue:nil usingBlock:^(NSNotification *note) { strongify(self)
[self.collectionView setNeedsLayout];
[self setNeedsUpdateConstraints];
// Notify observers
__typeof(self) self = weakSelf;
for (void (^block)(FLEXScopeCarousel *) in self.dynamicTypeHandlers) {
block(self);
}
@@ -118,7 +118,7 @@ NSString * const kCarouselCellReuseIdentifier = @"kCarouselCellReuseIdentifier";
- (void)updateConstraints {
if (!self.constraintsInstalled) {
self.collectionView.translatesAutoresizingMaskIntoConstraints = NO;
[self.collectionView pinEdgesToSuperview];
[self.collectionView flex_pinEdgesToSuperview];
self.constraintsInstalled = YES;
}
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 12/27/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXMultilineTableViewCell.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 12/27/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCodeFontCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 1/23/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 1/23/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXKeyValueTableViewCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Ryan Olson on 2/13/15.
// Copyright (c) 2015 f. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Ryan Olson on 2/13/15.
// Copyright (c) 2015 f. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXMultilineTableViewCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSubtitleTableViewCell.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewCell.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 4/17/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/30/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/30/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputColorView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Daniel Rodriguez Troitino on 2/14/15.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Daniel Rodriguez Troitino on 2/14/15.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputDateView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputFontView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/18/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/18/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputNotSupportedView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/15/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/15/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputNumberView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/15/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/15/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputObjectView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputTextView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputStringView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputStructView.h"
@@ -11,7 +11,7 @@
#import "FLEXRuntimeUtility.h"
#import "FLEXTypeEncodingParser.h"
@interface FLEXArgumentInputStructView () <FLEXArgumentInputViewDelegate>
@interface FLEXArgumentInputStructView ()
@property (nonatomic) NSArray<FLEXArgumentInputView *> *argumentInputViews;
@@ -30,11 +30,8 @@
NSUInteger fieldIndex,
NSUInteger fieldOffset) {
FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory
argumentInputViewForTypeEncoding:fieldTypeEncoding
];
FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:fieldTypeEncoding];
inputView.targetSize = FLEXArgumentInputViewSizeSmall;
inputView.delegate = self;
if (fieldIndex < customTitles.count) {
inputView.title = customTitles[fieldIndex];
@@ -128,45 +125,15 @@
return boxedStruct;
}
- (FLEXArgumentInputView *)firstResponderInputView {
- (BOOL)inputViewIsFirstResponder {
BOOL isFirstResponder = NO;
for (FLEXArgumentInputView *inputView in self.argumentInputViews) {
if ([inputView inputViewIsFirstResponder]) {
return inputView;
isFirstResponder = YES;
break;
}
}
return nil;
}
- (BOOL)resignFirstResponder {
FLEXArgumentInputView *responder = [self firstResponderInputView];
if (responder) {
return [responder resignFirstResponder];
} else {
return [super resignFirstResponder];
}
}
#pragma mark - FLEXArgumentInputViewDelegate
- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)inputView {
// Nothing to see here
}
- (void)argumentInputViewWantsNextAsFirstResponder:(FLEXArgumentInputView *)inputView {
if (self.argumentInputViews.lastObject == inputView) {
// If this is our last or only input view,
// notify the delegate or dismiss the keyboard
if (self.delegate) {
[self.delegate argumentInputViewWantsNextAsFirstResponder:self];
} else {
[inputView resignFirstResponder];
}
} else {
NSInteger idx = [self.argumentInputViews indexOfObject:inputView];
[self.argumentInputViews[idx+1] becomeFirstResponder];
}
return isFirstResponder;
}
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputSwitchView.h"
@@ -8,15 +8,11 @@
#import "FLEXArgumentInputView.h"
NS_ASSUME_NONNULL_BEGIN
@interface FLEXArgumentInputTextView : FLEXArgumentInputView <UITextViewDelegate>
// For subclass eyes only
@property (nonatomic, readonly) UITextView *inputTextView;
@property (nonatomic, nullable) NSString *inputPlaceholderText;
@property (nonatomic) NSString *inputPlaceholderText;
@end
NS_ASSUME_NONNULL_END
@@ -31,7 +31,7 @@
self.inputTextView.autocapitalizationType = UITextAutocapitalizationTypeNone;
self.inputTextView.autocorrectionType = UITextAutocorrectionTypeNo;
self.inputTextView.delegate = self;
self.inputAccessoryView = [self createToolBar];
self.inputTextView.inputAccessoryView = [self createToolBar];
if (@available(iOS 11, *)) {
[self.inputTextView.layer setValue:@YES forKey:@"continuousCorners"];
} else {
@@ -51,14 +51,6 @@
return self;
}
- (UIToolbar *)inputAccessoryView {
return (id)self.inputTextView.inputAccessoryView;
}
- (void)setInputAccessoryView:(UIToolbar *)inputAccessoryView {
self.inputTextView.inputAccessoryView = inputAccessoryView;
}
#pragma mark - Private
- (UIToolbar *)createToolBar {
@@ -70,7 +62,7 @@
];
UIBarButtonItem *pasteItem = [[UIBarButtonItem alloc]
initWithTitle:@"Paste" style:UIBarButtonItemStyleDone
target:self action:@selector(paste:)
target:self.inputTextView action:@selector(paste:)
];
UIBarButtonItem *doneItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemDone
@@ -99,16 +91,6 @@
return self.placeholderLabel.text;
}
- (void)paste:(id)sender {
[self.inputTextView paste:sender];
if (self.delegate) {
[self.delegate argumentInputViewWantsNextAsFirstResponder:self];
} else {
[self.inputTextView resignFirstResponder];
}
}
#pragma mark - Superclass Overrides
@@ -116,18 +98,6 @@
return self.inputTextView.isFirstResponder;
}
- (BOOL)becomeFirstResponder {
return [self.inputTextView becomeFirstResponder];
}
- (BOOL)resignFirstResponder {
if (self.inputViewIsFirstResponder) {
return self.inputTextView.resignFirstResponder;
} else {
return [super resignFirstResponder];
}
}
#pragma mark - Layout and Sizing
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/30/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -19,8 +19,6 @@ typedef NS_ENUM(NSUInteger, FLEXArgumentInputViewSize) {
@protocol FLEXArgumentInputViewDelegate;
NS_ASSUME_NONNULL_BEGIN
@interface FLEXArgumentInputView : UIView
- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding;
@@ -33,25 +31,23 @@ NS_ASSUME_NONNULL_BEGIN
/// Primitive types and structs should/will be boxed in NSValue containers.
/// Concrete subclasses should override both the setter and getter for this property.
/// Subclasses can call super.inputValue to access a backing store for the value.
@property (nonatomic, nullable) id inputValue;
@property (nonatomic) id inputValue;
/// Setting this value to large will make some argument input views increase the size of their input field(s).
/// Useful to increase the use of space if there is only one input view on screen (i.e. for property and ivar editing).
@property (nonatomic) FLEXArgumentInputViewSize targetSize;
/// Users of the input view can get delegate callbacks for incremental changes in user input.
@property (nonatomic, weak, nullable) id <FLEXArgumentInputViewDelegate> delegate;
@property (nonatomic, weak) id <FLEXArgumentInputViewDelegate> delegate;
// Subclasses can override
@property (nonatomic, nullable) UIToolbar *inputAccessoryView;
/// If the input view has one or more text views, returns YES when one of them is focused.
@property (nonatomic, readonly) BOOL inputViewIsFirstResponder;
/// For subclasses to indicate that they can handle editing a field the give type and value.
/// Used by FLEXArgumentInputViewFactory to create appropriate input views.
+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(nullable id)value;
+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value;
// For subclass eyes only
@@ -63,11 +59,6 @@ NS_ASSUME_NONNULL_BEGIN
@protocol FLEXArgumentInputViewDelegate <NSObject>
//- (void)
- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView;
- (void)argumentInputViewWantsNextAsFirstResponder:(FLEXArgumentInputView *)argumentInputView;
@end
NS_ASSUME_NONNULL_END
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/30/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
@@ -3,15 +3,19 @@
// Flipboard
//
// Created by Ryan Olson on 5/23/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorViewController.h"
@interface FLEXDefaultEditorViewController : FLEXFieldEditorViewController
NS_ASSUME_NONNULL_BEGIN
- (id)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key;
@interface FLEXDefaultEditorViewController : FLEXVariableEditorViewController
+ (BOOL)canEditDefaultWithValue:(id)currentValue;
+ (instancetype)target:(NSUserDefaults *)defaults key:(NSString *)key commitHandler:(void(^_Nullable)())onCommit;
+ (BOOL)canEditDefaultWithValue:(nullable id)currentValue;
@end
NS_ASSUME_NONNULL_END
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/23/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXDefaultEditorViewController.h"
@@ -15,23 +15,24 @@
@interface FLEXDefaultEditorViewController ()
@property (nonatomic, readonly) NSUserDefaults *defaults;
@property (nonatomic) NSString *key;
@property (nonatomic, readonly) NSString *key;
@end
@implementation FLEXDefaultEditorViewController
- (id)initWithDefaults:(NSUserDefaults *)defaults key:(NSString *)key {
self = [super initWithTarget:defaults];
if (self) {
self.key = key;
self.title = @"Edit Default";
}
return self;
+ (instancetype)target:(NSUserDefaults *)defaults key:(NSString *)key commitHandler:(void(^_Nullable)())onCommit {
FLEXDefaultEditorViewController *editor = [self target:defaults data:key commitHandler:onCommit];
editor.title = @"Edit Default";
return editor;
}
- (NSUserDefaults *)defaults {
return [self.target isKindOfClass:[NSUserDefaults class]] ? self.target : nil;
return [_target isKindOfClass:[NSUserDefaults class]] ? _target : nil;
}
- (NSString *)key {
return _data;
}
- (void)viewDidLoad {
@@ -46,13 +47,10 @@
];
inputView.backgroundColor = self.view.backgroundColor;
inputView.inputValue = currentValue;
inputView.delegate = self;
self.fieldEditorView.argumentInputViews = @[inputView];
}
- (void)actionButtonPressed:(id)sender {
[super actionButtonPressed:sender];
id value = self.firstInputView.inputValue;
if (value) {
[self.defaults setObject:value forKey:self.key];
@@ -60,14 +58,16 @@
[self.defaults removeObjectForKey:self.key];
}
[self.defaults synchronize];
self.firstInputView.inputValue = [self.defaults objectForKey:self.key];
}
- (void)getterButtonPressed:(id)sender {
[super getterButtonPressed:sender];
id returnedObject = [self.defaults objectForKey:self.key];
[self exploreObjectOrPopViewController:returnedObject];
// Dismiss keyboard and handle committed changes
[super actionButtonPressed:sender];
// Go back after setting, but not for switches.
if (sender) {
[self.navigationController popViewControllerAnimated:YES];
} else {
self.firstInputView.inputValue = [self.defaults objectForKey:self.key];
}
}
+ (BOOL)canEditDefaultWithValue:(id)currentValue {
+1 -1
View File
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorView.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 11/22/18.
// Copyright © 2018 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXVariableEditorViewController.h"
@@ -15,9 +15,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface FLEXFieldEditorViewController : FLEXVariableEditorViewController
/// @return nil if the property is readonly or if the type is unsupported
+ (nullable instancetype)target:(id)target property:(FLEXProperty *)property;
+ (nullable instancetype)target:(id)target property:(FLEXProperty *)property commitHandler:(void(^_Nullable)())onCommit;
/// @return nil if the ivar type is unsupported
+ (nullable instancetype)target:(id)target ivar:(FLEXIvar *)ivar;
+ (nullable instancetype)target:(id)target ivar:(FLEXIvar *)ivar commitHandler:(void(^_Nullable)())onCommit;
/// Subclasses can change the button title via the \c title property
@property (nonatomic, readonly) UIBarButtonItem *getterButton;
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 11/22/18.
// Copyright © 2018 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFieldEditorViewController.h"
@@ -30,20 +30,20 @@
#pragma mark - Initialization
+ (instancetype)target:(id)target property:(FLEXProperty *)property {
+ (instancetype)target:(id)target property:(nonnull FLEXProperty *)property commitHandler:(void(^_Nullable)())onCommit {
id value = [property getValue:target];
if (![self canEditProperty:property onObject:target currentValue:value]) {
return nil;
}
FLEXFieldEditorViewController *editor = [self target:target];
FLEXFieldEditorViewController *editor = [self target:target data:property commitHandler:onCommit];
editor.title = [@"Property: " stringByAppendingString:property.name];
editor.property = property;
return editor;
}
+ (instancetype)target:(id)target ivar:(nonnull FLEXIvar *)ivar {
FLEXFieldEditorViewController *editor = [self target:target];
+ (instancetype)target:(id)target ivar:(nonnull FLEXIvar *)ivar commitHandler:(void(^_Nullable)())onCommit {
FLEXFieldEditorViewController *editor = [self target:target data:ivar commitHandler:onCommit];
editor.title = [@"Ivar: " stringByAppendingString:ivar.name];
editor.ivar = ivar;
return editor;
@@ -86,8 +86,6 @@
}
- (void)actionButtonPressed:(id)sender {
[super actionButtonPressed:sender];
if (self.property) {
id userInputObject = self.firstInputView.inputValue;
NSArray *arguments = userInputObject ? @[userInputObject] : nil;
@@ -103,6 +101,9 @@
// this currently could and would assign NSArray to NSMutableArray
[self.ivar setValue:self.firstInputView.inputValue onObject:self.target];
}
// Dismiss keyboard and handle committed changes
[super actionButtonPressed:sender];
// Go back after setting, but not for switches.
if (sender) {
@@ -118,8 +119,8 @@
[self exploreObjectOrPopViewController:self.currentValue];
}
- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)inputView {
if ([inputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) {
- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView {
if ([argumentInputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) {
[self actionButtonPressed:nil];
}
}
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/23/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXVariableEditorViewController.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/23/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXMethodCallingViewController.h"
@@ -16,7 +16,7 @@
#import "FLEXUtility.h"
@interface FLEXMethodCallingViewController ()
@property (nonatomic) FLEXMethod *method;
@property (nonatomic, readonly) FLEXMethod *method;
@end
@implementation FLEXMethodCallingViewController
@@ -28,9 +28,8 @@
- (id)initWithTarget:(id)target method:(FLEXMethod *)method {
NSParameterAssert(method.isInstanceMethod == !object_isClass(target));
self = [super initWithTarget:target];
self = [super initWithTarget:target data:method commitHandler:nil];
if (self) {
self.method = method;
self.title = method.isInstanceMethod ? @"Method: " : @"Class Method: ";
self.title = [self.title stringByAppendingString:method.selectorString];
}
@@ -64,7 +63,6 @@
inputView.backgroundColor = self.view.backgroundColor;
inputView.title = methodComponent;
inputView.delegate = self;
[argumentInputViews addObject:inputView];
argumentIndex++;
}
@@ -73,8 +71,6 @@
}
- (void)actionButtonPressed:(id)sender {
[super actionButtonPressed:sender];
// Gather arguments
NSMutableArray *arguments = [NSMutableArray new];
for (FLEXArgumentInputView *inputView in self.fieldEditorView.argumentInputViews) {
@@ -90,6 +86,9 @@
withArguments:arguments
error:&error
];
// Dismiss keyboard and handle committed changes
[super actionButtonPressed:sender];
// Display return value or error
if (error) {
@@ -104,4 +103,8 @@
}
}
- (FLEXMethod *)method {
return _data;
}
@end
@@ -3,34 +3,53 @@
// Flipboard
//
// Created by Ryan Olson on 5/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXArgumentInputView.h"
#import <UIKit/UIKit.h>
@class FLEXFieldEditorView;
@class FLEXArgumentInputView;
/// Provides a screen for editing or configuring one or more variables.
@interface FLEXVariableEditorViewController : UIViewController <FLEXArgumentInputViewDelegate>
NS_ASSUME_NONNULL_BEGIN
+ (instancetype)target:(id)target;
- (id)initWithTarget:(id)target;
/// An abstract screen for editing or configuring one or more variables.
/// "Target" is the target of the edit operation, and "data" is the data
/// you want to mutate or pass to the target when the action is performed.
/// The action may be something like calling a method, setting an ivar, etc.
@interface FLEXVariableEditorViewController : UIViewController {
@protected
id _target;
_Nullable id _data;
void (^_Nullable _commitHandler)();
}
// Convenience accessor since many subclasses only use one input view
@property (nonatomic, readonly) FLEXArgumentInputView *firstInputView;
// Also a convenience accessor
@property (nonatomic, readonly) NSArray<FLEXArgumentInputView *> *inputViews;
/// @param target The target of the operation
/// @param data The data associated with the operation
/// @param onCommit An action to perform when the data changes
+ (instancetype)target:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)())onCommit;
/// @param target The target of the operation
/// @param data The data associated with the operation
/// @param onCommit An action to perform when the data changes
- (id)initWithTarget:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)())onCommit;
// For subclass use only.
@property (nonatomic, readonly) id target;
/// Convenience accessor since many subclasses only use one input view
@property (nonatomic, readonly, nullable) FLEXArgumentInputView *firstInputView;
@property (nonatomic, readonly) FLEXFieldEditorView *fieldEditorView;
/// Subclasses can change the button title via the button's \c title property
@property (nonatomic, readonly) UIBarButtonItem *actionButton;
- (void)actionButtonPressed:(id)sender;
/// Subclasses should override to provide "set" functionality.
/// The commit handler--if present--is called here.
- (void)actionButtonPressed:(nullable id)sender;
/// Pushes an explorer view controller for the given object
/// or pops the current view controller.
- (void)exploreObjectOrPopViewController:(id)objectOrNil;
- (void)exploreObjectOrPopViewController:(nullable id)objectOrNil;
@end
NS_ASSUME_NONNULL_END
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/16/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXColor.h"
@@ -19,21 +19,22 @@
@interface FLEXVariableEditorViewController () <UIScrollViewDelegate>
@property (nonatomic) UIScrollView *scrollView;
@property (nonatomic) id target;
@end
@implementation FLEXVariableEditorViewController
#pragma mark - Initialization
+ (instancetype)target:(id)target {
return [[self alloc] initWithTarget:target];
+ (instancetype)target:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)())onCommit {
return [[self alloc] initWithTarget:target data:data commitHandler:onCommit];
}
- (id)initWithTarget:(id)target {
- (id)initWithTarget:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)())onCommit {
self = [super init];
if (self) {
self.target = target;
_target = target;
_data = data;
_commitHandler = onCommit;
[NSNotificationCenter.defaultCenter
addObserver:self selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification object:nil
@@ -54,8 +55,8 @@
#pragma mark - UIViewController methods
- (void)keyboardDidShow:(NSNotification *)notification {
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGSize keyboardSize = [self.view convertRect:keyboardRect fromView:nil].size;
CGRect keyboardRectInWindow = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGSize keyboardSize = [self.view convertRect:keyboardRectInWindow fromView:nil].size;
UIEdgeInsets scrollInsets = self.scrollView.contentInset;
scrollInsets.bottom = keyboardSize.height;
self.scrollView.contentInset = scrollInsets;
@@ -114,16 +115,15 @@
#pragma mark - Public
- (FLEXArgumentInputView *)firstInputView {
return self.fieldEditorView.argumentInputViews.firstObject;
}
- (NSArray<FLEXArgumentInputView *> *)inputViews {
return self.fieldEditorView.argumentInputViews;
return [self.fieldEditorView argumentInputViews].firstObject;
}
- (void)actionButtonPressed:(id)sender {
// Subclasses can override
[self.fieldEditorView endEditing:YES];
if (_commitHandler) {
_commitHandler();
}
}
- (void)exploreObjectOrPopViewController:(id)objectOrNil {
@@ -138,20 +138,4 @@
}
}
#pragma mark - FLEXArgumentInputViewDelegate
- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)inputView {
// Subclasses might want to do something here but we don't
}
- (void)argumentInputViewWantsNextAsFirstResponder:(FLEXArgumentInputView *)inputView {
if (self.inputViews.lastObject == inputView) {
// If this is our last or only input view, dismiss the keyboard
[inputView resignFirstResponder];
} else {
NSInteger idx = [self.inputViews indexOfObject:inputView];
[self.inputViews[idx+1] becomeFirstResponder];
}
}
@end
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXBookmarkManager.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXBookmarksViewController.h"
@@ -68,10 +68,10 @@
- (void)setupEditingBarItems {
self.navigationItem.rightBarButtonItem = nil;
self.toolbarItems = @[
[UIBarButtonItem itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)],
[UIBarButtonItem flex_itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)],
UIBarButtonItem.flex_flexibleSpace,
// We use a non-system done item because we change its title dynamically
[UIBarButtonItem doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)]
[UIBarButtonItem flex_doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)]
];
self.toolbarItems.firstObject.tintColor = FLEXColor.destructiveColor;
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 4/4/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXExplorerToolbar.h"
@@ -25,7 +25,8 @@
///
/// If a tool is already presented, this method simply dismisses it and calls the completion block.
/// If no tool is presented, @code future() @endcode is presented and the completion block is called.
- (void)toggleToolWithViewControllerProvider:(UINavigationController *(^)(void))future completion:(void(^)(void))completion;
- (void)toggleToolWithViewControllerProvider:(UINavigationController *(^)(void))future
completion:(void (^)(void))completion;
// Keyboard shortcut helpers
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 4/4/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXExplorerViewController.h"
@@ -45,6 +45,9 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
/// Only valid while a toolbar drag pan gesture is in progress.
@property (nonatomic) CGRect toolbarFrameBeforeDragging;
/// Only valid while a selected view pan gesture is in progress.
@property (nonatomic) CGFloat selectedViewLastPanX;
/// Borders of all the visible views in the hierarchy at the selection point.
/// The keys are NSValues with the corresponding view (nonretained).
@property (nonatomic) NSDictionary<NSValue *, UIView *> *outlineViewsForVisibleViews;
@@ -58,6 +61,9 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
/// A colored transparent overlay to indicate that the view is selected.
@property (nonatomic) UIView *selectedViewOverlay;
/// Used to actuate changes in view selection on iOS 10+
@property (nonatomic, readonly) UISelectionFeedbackGenerator *selectionFBG API_AVAILABLE(ios(10.0));
/// self.view.window as a \c FLEXWindow
@property (nonatomic, readonly) FLEXWindow *window;
@@ -118,6 +124,11 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
self.movePanGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMovePan:)];
self.movePanGR.enabled = self.currentMode == FLEXExplorerModeMove;
[self.view addGestureRecognizer:self.movePanGR];
// Feedback
if (@available(iOS 10.0, *)) {
_selectionFBG = [UISelectionFeedbackGenerator new];
}
}
- (void)viewWillAppear:(BOOL)animated {
@@ -450,16 +461,16 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
];
[toolbar.selectedViewDescriptionContainer addGestureRecognizer:self.detailsTapGR];
// Swipe gestures for selecting deeper / higher views at a point
UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc]
UIPanGestureRecognizer *leftSwipe = [[UIPanGestureRecognizer alloc]
initWithTarget:self action:@selector(handleChangeViewAtPointGesture:)
];
UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc]
initWithTarget:self action:@selector(handleChangeViewAtPointGesture:)
];
leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
// UIPanGestureRecognizer *rightSwipe = [[UIPanGestureRecognizer alloc]
// initWithTarget:self action:@selector(handleChangeViewAtPointGesture:)
// ];
// leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
// rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
[toolbar.selectedViewDescriptionContainer addGestureRecognizer:leftSwipe];
[toolbar.selectedViewDescriptionContainer addGestureRecognizer:rightSwipe];
// [toolbar.selectedViewDescriptionContainer addGestureRecognizer:rightSwipe];
// Long press gesture to present tabs manager
[toolbar.globalsItem addGestureRecognizer:[[UILongPressGestureRecognizer alloc]
@@ -598,19 +609,54 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
}
}
- (void)handleChangeViewAtPointGesture:(UISwipeGestureRecognizer *)sender {
- (void)handleChangeViewAtPointGesture:(UIPanGestureRecognizer *)sender {
NSInteger max = self.viewsAtTapPoint.count - 1;
NSInteger currentIdx = [self.viewsAtTapPoint indexOfObject:self.selectedView];
switch (sender.direction) {
case UISwipeGestureRecognizerDirectionLeft:
self.selectedView = self.viewsAtTapPoint[MIN(max, currentIdx + 1)];
break;
case UISwipeGestureRecognizerDirectionRight:
self.selectedView = self.viewsAtTapPoint[MAX(0, currentIdx - 1)];
CGFloat locationX = [sender locationInView:self.view].x;
// Track the pan gesture: every N points we move along the X axis,
// actuate some haptic feedback and move up or down the hierarchy.
// We only store the "last" location when we've met the threshold.
// We only change the view and actuate feedback if the view selection
// changes; that is, as long as we don't go outside or under the array.
switch (sender.state) {
case UIGestureRecognizerStateBegan: {
self.selectedViewLastPanX = locationX;
break;
}
case UIGestureRecognizerStateChanged: {
static CGFloat kNextLevelThreshold = 20.f;
CGFloat lastX = self.selectedViewLastPanX;
NSInteger newSelection = currentIdx;
// Left, go down the hierarchy
if (locationX < lastX && (lastX - locationX) >= kNextLevelThreshold) {
// Choose a new view index up to the max index
newSelection = MIN(max, currentIdx + 1);
self.selectedViewLastPanX = locationX;
}
// Right, go up the hierarchy
else if (lastX < locationX && (locationX - lastX) >= kNextLevelThreshold) {
// Choose a new view index down to the min index
newSelection = MAX(0, currentIdx - 1);
self.selectedViewLastPanX = locationX;
}
if (currentIdx != newSelection) {
self.selectedView = self.viewsAtTapPoint[newSelection];
[self actuateSelectionChangedFeedback];
}
default:
break;
}
default: break;
}
}
- (void)actuateSelectionChangedFeedback {
if (@available(iOS 10.0, *)) {
[self.selectionFBG selectionChanged];
}
}
@@ -872,13 +918,12 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
[super dismissViewControllerAnimated:animated completion:completion];
}
- (BOOL)wantsWindowToBecomeKey
{
- (BOOL)wantsWindowToBecomeKey {
return self.window.previousKeyWindow != nil;
}
- (void)toggleToolWithViewControllerProvider:(UINavigationController *(^)(void))future
completion:(void(^)(void))completion {
completion:(void (^)(void))completion {
if (self.presentedViewController) {
[self dismissViewControllerAnimated:YES completion:completion];
} else if (future) {
@@ -924,11 +969,7 @@ typedef NS_ENUM(NSUInteger, FLEXExplorerMode) {
} else {
return [FLEXHierarchyViewController delegate:self];
}
} completion:^{
if (completion) {
completion();
}
}];
} completion:completion];
}
- (void)toggleMenuTool {
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 2/13/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 2/13/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXViewControllersViewController.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 4/13/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 4/13/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXWindow.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/6/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXWindowManagerController.h"
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/1/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/1/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTabList.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/4/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 2/4/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTabsViewController.h"
@@ -121,12 +121,12 @@
- (void)setupEditingBarItems {
self.navigationItem.rightBarButtonItem = nil;
self.toolbarItems = @[
[UIBarButtonItem itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)],
[UIBarButtonItem flex_itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)],
UIBarButtonItem.flex_flexibleSpace,
[UIBarButtonItem disabledSystemItem:UIBarButtonSystemItemAdd],
[UIBarButtonItem flex_disabledSystemItem:UIBarButtonSystemItemAdd],
UIBarButtonItem.flex_flexibleSpace,
// We use a non-system done item because we change its title dynamically
[UIBarButtonItem doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)]
[UIBarButtonItem flex_doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)]
];
self.toolbarItems.firstObject.tintColor = FLEXColor.destructiveColor;
+1 -6
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/12/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
@@ -12,16 +12,11 @@
#import <FLEX/CALayer+FLEX.h>
#import <FLEX/UIFont+FLEX.h>
#import <FLEX/UIGestureRecognizer+Blocks.h>
#import <FLEX/UIView+FLEX_Layout.h>
#import <FLEX/UIPasteboard+FLEX.h>
#import <FLEX/UIMenu+FLEX.h>
#import <FLEX/UITextField+Range.h>
#import <FLEX/NSObject+FLEX_Reflection.h>
#import <FLEX/NSArray+FLEX.h>
#import <FLEX/NSDictionary+ObjcRuntime.h>
#import <FLEX/NSString+ObjcRuntime.h>
#import <FLEX/NSString+FLEX.h>
#import <FLEX/NSUserDefaults+FLEX.h>
#import <FLEX/NSMapTable+FLEX_Subscripting.h>
#import <FLEX/NSTimer+FLEX.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/11/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEX/FLEXFilteringTableViewController.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/11/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEX/FLEXObjectExplorerFactory.h>
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/11/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <FLEX/FLEXObjcInternal.h>
+1 -2
View File
@@ -4,7 +4,7 @@
//
// Created by Eric Horacek on 7/18/15.
// Modified by Tanner Bennett on 3/12/20.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <FLEX/FLEXManager.h>
@@ -20,6 +20,5 @@
#import <FLEX/FLEX-Categories.h>
#import <FLEX/FLEX-ObjectExploring.h>
#import <FLEX/FLEXMacros.h>
#import <FLEX/FLEXAlert.h>
#import <FLEX/FLEXResources.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/3/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import <Foundation/Foundation.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner on 3/3/20.
// Copyright © 2020 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXSQLResult.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/10/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsEntry.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/10/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXAddressExplorerCoordinator.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Rich Robinson on 19/10/2015.
// Copyright © 2015 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsEntry.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Rich Robinson on 19/10/2015.
// Copyright © 2015 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXCookiesViewController.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewController.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXLiveObjectsController.h"
@@ -35,6 +35,7 @@ static const NSInteger kFLEXLiveObjectsSortBySizeIndex = 2;
self.showsSearchBar = YES;
self.showSearchBarInitially = YES;
self.activatesSearchBarAutomatically = YES;
self.searchBarDebounceInterval = kFLEXDebounceInstant;
self.showsCarousel = YES;
self.carousel.items = @[@"A→Z", @"Count", @"Size"];
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXFilteringTableViewController.h"
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 5/28/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXObjectListViewController.h"
@@ -20,11 +20,25 @@
#import <malloc/malloc.h>
typedef NS_ENUM(NSUInteger, FLEXObjectReferenceSection) {
FLEXObjectReferenceSectionMain,
FLEXObjectReferenceSectionAutoLayout,
FLEXObjectReferenceSectionKVO,
FLEXObjectReferenceSectionFLEX,
FLEXObjectReferenceSectionCount
};
@interface FLEXObjectListViewController ()
@property (nonatomic, readonly, class) NSArray<NSPredicate *> *defaultPredicates;
@property (nonatomic, readonly, class) NSArray<NSString *> *defaultSectionTitles;
@property (nonatomic, copy) NSArray<FLEXMutableListSection *> *sections;
@property (nonatomic, copy) NSArray<FLEXMutableListSection *> *allSections;
@property (nonatomic, readonly) NSArray<FLEXObjectRef *> *references;
@property (nonatomic, readonly, nullable) NSArray<FLEXObjectRef *> *references;
@property (nonatomic, readonly) NSArray<NSPredicate *> *predicates;
@property (nonatomic, readonly) NSArray<NSString *> *sectionTitles;
@@ -38,7 +52,7 @@
+ (NSPredicate *)defaultPredicateForSection:(NSInteger)section {
// These are the types of references that we typically don't care about.
// We want this list of "object-ivar pairs" split into two sections.
BOOL(^isObserver)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) {
BOOL(^isKVORelated)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) {
NSString *row = ref.reference;
return [row isEqualToString:@"__NSObserver object"] ||
[row isEqualToString:@"_CFXNotificationObjcObserverRegistration _object"];
@@ -65,34 +79,50 @@
([row hasPrefix:@"_NSAutoresizingMask"] && [row hasSuffix:@" _referenceItem"]) ||
[ignored containsObject:row];
};
/// These are FLEX classes and usually you aren't looking for FLEX references inside FLEX itself
BOOL(^isFLEXClass)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) {
return [ref.reference hasPrefix:@"FLEX"];
};
BOOL(^isEssential)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) {
return !(isObserver(ref, bindings) || isConstraintRelated(ref, bindings));
return !(
isKVORelated(ref, bindings) ||
isConstraintRelated(ref, bindings) ||
isFLEXClass(ref, bindings)
);
};
switch (section) {
case 0: return [NSPredicate predicateWithBlock:isEssential];
case 1: return [NSPredicate predicateWithBlock:isConstraintRelated];
case 2: return [NSPredicate predicateWithBlock:isObserver];
case FLEXObjectReferenceSectionMain:
return [NSPredicate predicateWithBlock:isEssential];
case FLEXObjectReferenceSectionAutoLayout:
return [NSPredicate predicateWithBlock:isConstraintRelated];
case FLEXObjectReferenceSectionKVO:
return [NSPredicate predicateWithBlock:isKVORelated];
case FLEXObjectReferenceSectionFLEX:
return [NSPredicate predicateWithBlock:isFLEXClass];
default: return nil;
}
}
+ (NSArray<NSPredicate *> *)defaultPredicates {
return @[[self defaultPredicateForSection:0],
[self defaultPredicateForSection:1],
[self defaultPredicateForSection:2]];
return [NSArray flex_forEachUpTo:FLEXObjectReferenceSectionCount map:^id(NSUInteger i) {
return [self defaultPredicateForSection:i];
}];
}
+ (NSArray<NSString *> *)defaultSectionTitles {
return @[@"", @"AutoLayout", @"Trivial"];
return @[
@"", @"AutoLayout", @"Key-Value Observing", @"FLEX"
];
}
#pragma mark - Initialization
- (id)initWithReferences:(NSArray<FLEXObjectRef *> *)references {
- (id)initWithReferences:(nullable NSArray<FLEXObjectRef *> *)references {
return [self initWithReferences:references predicates:nil sectionTitles:nil];
}
@@ -184,19 +214,18 @@
}
}
free(ivars);
tryClass = class_getSuperclass(tryClass);
}
}];
NSArray<NSPredicate *> *predicates = [self defaultPredicates];
NSArray<NSString *> *sectionTitles = [self defaultSectionTitles];
FLEXObjectListViewController *viewController = [[self alloc]
initWithReferences:instances
predicates:predicates
sectionTitles:sectionTitles
predicates:self.defaultPredicates
sectionTitles:self.defaultSectionTitles
];
viewController.title = [NSString stringWithFormat:@"Referencing %@ %p",
NSStringFromClass(object_getClass(object)), object
[FLEXRuntimeUtility safeClassNameForObject:object], object
];
return viewController;
}
@@ -231,7 +260,7 @@
}];
}
- (FLEXMutableListSection *)makeSection:(NSArray *)rows title:(NSString *)title {
- (FLEXMutableListSection *)makeSection:(NSArray *)rows title:(NSString *)title { weakify(self)
FLEXMutableListSection *section = [FLEXMutableListSection list:rows
cellConfiguration:^(FLEXTableViewCell *cell, FLEXObjectRef *ref, NSInteger row) {
cell.textLabel.text = ref.reference;
@@ -246,14 +275,10 @@
}
];
__weak __typeof(self) weakSelf = self;
section.selectionHandler = ^(__kindof UIViewController *host, FLEXObjectRef *ref) {
__strong __typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.navigationController pushViewController:[
FLEXObjectExplorerFactory explorerViewControllerForObject:ref.object
] animated:YES];
}
section.selectionHandler = ^(UIViewController *host, FLEXObjectRef *ref) { strongify(self)
[self.navigationController pushViewController:[
FLEXObjectExplorerFactory explorerViewControllerForObject:ref.object
] animated:YES];
};
section.customTitle = title;
+1 -1
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/24/18.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <Foundation/Foundation.h>
+2 -2
View File
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/24/18.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXObjectRef.h"
@@ -47,7 +47,7 @@
_object = object;
_wantsSummary = showSummary;
NSString *class = NSStringFromClass(object_getClass(object));
NSString *class = [FLEXRuntimeUtility safeClassNameForObject:object];
if (ivar) {
_reference = [NSString stringWithFormat:@"%@ %@", class, ivar];
} else if (showSummary) {
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/10/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -3,7 +3,7 @@
// Flipboard
//
// Created by Ryan Olson on 6/10/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXWebViewController.h"
@@ -25,7 +25,7 @@
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
if (@available(iOS 10.0, *)) {
configuration.dataDetectorTypes = UIDataDetectorTypeLink;
configuration.dataDetectorTypes = WKDataDetectorTypeLink;
}
self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
@@ -54,9 +54,8 @@ typedef NS_ENUM(NSUInteger, FLEXFileBrowserSortAttribute) {
self.title = [path lastPathComponent];
self.operationQueue = [NSOperationQueue new];
//computing path size
FLEXFileBrowserController *__weak weakSelf = self;
// Compute path size
weakify(self)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSFileManager *fileManager = NSFileManager.defaultManager;
NSDictionary<NSString *, id> *attributes = [fileManager attributesOfItemAtPath:path error:NULL];
@@ -66,16 +65,15 @@ typedef NS_ENUM(NSUInteger, FLEXFileBrowserSortAttribute) {
attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL];
totalSize += [attributes fileSize];
// Bail if the interested view controller has gone away.
if (!weakSelf) {
// Bail if the interested view controller has gone away
if (!self) {
return;
}
}
dispatch_async(dispatch_get_main_queue(), ^{
FLEXFileBrowserController *__strong strongSelf = weakSelf;
strongSelf.recursiveSize = @(totalSize);
[strongSelf.tableView reloadData];
dispatch_async(dispatch_get_main_queue(), ^{ strongify(self)
self.recursiveSize = @(totalSize);
[self.tableView reloadData];
});
});
@@ -360,38 +358,41 @@ typedef NS_ENUM(NSUInteger, FLEXFileBrowserSortAttribute) {
#if FLEX_AT_LEAST_IOS13_SDK
- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point __IOS_AVAILABLE(13.0) {
__weak __typeof__(self) weakSelf = self;
return [UIContextMenuConfiguration configurationWithIdentifier:nil
previewProvider:nil
actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
UITableViewCell * const cell = [tableView cellForRowAtIndexPath:indexPath];
UIAction *rename = [UIAction actionWithTitle:@"Rename"
image:nil
identifier:@"Rename"
handler:^(__kindof UIAction * _Nonnull action) {
[weakSelf fileBrowserRename:cell];
}];
UIAction *delete = [UIAction actionWithTitle:@"Delete"
image:nil
identifier:@"Delete"
handler:^(__kindof UIAction * _Nonnull action) {
[weakSelf fileBrowserDelete:cell];
}];
UIAction *copyPath = [UIAction actionWithTitle:@"Copy Path"
image:nil
identifier:@"Copy Path"
handler:^(__kindof UIAction * _Nonnull action) {
[weakSelf fileBrowserCopyPath:cell];
}];
UIAction *share = [UIAction actionWithTitle:@"Share"
image:nil
identifier:@"Share"
handler:^(__kindof UIAction * _Nonnull action) {
[weakSelf fileBrowserShare:cell];
}];
return [UIMenu menuWithTitle:@"Manage File" image:nil identifier:@"Manage File" options:UIMenuOptionsDisplayInline children:@[rename, delete, copyPath, share]];
}];
- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView
contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
point:(CGPoint)point __IOS_AVAILABLE(13.0) {
weakify(self)
return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil
actionProvider:^UIMenu *(NSArray<UIMenuElement *> *suggestedActions) {
UITableViewCell * const cell = [tableView cellForRowAtIndexPath:indexPath];
UIAction *rename = [UIAction actionWithTitle:@"Rename" image:nil identifier:@"Rename"
handler:^(UIAction *action) { strongify(self)
[self fileBrowserRename:cell];
}
];
UIAction *delete = [UIAction actionWithTitle:@"Delete" image:nil identifier:@"Delete"
handler:^(UIAction *action) { strongify(self)
[self fileBrowserDelete:cell];
}
];
UIAction *copyPath = [UIAction actionWithTitle:@"Copy Path" image:nil identifier:@"Copy Path"
handler:^(UIAction *action) { strongify(self)
[self fileBrowserCopyPath:cell];
}
];
UIAction *share = [UIAction actionWithTitle:@"Share" image:nil identifier:@"Share"
handler:^(UIAction *action) { strongify(self)
[self fileBrowserShare:cell];
}
];
return [UIMenu menuWithTitle:@"Manage File" image:nil
identifier:@"Manage File"
options:UIMenuOptionsDisplayInline
children:@[rename, delete, copyPath, share]
];
}
];
}
#endif
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Javier Soto on 7/26/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import <UIKit/UIKit.h>
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Javier Soto on 7/26/14.
// Copyright (c) 2020 Flipboard. All rights reserved.
// Copyright (c) 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsEntry.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/11/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXTableViewSection.h"
@@ -3,7 +3,7 @@
// FLEX
//
// Created by Tanner Bennett on 7/11/19.
// Copyright © 2019 Flipboard. All rights reserved.
// Copyright © 2020 FLEX Team. All rights reserved.
//
#import "FLEXGlobalsSection.h"

Some files were not shown because too many files have changed in this diff Show More