Tweak-Tutorial

How do you create a respringless tweak?

Tweak

Open your terminal and create a tweak project, your Tweak.x should look like this:

#import "Tweak.h"


static CGFloat blurIntensity = 0.85f;

static void loadPrefs(void) {

    NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.example.respringlesstweakprefs"];
    blurIntensity = [prefs objectForKey:@"blurIntensity"] ? [prefs floatForKey:@"blurIntensity"] : 0.85;

}

%hook CSCoverSheetViewController

%property (nonatomic, strong) _UIBackdropView *blurView;

%new

- (void)setupBlur {

    _UIBackdropViewSettings *settings = [_UIBackdropViewSettings settingsForStyle:2];

    if(!self.blurView) {
        self.blurView = [[_UIBackdropView alloc] initWithFrame:CGRectZero autosizesToFitSuperview:YES settings:settings];
        self.blurView.alpha = blurIntensity;
        [self.view insertSubview:self.blurView atIndex:0];
    }
}

%new

- (void)updateBlurIntensity {

    loadPrefs();
    self.blurView.alpha = blurIntensity;

}

- (void)viewDidLoad {

    %orig;
    [self setupBlur];

    [NSDistributedNotificationCenter.defaultCenter addObserver:self selector:@selector(updateBlurIntensity) name:@"com.example.respringlesstweakprefs/DidUpdateBlurIntensityNotification" object: nil];

}

%end

%ctor {
    loadPrefs();
}

Then your Tweak.h should have:

@import UIKit;


@interface _UIBackdropViewSettings : NSObject
+ (id)settingsForStyle:(NSInteger)style;
@end


@interface _UIBackdropView : UIView
- (id)initWithFrame:(CGRect)frame autosizesToFitSuperview:(BOOL)autosizes settings:(_UIBackdropViewSettings *)settings;
@end


@interface CSCoverSheetViewController: UIViewController
@property (nonatomic, strong) _UIBackdropView *blurView;
- (void)setupBlur;
@end

@interface NSDistributedNotificationCenter: NSNotificationCenter
@end

Explanation

Now we have to actually make the preferences, so create a preference bundle project, your root view controller should look like this:


#import "RTRootVC.h"

@implementation RTRootVC

- (NSArray *)specifiers {

    if(!_specifiers) _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self];
    return _specifiers;

}

- (void)setPreferenceValue:(id)value specifier:(PSSpecifier *)specifier {

    NSUserDefaults *prefs = [[NSUserDefaults alloc] initWithSuiteName:@"com.example.respringlesstweakprefs"];
    [prefs setObject:value forKey:specifier.properties[@"key"]];

    [super setPreferenceValue:value specifier:specifier];

    if(![specifier.properties[@"key"] isEqualToString: @"blurIntensity"]) return;
    [NSDistributedNotificationCenter.defaultCenter postNotificationName:@"com.example.respringlesstweakprefs/DidUpdateBlurIntensityNotification" object:nil];

}

@end

Then your RTRootVC.h:

@import Preferences.PSListController;
@import Preferences.PSSpecifier;

@interface RTRootVC : PSListController
@end

@interface NSDistributedNotificationCenter : NSNotificationCenter
@end

Previous Page (Substrate Tweaks)

Next Page (Challenges)