Giter Club home page Giter Club logo

tweaks's Introduction

Tweaks

Tweaks is an easy way to fine-tune an iOS app. Build Status

Tweaks

Why

The best way to improve an app is to use it every day. Even when ideas can be tested out in advance β€” for example, with Origami β€” it can still take some time with the app to see how it works in practice.

Occasionally, it's perfect the first try. Sometimes, the idea doesn't work at all. But often, it just needs a few minor adjustments. That last case is where Tweaks fits in. Tweaks makes those small adjustments easy: with no code changes and no computer, you can try out different options and decide which works best.

Some of the most useful parameters to adjust are animation timings, velocity thresholds, colors, and physics constants. At Facebook, we also use tweaks to temporarily disable new features during development. That way, the designers and engineers involved can enable it on just their devices, without getting in the way of others testing the app.

Tweaks was invaluable for building Paper. We hope it can be useful for your app too.

Usage

Each configurable value is called a tweak. There's a few ways to set them up, found in FBTweakInline.h.

Value

The simplest way to create a tweak is to replace a constant with FBTweakValue:

CGFloat animationDuration = FBTweakValue(@"Category", @"Group", @"Duration", 0.5);

The first three parameters are where the tweak is listed and what it's called, and the last one is the default value. You can pass in many types of values for the default: booleans, numbers, or strings.

if (FBTweakValue(@"Category", @"Feature", @"Enabled", YES)) {
  label.text = FBTweakValue(@"Category", @"Group", @"Text", @"Tweaks example.");
}

In release builds, the FBTweakValue macro expands to just the default value, so there's no performance impact. In debug builds, though, it fetches the latest value of the tweak.

You can also pass a fifth parameter, which will constrain the possible values for a tweak. The fifth parameter can be an array, dictionary, or an FBTweakNumericRange. If it's a dictionary, the values should be strings to show in the list of choices. Arrays will show the values' description as choices. (Note that you have to surround array and dictionary literals with an extra set of parentheses.)

self.initialMode = FBTweakValue(@"Header", @"Initial", @"Mode", @(FBSimpleMode), (@{ @(FBSimpleMode) : @"Simple", @(FBAdvancedMode) : @"Advanced" }));

For numeric tweaks (NSInteger, CGFloat, and others), you can instead pass two parameters, which constrain the value to a FBTweakNumericRange:

self.red = FBTweakValue(@"Header", @"Colors", @"Red", 0.5, 0.0, 1.0);

Bind

To make tweaks update live, you can use FBTweakBind:

FBTweakBind(self.headerView, alpha, @"Main Screen", @"Header", @"Alpha", 0.85);

The first parameter is the object to bind to, and the second is the property. Whenever the tweak is changed, self.headerView's alpha property is updated to match. A few more examples:

FBTweakBind(audioPlayer, volume, @"Player", @"Audio", @"Volume", 0.9);
FBTweakBind(webView.scrollView, scrollEnabled, @"Browser", @"Scrolling", @"Enabled", YES);

As with FBTweakValue, in release builds FBTweakBind expands to just setting the property to the default value.

Action

Actions let you run a (global) block when a tweak is selected. To make one, use FBTweakAction:

FBTweakAction(@"Player", @"Audio", @"Volume", ^{
  NSLog(@"Action selected.");
});

The first three parameters are the standard tweak listing information, and the last is a block to call. You can use FBTweakAction in any scope, but the block must be global: it can't depend on any local or instance variables (it wouldn't know which object to adjust).

Actions are useful for things like launching debug UIs, checking for updates, or (if you make one that intentionally crashes) testing crash reporting.

Tweaks UI

To configure your tweaks, you need a way to show the configuration UI. There's two options for that:

  • Traditionally, tweaks is activated by shaking your phone. To use that, just replace your root UIWindow with a FBTweakShakeWindow. If you're using Storyboards, you can override -window on your app delegate:
