BOOM Analytics: Exploring Data-Centric, Declarative Programming for the Cloud
If you've haven't seen it before, there is a cool accessibility feature in UITableView that allows the user to toggle between different actions. It's really very elegant and it's a powerful and convenient implementation for VoiceOver users on iOS. One could say that it's the VoiceOver version of the swipe-to-delete feature.
To try it out yourselves, open one of the built in apps like Mail or Notes and turn on VoiceOver. If you are afraid to accidentally delete some of your important notes or email, you can also create a new Master-Detail Application in Xcode and run it on your device. Navigate to one of the cells and use the "Rotor" (rotate with two fingers on the screen) to find the "Actions" item. Now you can swipe up and down do toggle between "Activate Item (default action)" and "Delete". If you now double tap, the cell gets deleted instead of selected.
This is the default behavior and you get this accessibility out of the box with UITableView.
extension Array { | |
func first() -> Element? { | |
if isEmpty { | |
return nil | |
} | |
return self[0] | |
} | |
func last() -> Element? { |
/** | |
Allows easier pushing and popping of clang warnings. | |
Example (Ignoring undeclared selectors): | |
SQClangDiagnosticPushIgnored(-Wundeclared-selector); | |
SEL undeclaredSelector = @selector(thisSelectorDoesNotExist:::); | |
SQClangDiagnosticPop; | |
*/ |
import lldb | |
import commands | |
def __lldb_init_module (debugger, dict): | |
debugger.HandleCommand('command script add -f LBRShortcut.window_description_command window_description') | |
debugger.HandleCommand('command script add -f LBRShortcut.json_data_command json_data') | |
debugger.HandleCommand('command script add -f LBRShortcut.fire_fault_command fire_fault') | |
def window_description_command(debbuger, command, result, dict): |
There was [a tweet][tweetSoto] a couple of days ago that resulted in a discussion/question about what it wrong with the usage of removedOnCompletion = NO
in the [SparkRecordingCircle code][code] for that [Subjective-C post][post].
We all kept saying that the explanation doesn't fit in a tweet, so here is my rough explanation about the issues.
But, let me first say that I think that the Subjective-C articles are reallt cool and useful to learn from. This is trying to reason about the general usage of removedOnCompletion = NO
, using that code as an example, since that was what was discussed on twitter.
The root problem, as [Nacho Soto pointed out][rootProblem], is that removedOnCompletion = NO
in combination with fillMode = kCAFillModeForwards
is almost always used when you are not updating the model layer. This means that after the animation has finished, what you see on screen is not reflected in the property of the layer. The biggest issue that this can cause is that all the
# Your keymap | |
# | |
'body': | |
'ctrl-tab': 'pane:show-next-item' | |
'alt-cmd-up': 'pane:split-up' | |
'alt-cmd-down': 'pane:split-down' | |
'shift-cmd-L': 'application:open-dev' | |
'shift-cmd-0': 'window:reset-font-size' | |
'.platform-darwin': |
#import <UIKit/UIPageViewController.h> | |
// Because UIPageViewController somehow "caches" its view controllers when you pass animated:YES and there is no "reloadData" method in UIPageViewControllerDataSource | |
@interface UIPageViewController (ReloadData) | |
- (void) xcd_setViewControllers:(NSArray *)viewControllers direction:(UIPageViewControllerNavigationDirection)direction animated:(BOOL)animated completion:(void (^)(BOOL))completion; | |
@end |
@interface UIView (PSPDFKitAdditions) | |
// Allows to change frame/bounds without triggering `layoutSubviews` on the parent. | |
// Not needed for changes that are performed within `layoutSubviews`. | |
- (void)pspdf_performWithoutTriggeringSetNeedsLayout:(dispatch_block_t)block; | |
@end | |
#import "UIView+PSPDFKitAdditions.h" |
#!/usr/bin/env bash | |
function openWorkspaceOrProjectWithApp() | |
{ | |
if [[ -z "$1" || "$#" -ne 2 ]]; then | |
echo -e "Nothing found\n" | |
return | |
fi | |
IDEFileName=${2##*/} |