├── .github └── ISSUE_TEMPLATE │ ├── bug-report.md │ ├── feature-request.md │ └── feature_request.md ├── .gitignore ├── Example ├── ACDRootListController.h ├── ACDRootListController.m ├── Makefile ├── Resources │ ├── Info.plist │ ├── Root.plist │ ├── dark.png │ ├── default.png │ ├── icon.png │ └── light.png └── entry.plist ├── LICENSE ├── Library ├── AppearanceSelectionTableCell.m ├── Makefile ├── libappearancecell+UIColor.m └── private │ ├── AppearanceSelectionTableCell.h │ └── libappearancecell-private.h ├── Makefile ├── README.md ├── control └── libappearancecell.h /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug that exists in libappearancecell 4 | title: "[Bug]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Device Information (please complete the following information):** 27 | - iOS Version: [e.g. 13.5] 28 | - Device [e.g. iPhone X, iPhone 11 Pro] 29 | - Jailbreak + Bootstrap [e.g. checkra1n (oddessyra1n), unc0ver (default)] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest an idea for libappearancecell 4 | title: "[Feature]" 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Additional context** 17 | Add any other context or screenshots about the feature request here. 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .theos/ 2 | packages/ 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /Example/ACDRootListController.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface ACDRootListController : PSListController 5 | @end 6 | -------------------------------------------------------------------------------- /Example/ACDRootListController.m: -------------------------------------------------------------------------------- 1 | #include "ACDRootListController.h" 2 | 3 | @implementation ACDRootListController 4 | 5 | - (NSArray *)specifiers { 6 | if (!_specifiers) { 7 | _specifiers = [self loadSpecifiersFromPlistName:@"Root" target:self]; 8 | } 9 | 10 | return _specifiers; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = iphone:clang:13.0:11.0 2 | ARCHS = arm64 arm64e 3 | INSTALL_TARGETS_PROCESS = Preferences 4 | 5 | include $(THEOS)/makefiles/common.mk 6 | 7 | BUNDLE_NAME = libappearancecell_demo 8 | 9 | libappearancecell_demo_FILES = ACDRootListController.m 10 | libappearancecell_demo_INSTALL_PATH = /Library/PreferenceBundles 11 | libappearancecell_demo_FRAMEWORKS = UIKit 12 | libappearancecell_demo_LIBRARIES = appearancecell 13 | libappearancecell_demo_PRIVATE_FRAMEWORKS = Preferences 14 | libappearancecell_demo_CFLAGS = -fobjc-arc 15 | 16 | internal-stage:: 17 | $(ECHO_NOTHING)mkdir -p $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences$(ECHO_END) 18 | $(ECHO_NOTHING)cp entry.plist $(THEOS_STAGING_DIR)/Library/PreferenceLoader/Preferences/libappearancecell_demo.plist$(ECHO_END) 19 | 20 | include $(THEOS_MAKE_PATH)/bundle.mk 21 | -------------------------------------------------------------------------------- /Example/Resources/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | libappearancecell_demo 9 | CFBundleIdentifier 10 | me.conorthedev.libappearancecell.demo 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1.0 21 | NSPrincipalClass 22 | ACDRootListController 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Resources/Root.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | items 6 | 7 | 8 | cell 9 | PSGroupCell 10 | label 11 | Example 12 | 13 | 14 | cell 15 | PSDefaultCell 16 | cellClass 17 | AppearanceSelectionTableCell 18 | options 19 | 20 | 21 | text 22 | Light 23 | image 24 | light 25 | 26 | 27 | text 28 | Dark 29 | image 30 | dark 31 | 32 | 33 | text 34 | Default 35 | image 36 | default 37 | 38 | 39 | defaults 40 | me.conorthedev.libappearancecell.demo 41 | PostNotification 42 | me.conorthedev.libappearancecell.demo/reload 43 | key 44 | appearance 45 | height 46 | 210 47 | 48 | 49 | cell 50 | PSGroupCell 51 | label 52 | Example with Tint Color 53 | 54 | 55 | cell 56 | PSDefaultCell 57 | cellClass 58 | AppearanceSelectionTableCell 59 | options 60 | 61 | 62 | text 63 | Light 64 | image 65 | light 66 | 67 | 68 | text 69 | Dark 70 | image 71 | dark 72 | 73 | 74 | defaults 75 | me.conorthedev.libappearancecell.demo 76 | PostNotification 77 | me.conorthedev.libappearancecell.demo/reload 78 | key 79 | appearanceTint 80 | height 81 | 210 82 | tintColor 83 | #00FF00 84 | 85 | 86 | title 87 | libappearancecell 88 | 89 | 90 | -------------------------------------------------------------------------------- /Example/Resources/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/conorthedev/libappearancecell/fa7694f83ec7da4e44faadd3bda0697014b7fe17/Example/Resources/dark.png -------------------------------------------------------------------------------- /Example/Resources/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/conorthedev/libappearancecell/fa7694f83ec7da4e44faadd3bda0697014b7fe17/Example/Resources/default.png -------------------------------------------------------------------------------- /Example/Resources/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/conorthedev/libappearancecell/fa7694f83ec7da4e44faadd3bda0697014b7fe17/Example/Resources/icon.png -------------------------------------------------------------------------------- /Example/Resources/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/conorthedev/libappearancecell/fa7694f83ec7da4e44faadd3bda0697014b7fe17/Example/Resources/light.png -------------------------------------------------------------------------------- /Example/entry.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | entry 6 | 7 | bundle 8 | libappearancecell_demo 9 | cell 10 | PSLinkCell 11 | detail 12 | ACDRootListController 13 | icon 14 | icon.png 15 | isController 16 | 17 | label 18 | libappearancecell 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /Library/AppearanceSelectionTableCell.m: -------------------------------------------------------------------------------- 1 | #import "private/AppearanceSelectionTableCell.h" 2 | 3 | @implementation AppearanceTypeStackView 4 | 5 | - (AppearanceTypeStackView *)initWithType:(int)type forController:(AppearanceSelectionTableCell *)controller withImage:(UIImage *)image andText:(NSString *)text andSpecifier:(PSSpecifier *)specifier { 6 | self = [super init]; 7 | if (self) { 8 | self.type = type; 9 | self.hostController = controller; 10 | 11 | self.key = specifier.properties[@"key"]; 12 | self.postNotification = specifier.properties[@"PostNotification"]; 13 | self.tintColor = specifier.properties[@"tintColor"]; 14 | 15 | self.feedbackGenerator = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleMedium]; 16 | [self.feedbackGenerator prepare]; 17 | 18 | self.defaults = [[NSUserDefaults alloc] initWithSuiteName:specifier.properties[@"defaults"]]; 19 | [self.defaults registerDefaults:@{ self.key : @0 }]; 20 | 21 | self.axis = UILayoutConstraintAxisVertical; 22 | self.alignment = UIStackViewAlignmentCenter; 23 | self.distribution = UIStackViewDistributionEqualSpacing; 24 | self.spacing = 8; 25 | self.translatesAutoresizingMaskIntoConstraints = false; 26 | 27 | self.iconView = [[UIImageView alloc] init]; 28 | self.iconView.clipsToBounds = YES; 29 | self.iconView.contentMode = UIViewContentModeScaleAspectFit; 30 | self.iconView.translatesAutoresizingMaskIntoConstraints = false; 31 | self.iconView.image = image; 32 | 33 | [self addArrangedSubview:self.iconView]; 34 | [self.iconView.widthAnchor constraintEqualToConstant:60].active = true; 35 | 36 | self.captionLabel = [[UILabel alloc] init]; 37 | self.captionLabel.text = text; 38 | [self.captionLabel setFont:[UIFont systemFontOfSize:17.0f]]; 39 | [self.captionLabel.heightAnchor constraintEqualToConstant:20].active = true; 40 | 41 | [self addArrangedSubview:self.captionLabel]; 42 | 43 | if (@available(iOS 13.0, *)) { 44 | [self.captionLabel setTextColor:[UIColor labelColor]]; 45 | } else { 46 | [self.captionLabel setTextColor:[UIColor blackColor]]; 47 | } 48 | 49 | self.checkmarkButton = [UIButton buttonWithType:UIButtonTypeCustom]; 50 | self.checkmarkButton.translatesAutoresizingMaskIntoConstraints = false; 51 | self.checkmarkButton.selected = [[self.defaults objectForKey:self.key] intValue] == self.type; 52 | self.checkmarkButton.tintColor = (self.checkmarkButton.selected) ? (self.tintColor ? [UIColor colorFromHexString:self.tintColor] : [UIColor systemBlueColor]) : [UIColor systemGrayColor]; 53 | [self.checkmarkButton.heightAnchor constraintEqualToConstant:22].active = true; 54 | [self.checkmarkButton.widthAnchor constraintEqualToConstant:22].active = true; 55 | 56 | [self.checkmarkButton setImage:[[UIImage kitImageNamed:@"UIRemoveControlMultiNotCheckedImage.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateNormal]; 57 | [self.checkmarkButton setImage:[[UIImage kitImageNamed:@"UITintedCircularButtonCheckmark.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forState:UIControlStateSelected]; 58 | [self.checkmarkButton addTarget:self action:@selector(buttonTapped) forControlEvents:UIControlEventTouchUpInside]; 59 | [self addArrangedSubview:self.checkmarkButton]; 60 | 61 | self.tapGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(buttonTapped:)]; 62 | self.tapGestureRecognizer.minimumPressDuration = 0; 63 | [self setUserInteractionEnabled:true]; 64 | [self addGestureRecognizer:self.tapGestureRecognizer]; 65 | } 66 | 67 | return self; 68 | } 69 | 70 | - (void)buttonTapped:(UILongPressGestureRecognizer *)sender { 71 | if(sender.state == UIGestureRecognizerStateBegan) { 72 | [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 73 | self.alpha = 0.5; 74 | } completion:^(BOOL finished) {}]; 75 | } else if (sender.state == UIGestureRecognizerStateEnded) { 76 | [UIView animateWithDuration:0.1 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 77 | self.alpha = 1; 78 | [self.hostController updateForType:self.type]; 79 | } completion:^(BOOL finished) {}]; 80 | 81 | [self.feedbackGenerator impactOccurred]; 82 | 83 | [self.defaults setObject:[NSNumber numberWithInt:self.type] forKey:self.key]; 84 | [self.defaults synchronize]; 85 | 86 | if(self.postNotification) { 87 | CFNotificationCenterPostNotification(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge CFStringRef)self.postNotification, NULL, NULL, true); 88 | } 89 | } 90 | } 91 | 92 | @end 93 | 94 | @implementation AppearanceSelectionTableCell 95 | 96 | - (AppearanceSelectionTableCell *)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier specifier:(PSSpecifier *)specifier { 97 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier specifier:specifier]; 98 | 99 | if (self) { 100 | NSBundle *prefsBundle = [NSBundle bundleForClass:[specifier.target class]]; 101 | self.options = specifier.properties[@"options"]; 102 | 103 | self.containerStackView = [[UIStackView alloc] init]; 104 | self.containerStackView.axis = UILayoutConstraintAxisHorizontal; 105 | self.containerStackView.alignment = UIStackViewAlignmentCenter; 106 | self.containerStackView.distribution = UIStackViewDistributionEqualSpacing; 107 | self.containerStackView.spacing = 60; 108 | self.containerStackView.translatesAutoresizingMaskIntoConstraints = false; 109 | 110 | for (NSDictionary *option in self.options) { 111 | AppearanceTypeStackView *stackView = [[AppearanceTypeStackView alloc] initWithType:[self.options indexOfObject:option] 112 | forController:self 113 | withImage:[UIImage imageNamed:option[@"image"] inBundle:prefsBundle compatibleWithTraitCollection:NULL] 114 | andText:option[@"text"] 115 | andSpecifier:specifier]; 116 | [self.containerStackView addArrangedSubview:stackView]; 117 | [stackView.topAnchor constraintEqualToAnchor:self.containerStackView.topAnchor constant:16].active = true; 118 | [stackView.bottomAnchor constraintEqualToAnchor:self.containerStackView.bottomAnchor constant:-16].active = true; 119 | } 120 | 121 | [self.contentView addSubview:self.containerStackView]; 122 | 123 | [self.containerStackView.heightAnchor constraintEqualToAnchor:self.heightAnchor].active = true; 124 | [self.containerStackView.centerXAnchor constraintEqualToAnchor:self.centerXAnchor].active = true; 125 | [self.containerStackView.centerYAnchor constraintEqualToAnchor:self.centerYAnchor].active = true; 126 | } 127 | 128 | return self; 129 | } 130 | 131 | - (AppearanceSelectionTableCell *)initWithSpecifier:(PSSpecifier *)specifier { 132 | self = [self initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AppearanceSelectionTableCell" specifier:specifier]; 133 | return self; 134 | } 135 | 136 | - (void)updateForType:(int)type { 137 | for (AppearanceTypeStackView *subview in self.containerStackView.arrangedSubviews) { 138 | subview.checkmarkButton.selected = subview.type == type; 139 | subview.checkmarkButton.tintColor = (subview.checkmarkButton.selected) ? (subview.tintColor ? [UIColor colorFromHexString:subview.tintColor] : [UIColor systemBlueColor]) : [UIColor systemGrayColor]; 140 | } 141 | } 142 | 143 | @end -------------------------------------------------------------------------------- /Library/Makefile: -------------------------------------------------------------------------------- 1 | TARGET = iphone:clang:13.0:11.0 2 | ARCHS = arm64 arm64e 3 | 4 | include $(THEOS)/makefiles/common.mk 5 | 6 | LIBRARY_NAME = libappearancecell 7 | 8 | libappearancecell_FILES = $(wildcard *.m) 9 | libappearancecell_CFLAGS = -fobjc-arc 10 | libappearancecell_FRAMEWORKS = UIKit 11 | libappearancecell_PRIVATE_FRAMEWORKS = Preferences 12 | 13 | after-all:: 14 | cp ../.theos/obj/libappearancecell.dylib $(THEOS)/lib 15 | mkdir -p $(THEOS_STAGING_DIR)/usr/include/libappearancecell 16 | cp ../libappearancecell.h $(THEOS_STAGING_DIR)/usr/include/libappearancecell 17 | mkdir -p $(THEOS)/include/libappearancecell/ 18 | cp ../libappearancecell.h $(THEOS)/include/libappearancecell/libappearancecell.h 19 | 20 | include $(THEOS_MAKE_PATH)/library.mk 21 | include $(THEOS_MAKE_PATH)/aggregate.mk 22 | -------------------------------------------------------------------------------- /Library/libappearancecell+UIColor.m: -------------------------------------------------------------------------------- 1 | #import "private/AppearanceSelectionTableCell.h" 2 | 3 | @implementation UIColor (libappearancecell) 4 | + (UIColor *)colorFromHexString:(NSString *)hexString { 5 | unsigned rgbValue = 0; 6 | NSScanner *scanner = [NSScanner scannerWithString:hexString]; 7 | [scanner setScanLocation:1]; 8 | [scanner scanHexInt:&rgbValue]; 9 | return [UIColor colorWithRed:((rgbValue & 0xFF0000) >> 16)/255.0 green:((rgbValue & 0xFF00) >> 8)/255.0 blue:(rgbValue & 0xFF)/255.0 alpha:1.0]; 10 | } 11 | @end -------------------------------------------------------------------------------- /Library/private/AppearanceSelectionTableCell.h: -------------------------------------------------------------------------------- 1 | #import "../../libappearancecell.h" 2 | #import "libappearancecell-private.h" 3 | #import 4 | #import 5 | 6 | @interface AppearanceTypeStackView : UIStackView 7 | @property(nonatomic, retain) AppearanceSelectionTableCell *hostController; 8 | 9 | @property(nonatomic, retain) UIImageView *iconView; 10 | @property(nonatomic, retain) UILabel *captionLabel; 11 | @property(nonatomic, retain) UIButton *checkmarkButton; 12 | 13 | @property(nonatomic, retain) UIImpactFeedbackGenerator *feedbackGenerator; 14 | @property(nonatomic, retain) UILongPressGestureRecognizer *tapGestureRecognizer; 15 | 16 | @property(nonatomic, assign) int type; 17 | @property(nonatomic, retain) NSString *defaultsIdentifier; 18 | @property(nonatomic, retain) NSString *postNotification; 19 | @property(nonatomic, retain) NSString *key; 20 | @property(nonatomic, retain) NSString *tintColor; 21 | @property(nonatomic, retain) NSUserDefaults *defaults; 22 | 23 | - (AppearanceTypeStackView *)initWithType:(int)type forController:(AppearanceSelectionTableCell *)controller withImage:(UIImage *)image andText:(NSString *)text andSpecifier:(PSSpecifier *)specifier; 24 | - (void)buttonTapped:(UILongPressGestureRecognizer *)sender; 25 | @end -------------------------------------------------------------------------------- /Library/private/libappearancecell-private.h: -------------------------------------------------------------------------------- 1 | @interface UIImage (Private) 2 | + (UIImage*)kitImageNamed:(NSString*)name; 3 | @end 4 | 5 | @interface UIColor (libappearancecell) 6 | + (UIColor *)colorFromHexString:(NSString *)hexString; 7 | @end 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | include $(THEOS)/makefiles/common.mk 2 | 3 | SUBPROJECTS += Library 4 | 5 | ifeq ($(DEBUG), 1) 6 | SUBPROJECTS += Example 7 | endif 8 | 9 | include $(THEOS_MAKE_PATH)/aggregate.mk 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # libappearancecell 4 | libappearancecell is a library for jailbroken iOS devices that allows developers to use an iOS 13-style appearance selector in their Preferences. 5 | 6 | ## Usage 7 | The setup of libappearancecell is very simple, just follow these 5 simple steps and you should be good to go! 8 | - 1: Copy neccessary files 9 | - Copy ``libappearancecell.h`` from this repository to ``$THEOS/include/libappearancecell`` 10 | - Copy ``libappearancecell.dylib`` from your device to ``$THEOS/lib`` 11 | - 2: Link libappearancecell in your bundle 12 | - Add ``appearancecell`` to your LIBRARIES in Preferences Makefile 13 | - Example: 14 | ``` 15 | MyBundle_LIBRARIES = appearancecell 16 | ``` 17 | - 3: Make sure your project depends on libappearancecell 18 | - control: 19 | ``` 20 | Depends: me.conorthedev.libappearancecell 21 | ``` 22 | - 4: Import libappearancecell 23 | ```objc 24 | #import 25 | ``` 26 | - 5: Check out the example below for how to use it in your Preferences! 27 | 28 | ## Documentation 29 | [You can find details on setting up and using libappearancecell on the wiki](https://github.com/cbyrne/libappearancecell/wiki) 30 | 31 | ## Preference Bundle Example 32 | If you're a bit stuck on the integration, there's an example of a working Preference Bundle [here](https://github.com/cbyrne/libappearancecell/tree/master/Example). 33 | -------------------------------------------------------------------------------- /control: -------------------------------------------------------------------------------- 1 | Package: me.conorthedev.libappearancecell 2 | Name: libappearancecell 3 | Version: 1.0.2 4 | Architecture: iphoneos-arm 5 | Description: A library for that allows developers to use an iOS 13-style appearance selector in their Preferences. 6 | Maintainer: ConorTheDev 7 | Author: ConorTheDev 8 | Section: System 9 | Tag: role::developer 10 | -------------------------------------------------------------------------------- /libappearancecell.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface AppearanceSelectionTableCell : PSTableCell 4 | @property(nonatomic, retain) UIStackView *containerStackView; 5 | @property(nonatomic, retain) NSArray *options; 6 | 7 | - (void)updateForType:(int)type; 8 | @end 9 | --------------------------------------------------------------------------------