- (UIWindow *)window
{
  if (!_window) {
    _window = [[FBTweakShakeWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  }

  return _window;
}
  • You can present a FBTweakViewController from anywhere in your app. Be sure to restrict the activation UI to debug builds!
- (void)showTweaks {
   FBTweakViewController *tweakVC = [[FBTweakViewController alloc] initWithStore:[FBTweakStore sharedInstance]];
   tweakVC.tweaksDelegate = self;
   // Assuming this is in the app delegate
   [self.window.rootViewController presentViewController:tweakVC animated:YES completion:nil];
}

- (void)tweakViewControllerPressedDone:(FBTweakViewController *)tweakViewController {
   [tweakViewController dismissViewControllerAnimated:YES completion:NULL];
}

Tweaks UI Dismiss Notification

Alternatively, when the Tweaks UI is dismissed, you can register your notification center to listen to FBTweakShakeViewControllerDidDismissNotification, which can be used after importing FBTweakViewController.h

Advanced

You can also access the objects that make up the macros mentioned above. That can be useful for more complex scenarios, like adjusting members of a C structure.

For example, to manually create a tweak:

FBTweak *tweak = [[FBTweak alloc] initWithIdentifier:@"com.tweaks.example.advanced"];
tweak.name = @"Advanced Settings";
tweak.defaultValue = @NO;

FBTweakStore *store = [FBTweakStore sharedInstance];
FBTweakCategory *category = [[FBTweakCategory alloc] initWithName:@"Settings"];
[store addTweakCategory:category];
FBTweakCollection *collection = [[FBTweakCollection alloc] initWithName:@"Enable"];
[category addTweakCollection:collection];
[collection addTweak:tweak];

[tweak addObserver:self];

Then, you can watch for when the tweak changes:

- (void)tweakDidChange:(FBTweak *)tweak
{
  self.advancedSettingsEnabled = ![tweak.currentValue boolValue];
}

Also you have de ability to implement the optional method tweakWillChange: in order to handle the previous value of your tweak:

- (void)tweakWillChange:(FBTweak *)tweak
{
  NSLog(@"%@", tweak.currentValue); // Here current value is the previous value of the tweak
}

To override when tweaks are enabled, you can define the FB_TWEAK_ENABLED macro. It's suggested to avoid including them when submitting to the App Store.

Using from a Swift Project

Khan Academy's project SwiftTweaks is designed for Swift, and might be a better choice for Swift projects.

Tweaks can be used from Swift projects. In this case the handy shortcut macros defined in FBTweakInline.h are not available, meaning tweaks need to be created programmatically, similar to this example:

let tweak = FBTweak(identifier: "com.tweaks.example.advanced")
tweak.name = "Advanced settings"
tweak.defaultValue = false

let collection = FBTweakCollection(name: "Enable");
collection.addTweak(tweak)
        
let category = FBTweakCategory(name: "Settings")
category.addTweakCollection(collection);
        
let store = FBTweakStore.sharedInstance()
store.addTweakCategory(category)

tweak.addObserver(self)

After setting up a tweak you can watch for when it changes:

func tweakDidChange(tweak: FBTweak!)
{
    self.advancedSettingsEnabled = tweak.currentValue as Bool;
}

How it works

In debug builds, the tweak macros use __attribute__((section)) to statically store data about each tweak in the __FBTweak section of the mach-o. Tweaks loads that data at startup and loads the latest values from NSUserDefaults.

In release builds, the macros just expand to the default value. Nothing extra is included in the binary.

Installation

There are two options:

  1. Tweaks is available as Tweaks in CocoaPods. (If you have issues with custom Xcode configurations, this comment might help.)
  2. Manually add the files from FBTweak/ into your Xcode project. Slightly simpler, but updates are also manual.

Tweaks requires iOS 6 or later.

There's also a demo project available. To use it, make sure to open FBTweakExample.xcworkspace (rather than the .xcodeproj) so the dependencies build correctly.

Contributing

See the CONTRIBUTING file for how to help out.

License

Tweaks is BSD-licensed. We also provide an additional patent grant.

tweaks's People

Contributors

algal avatar avhurst avatar b3ll avatar bdaz avatar callumboddy avatar danielalves avatar dasmer avatar davidcallahan avatar dmur avatar facebook-github-bot avatar fastred avatar flovilmart avatar gergelyorosz avatar grp avatar jamesgpearce avatar johntmcintosh avatar kastiglione avatar kcharwood avatar natan avatar nolanw avatar oliverletterer avatar rayray avatar readmecritic avatar renssies avatar rwarrender avatar samsonjs avatar sgl0v avatar sharplet avatar streeter avatar tudormunteanu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tweaks's Issues

Enable "Per-Category" basis reset

Just tried this framework right now and it feels like superb! But I found a couple of usability improvements to FBTweakViewControllers...

I found there are lot of needs for a reset button for each categories. Our team doesn't want to reset the entire settings out but just a single category. Perhaps we can adjust our workflow to update the default value of Tweaks and distribute builds fast enough, but for now such kind of function would be very useful.

floating point default values sometimes require 'f' suffix, but shouldn't need to

Hi,

Just updated from Cocoapods version 1.1.0 to :head to get the dictionary support feature, and found that I needed to update all of my previous default values for FBTweakValue with an explicit f suffix. Otherwise encoding would be NULL in the corresponding fb_tweak_entry, and I'd get a null pointer dereference in _FBTweakCreateWithEntry(). ie;

FBTweakValue(@"Category", @"Collection", @"Name", 0.25f);

works, whereas:

FBTweakValue(@"Category", @"Collection", @"Name", 0.25);

Causes the issue. This wasn't required in the previous version, and isn't (yet) noted in the docs, so though I should point this out.

Thanks!

Issues reading from mach_header when mixing swift and obj-c

Thanks for this very helpful library. In particular, using enums with dictionaries works great! Happy to see that got merged.

I ran into some issues where the Tweaks library couldn't pull the data out of the mach header in FBTweakInline.m's +load method. This check fails and it never gets to the for loop:

const fb_tweak_section *section = fb_tweak_getsectbynamefromheader((void *)mach_header, FBTweakSegmentName, FBTweakSectionName);

if (section == NULL) {
    return;
}

The net effect is that when I use the macros, the tweaks don't appear in the menu.

So I've fallen back to structure like the following:

FBTweakCategory *category = [store tweakCategoryWithName:@"Category"];
if (!category) {
    category = [[FBTweakCategory alloc] initWithName:@"Category"];
    [store addTweakCategory:category];
}
// ...

Would be great if there's a way to get the macros working.

My main project is swift, and I've replaced my UIWindow as instructed within AppDelegate.swift.
The main project depends on a cocoapod Foo. Foo is written in objective-c and lists Tweaks as a dependency in its .podspec. (No particular Tweaks version is specified.)

Thanks in advance for any insight you may be able to provide.

FBTweakBind lazily initialized objects

In my app, I extend NSParargraphStyle with my own custom style that I make accessible through a lazily instantiated property.

static NSMutableParagraphStyle *style;

@implementation NSParagraphStyle (Styling)

+ (instancetype)abc_authoringParagraphStyle {
    if (style == nil) {
        style = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
        FBTweakBind(style, paragraphSpacing, ABCAuthoringModeTweakName, ABCAuthoringModeTextTweakName, @"Paragraph Spacing", 20.f, 0.f, 50.f);
    }
    return style;
}

@end

I try to use tweak bind such that value updates are set directly on the underlying object. However, I get a
EXC_i386_IVOP exception.

Bump version

Looks like the latest tag, 2.0.0, is ~10 months old. Might be worth bumping the version number so people can easily get the latest fixes (such as #85 which fixes framework support) via Cocoapods without having to reference the git repo like this:

pod 'Tweaks', :git => 'https://github.com/facebook/Tweaks.git',

Bind Constants?

To improve usability, is it possible to bind constants? It seems like I have to restart the app ever time I modify a FBTweakValue?

How would I bind a float used in an animation?

CGFloat durationExample = FBTweakBind(@"Animation", @"Appear", @"Duration", 0.5);

[UIView animateWithDuration:durationExample animations:^{
        //some animation
}];

Thanks!

Support tweaks that run a block on tap

It's often useful to have tweaks to test out a feature on tap. For example, one could test that a crash reporter works as designed by crashing the app on tap.

FBTweakAction invoked on respective table cell scroll into view

When I have more than a screen's worth of items within the FBTweakViewController for a category, and the first table cell item is for a FBTweakAction, if I scroll down so that the table cell item for that action scrolls out of view, and then scroll back up so that it comes back into view, it triggers the action inadvertently.

Is this a known issue? I'd be glad to try and build a minimal test case for this when I have the time, but for right now all I can offer is that it happens with a table section with two action cells at the top, followed by several property sections with a variable number of items each (enough to allow the top section to be scrolled out of view)

Cocoapods Link Error: __FBTweakIdentifier (with custom build configuration)

Trying to get set up with Tweaks, added the pod to my podfile:

pod 'Tweaks'

Got the FBTweakShakeWindow integrated and displaying 0 items (as expected), went to add my first tweak as such:

self.alpha = FBTweakValue(@"Category", @"Thing", @"Alpha", .6, 0.1, 1.0);

When I went to build I got a Linker Error:

Undefined symbols for architecture i386: "__FBTweakIdentifier"

I see the externs defined in FBTweakInline.m and FBTweakinlineInternal.h, but I can't get this resolved.

Any suggestions on what I might have missed or what the problem might be?

Many thanks.

Network Tweaks

Right now it is a bit clumsy to have to open the Tweaks UI from inside of the app, make changes, and then close the UI to see them - so I created a Mac app that pairs with Tweaks in order to make changes from your desktop and have them take effect on the device over the network.

Is this something you would be interested in integrating?

Below are just some screenshots of a fully functional prototype that is paired with the test Tweaks project.

tweaks
tweaks-2

NSInteger Support?

When using an int - the tweak value is not converted correctly:

int gravityValue = FBTweakValue(@"Animation", @"Settings", @"Hide Gravity", 2);

Screenshot of output:
http://imgur.com/ZdTjNVD

Tests are not working

  • Running tests results in many errors
  • Tests are not running from a clean state, so they interfere with each other

Add "Done" buttons to _FBTweakCollectionViewController as well

Another small usability improvements is to add a Done button to _FBTweakCollectionViewController as well as the root view controller of FBTweak UI so that we can get back to our app right after changing Tweaks. Seemed to be a very small thing but we change tweaks a ton so just a single tap matters.

Getting wacky values in the tweaks UI

I'm setting integer values and getting crazy numbers in the "shake" UI.

for instance

FBTweakValue(@"marks", @"Swipe", @"Default height if not defined", 100);

and the output in the "shake UI" is some funky number - looks like it could be an overflow - but maybe its a weird floating point number.

Swiftish syntax?

let tweak = FBTweak(identifier: "com.tweaks.example.advanced")
tweak.name = "Advanced settings"
tweak.defaultValue = false

let collection = FBTweakCollection(name: "Enable");
collection.addTweak(tweak)

let category = FBTweakCategory(name: "Settings")
category.addTweakCollection(collection);

let store = FBTweakStore.sharedInstance()
store.addTweakCategory(category)

tweak.addObserver(self)

// ...
func tweakDidChange(tweak: FBTweak!)
{
    self.advancedSettingsEnabled = tweak.currentValue as Bool;
}

Compared to:

FBTweakStore.sharedInstance()
  + FBTweakCategory(name: "Settings")
  + FBTweakCollection(name: "Enabled")
  + FBTweak<Bool>("com.fb.example", "Advanced settings", false) {
      tweak in
      self.advancedSettingsEnabled = tweak.currentValue
    }

And the rhs should support Array as well:

let collection = FBTweakCollection(name: "Enabled")
    + [
        FBTweak<Bool>("com.fb.example", "Advanced settings", false) {
          tweak in
          self.advancedSettingsEnabled = tweak.currentValue
        },
        // Another Tweak
      ]

Support list of items

It would be great to provide a list of items to select from, but I can't quite think of a good way to do it.

FBTweakValue(@"Fun", @"Times", @"List", 0, @[@"TEST1", @"TEST2", @"TEST3]);

Something along the lines of this where you specify the default index value, but the tweaks selection UI would drill down to a list selection showing the string values?

Maybe there is a fancy way to do this with NS_ENUM and NS_OPTIONS, but I havent figured out a good way to do it yet.

Support changing the tweak value after initial definition

It would be very helpful if the tweaks UI would update if you defined it again. This would allow you to use the Tweaks UI to display relevant information, even if you didn't need to modify it.

For example, you could track things like "number of newsfeed items loaded" and as it changes, it would be updated in the UI.

Steps to reproduce:

  1. Include the following code snippet in application:didFinishLaunchingWithOptions:

    NSString *string;
    string = FBTweakValue(@"Info", @"Group", @"Text", @"Hello");
    string = FBTweakValue(@"Info", @"Group", @"Text", @"Goodbye");

  2. Launch the Tweaks UI and navigate to the section listed above

Expected Behavior: Goodbye is shown in the tweaks UI
Observed Behavior: Hello is shown in the tweaks UI

bad receiver type 'const char *' when compiling ObjC++

Hi guys,

So, I'm writing a Tweak for an animation curve in an ObjC++ file (ComponentKit πŸ˜‰), using the dictionary method. It's basically this:

[FBTweakValue(@"a", @"b", @"c",
                  @(UIViewAnimationOptionCurveEaseInOut),
                  (@{
                     @(UIViewAnimationOptionCurveEaseInOut) : @"Ease In-Out",
                     @(UIViewAnimationOptionCurveEaseIn) : @"Ease In",
                     @(UIViewAnimationOptionCurveEaseOut) : @"Ease Out",
                     @(UIViewAnimationOptionCurveLinear) : @"Linear"
                     })) unsignedIntegerValue]

However, this won't compile in an ObjC++ file with the following error:

<redacted>: error: bad receiver type 'const char *'
                FBTweakAnimationCurve(@"foo", @"Bar", @"Cheese");
                ^
In file included from <built-in>:351:
In file included from <command line>:26:
In file included from <redacted>:
<redacted>:18:2: note: expanded from macro 'FBTweakAnimationCurve'
[FBTweakValue(category_, collection_, name_, \
 ^
In file included from <built-in>:351:
In file included from <command line>:26:
In file included from  <redacted>:39:
In file included from  <redacted>:10:
 <redacted>/Headers/Public/Tweaks/FBTweakInline.h:38:58: note: expanded from macro 'FBTweakValue'
#define FBTweakValue(category_, collection_, name_, ...) _FBTweakValue(category_, collection_, name_, __VA_ARGS__)
                                                         ^
In file included from <built-in>:351:
In file included from <command line>:26:
In file included from  <redacted>:39:
In file included from  <redacted>:10:
In file included from  <redacted>/Headers/Public/Tweaks/FBTweakInline.h:10:
 <redacted>/Headers/Public/Tweaks/FBTweakInlineInternal.h:159:127: note: expanded from macro '_FBTweakValue'
#define _FBTweakValue(category_, collection_, name_, ...) _FBTweakDispatch(_FBTweakValueWithoutRange, _FBTweakValueWithRange, _FBTweakValueWithPossible, __VA_ARGS__)(category_, collection_, name_, __VA_ARGS__)
                                                                                                                              ^
 <redacted>/Headers/Public/Tweaks/FBTweakInlineInternal.h:67:174: note: expanded from macro '_FBTweakDispatch'
#define _FBTweakDispatch(__withoutRange, __withRange, __withPossible, ...) __FBTweakConcat(__FBTweakDispatch, __FBTweakIndexCount(__VA_ARGS__))(__withoutRange, __withRange, __withPossible)
                                                                                                                                                                             ^
 <redacted>/Headers/Public/Tweaks/FBTweakInlineInternal.h:65:78: note: expanded from macro '__FBTweakDispatch2'
#define __FBTweakDispatch2(__withoutRange, __withRange, __withPossible, ...) __withPossible
                                                                             ^
 <redacted>/Headers/Public/Tweaks/FBTweakInlineInternal.h:154:87: note: expanded from macro '_FBTweakValueWithPossible'
#define _FBTweakValueWithPossible(category_, collection_, name_, default_, possible_) \
                                                                                      ^
1 error generated.

It's possible to test this by pasting the macro into a plain ObjC file, then changing the type to ObjC++ or renaming to .mm. Since this works, I'm fairly sure this isn't my error...?

Of course, it's possible to work around this by returning the value from a function in an .h/.m helper pair, but raising here in case this is something that could be fixed.

Thanks!

Multiple values (e.g. arrays)

Has anyone considered the ability to set more than one value for a tweak?

Edit: My original question was about setting more than one value at a time, like a multi-select chooser. Could have been worded more clearly.

For example, if you wanted to be able to select multiple NS_OPTIONS values from a list, then you could write code to "or" them together.

Android support

This is not really an issue, rather a question. Is there an Android version of Tweaks?

fb_tweak_entry_block_field causing compile time error

Hello,

I've included Tweak in my project by manually adding the content of FBTweak/ folder to my .xcworkspace .
However, I've got multiple compile errors in FBTweakInline.m, relative to the expansion of the fb_tweak_entry_block_field macro, without ever using Tweak in my project.

Each time this macro is used, the following errors appear :

  • C++ requires a type specifier for all declaration
  • Expected '(' for function-style cast or type construction
  • Expected expression

As well as this warning

  • 'objc_ownership only applies to Objective-C object or block pointer types : type here is 'int(*())'

The project in itself is not extremely weird. I've got a couple of Objective-C++ subproject and a sample application (that uses both Objective-C and Objective-C++) in a .xcworkspace.
Note that dropping FBTweak in an empty project does generate the errors, but does not prevent the build from happening 😨.

Has anyone else run into this issue ? I don't really now how to proceed and would be extremely grateful for help.

Thanks

FBTweakBind and negative value

I'm experiencing problems while using negative values with FBTweakBind.

The problem is mostly in UI for tweaks when UIStepper's minimal value is set to 1/10th of current value.

What's the best way to set minimal value for a tweak and still use FBTweakBind?

Usage with Swift

Can this lib be used with Swift as I've heard Swift can't call hash define inline methods - e.g.
(hash)define FBTweakValue(category_, collection_, name_, ...) FBTweakValue(category, collection_, name_, VA_ARGS)

Turn-on Travis

  • You (or another maintainer) need to go to travis-ci.org and flip the switch on for the travis hook to this repo.
  • Then the next time you make any commit to this repo, you'll get a CI report from travis.

Referencing: #79 (comment)

Email button doesn't appear on handset

Running Tweaks on an iPhone 5, I'm not seeing the button to email my tweaks configuration.

Not sure if it's being pushed off the screen or I'm doing something wrong.

Integer values

I've just had an issue using an integer value, it seems to be decoded incorrectly and results in a massive value. Whereas float values are fine.

e.g. 60 vs 60.0

Can’t use a const double as default value for FBTweakValue()

Trying to use FBTweakValue() with a constant default value defined as:

const NSTimeInterval DefaultAnimationDuration = 0.5;

And then using it as follows

NSTimeInterval animationDuration = FBTweakValue(@"Category", @"Group", @"Duration", DefaultAnimationDuration);

Which produces two errors:

  1. error: initializing 'void *' with an expression of type 'typeof (DefaultAnimationDuration) *' (aka 'const double *') discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
  2. initializing 'NSTimeInterval' (aka 'double') with an expression of incompatible type 'const char *’

It seems to work if I use a numeric numeral instead.

Release new version to CocoaPods. (Last release was March 20 2015)

The current version 2.0.0 was released on March 20 2015, and there have been many nice updates since then particularly support for configuring UIColor. It would be good to release a new version to CocoaPods.

I spent quite a bit of time trying to figure out why I couldn't get UIColor to show the "color adjustment view", and then realized that the reason it was working in the example project, but was not working in the version on CocoaPods was that v2.0.0 did not include that support.

Integer Table View Cell issues

In _FBTweakTableViewCell the mode is sometimes not set correctly, leading to wrong step values.

Problem:
[value objCType] is only checked for NSInteger and NSUInteger, but not for short, int, long (to name other popular types).

Fix:

  • (void)setTweak:(FBTweak *)tweak
    {
    if (_tweak != tweak) {
    _tweak = tweak;

    self.textLabel.text = tweak.name;

    FBTweakValue value = (_tweak.currentValue ?: _tweak.defaultValue);

    _FBTweakTableViewCellMode mode = _FBTweakTableViewCellModeNone;
    if ([value isKindOfClass:[NSString class]]) {
    mode = _FBTweakTableViewCellModeString;
    } else if ([value isKindOfClass:[NSNumber class]]) {
    // In the 64-bit runtime, BOOL is a real boolean.
    // NSNumber doesn't always agree; compare both.
    const char *objCType=[value objCType];
    if (strcmp(objCType, @encode(char)) == 0 ||
    strcmp(objCType, @encode(_Bool)) == 0) {
    mode = _FBTweakTableViewCellModeBoolean;
    } else if (strcmp(objCType, @encode(NSInteger)) == 0 ||
    strcmp(objCType, @encode(NSUInteger)) == 0 ||
    strcmp(objCType, @encode(short)) == 0 ||
    strcmp(objCType, @encode(unsigned short)) == 0 ||
    strcmp(objCType, @encode(int)) == 0 ||
    strcmp(objCType, @encode(unsigned int)) == 0 ||
    strcmp(objCType, @encode(long)) == 0 ||
    strcmp(objCType, @encode(unsigned long)) == 0
    ) { // jg added int, unsigned int
    mode = _FBTweakTableViewCellModeInteger;
    } else {
    mode = _FBTweakTableViewCellModeReal;
    }
    } else if ([_tweak isAction]) {
    mode = _FBTweakTableViewCellModeAction;
    }

    [self _updateMode:mode];
    [self _updateValue:value primary:YES write:NO];
    }
    }

UIAlertView is deprecated in iOS 9 warning in Xcode 7 GM

Currently when building tweaks into an iOS9 application there will be a depreciation warning regarding UIAlertView:

/Pods/Tweaks/FBTweak/_FBTweakCategoryViewController.m:108:5: 'UIAlertView' is deprecated: first deprecated in iOS 9.0 - UIAlertView is deprecated. Use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert instead

Looks like this method does a check for iOS 8 and uses UIAlertController where appropriate but the deprecation warning is not suppressed.

`FBTweakBind` macro not working after telling Cocoapods to `use_frameworks!`

After switching my project over to using frameworks (by adding use_frameworks! in my Podfile and running pod install), FBTweakBind raises an assertion every time. Here is the offending code:

FBTweakBind(self, host, @"API", @"Host Settings", @"Host", @"https://api.example.com");

This crashes at _FBTweakBindObserver.m:27 where the following assertion failing:

NSAssert(tweak != nil, @"tweak is required");

This was working just fine before the switch to frameworks. If I remove FBTweakBind from my codebase, the app runs just fine. Any ideas?

simple question

why create Tweak and add it by dl_addr and some related function ? Just init it in every _FBTweakInlineWithPossibleInternal is also OK. I suppose there are some pros and I don`t understand.Please help me.
Best regards

Support for UIImage

Ability to pick an image from the camera roll or similar (perhaps with a simple crop rotate and zoom). Or I'm not sure if there is a better way to allow designers to drop in new assets?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.