Various iOS Ui improvements, especially on iOS 26

This commit is contained in:
Lior Halphon 2025-06-28 00:11:46 +03:00
parent 3f744254fd
commit 583c234953
30 changed files with 146 additions and 39 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

BIN
iOS/Cartridge64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

BIN
iOS/ColorCartridge64.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -119,9 +119,17 @@
[button sizeToFit];
CGRect frame = button.frame;
frame.size.width = ceil(frame.size.width + (label? 4 : 0));
if (@available(iOS 19.0, *)) {
if (label) {
frame.size.width += 12;
}
}
frame.size.height = 28;
button.frame = frame;
return [[UIBarButtonItem alloc] initWithCustomView:button];
UIView *wrapper = [[UIView alloc] initWithFrame:button.bounds];
[wrapper addSubview:button];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:wrapper];
return item;
}
return [[UIBarButtonItem alloc] initWithTitle:label style:UIBarButtonItemStylePlain target:target action:action];
}
@ -178,28 +186,37 @@
hasSFSymbols = true;
}
self.toolbarItems = @[
hasSFSymbols?
[self.class buttonWithLabel:nil
imageWithName:@"square.and.arrow.up"
target:self
action:@selector(exportCheats)] :
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:@selector(exportCheats)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:NULL],
[self.class buttonWithLabel:@"Import"
imageWithName:@"square.and.arrow.down"
UIBarButtonItem *export = hasSFSymbols?
[self.class buttonWithLabel:nil
imageWithName:@"square.and.arrow.up"
target:self
action:@selector(importCheats)],
[self.class buttonWithLabel:@"Add"
imageWithName:@"plus"
target:self
action:@selector(addCheat)],
];
action:@selector(exportCheats)] :
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self
action:@selector(exportCheats)];
UIBarButtonItem *flexItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
target:nil
action:NULL];
UIBarButtonItem *import = [self.class buttonWithLabel:@"Import"
imageWithName:@"square.and.arrow.down"
target:self
action:@selector(importCheats)];
UIBarButtonItem *add = [self.class buttonWithLabel:@"Add"
imageWithName:@"plus"
target:self
action:@selector(addCheat)];
if (@available(iOS 19.0, *)) {
self.toolbarItems = @[export,
flexItem,
import, [UIBarButtonItem fixedSpaceItemOfWidth:0], add];
} else {
self.toolbarItems = @[export,
flexItem,
import, add];
}
_gb = gb;
return self;

View File

@ -283,7 +283,12 @@ static NSString *const tips[] = {
button.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.3];
button.layer.borderWidth = 2.0;
button.layer.borderColor = [UIColor systemBlueColor].CGColor;
button.layer.cornerRadius = 8.0;
if (@available(iOS 19.0, *)) {
button.layer.cornerRadius = 32.0;
}
else {
button.layer.cornerRadius = 8.0;
}
}
else {
button.backgroundColor = [UIColor clearColor];

View File

@ -247,8 +247,8 @@
if ([newName containsString:@"/"]) {
[self.tableView reloadData];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"You can't use a name that contains “/”. Please choose another name."
message:nil
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Invalid Name"
message:@"You can't use a name that contains “/”. Please choose another name."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleCancel

View File

@ -22,6 +22,7 @@ static NSString const *typeLightTemp = @"typeLightTemp";
NSArray<NSDictionary *> *_structure;
UINavigationController *_detailsNavigation;
NSArray<NSArray<GBTheme *> *> *_themes; // For prewarming
bool _iPadRoot;
}
+ (UIImage *)settingsImageNamed:(NSString *)name
@ -187,7 +188,7 @@ static NSString const *typeLightTemp = @"typeLightTemp";
@{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"HQ2x", @"value": @"HQ2x"},
@{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"OmniScale", @"value": @"OmniScale"},
@{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"OmniScale Legacy", @"value": @"OmniScaleLegacy"},
@{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"AA OmniScale Legacy", @"value": @"AAOmniScaleLegacy"},
@{@"type": typeRadio, @"pref": @"GBFilter", @"title": @"Anti-aliased OmniScale Legacy", @"value": @"AAOmniScaleLegacy"},
]
},
]
@ -434,12 +435,20 @@ static NSString const *typeLightTemp = @"typeLightTemp";
return controller;
}
UISplitViewController *split = [[UISplitViewController alloc] init];
UISplitViewController *split = nil;
if (@available(iOS 14.5, *)) {
split = [[UISplitViewController alloc] initWithStyle:UISplitViewControllerStyleDoubleColumn];
split.displayModeButtonVisibility = UISplitViewControllerDisplayModeButtonVisibilityNever;
}
else {
split = [[UISplitViewController alloc] init];
}
UIViewController *blank = [[UIViewController alloc] init];
blank.view.backgroundColor = root.view.backgroundColor;
root->_detailsNavigation = [[UINavigationController alloc] initWithRootViewController:blank];
split.viewControllers = @[controller, root->_detailsNavigation];
split.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;
root->_iPadRoot = true;
return split;
}
@ -729,7 +738,6 @@ static id ValueForItem(NSDictionary *item)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *item = [self itemForIndexPath:indexPath];
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
cell.textLabel.text = item[@"title"];
@ -833,6 +841,13 @@ static id ValueForItem(NSDictionary *item)
cell.separatorInset = UIEdgeInsetsZero;
}
cell.imageView.image = item[@"image"];
if (@available(iOS 19.0, *)) {
if (_iPadRoot) {
cell.textLabel.textColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) {
return cell.isSelected? [UIColor whiteColor] : [UIColor labelColor];
}];
}
}
return cell;
}

View File

@ -21,11 +21,15 @@ static inline void temperature_tint(double temperature, double *r, double *g, do
}
@implementation GBSlider
{
GBSliderStyle _style;
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
[self addTarget:self action:@selector(valueChanged) forControlEvents:UIControlEventValueChanged];
self.style = GBSliderStyleTemperature;
return self;
}
@ -97,6 +101,10 @@ static inline void temperature_tint(double temperature, double *r, double *g, do
- (void)drawRect:(CGRect)rect
{
bool solarium = false;
if (@available(iOS 19.0, *)) {
solarium = true;
}
CGSize size = self.bounds.size;
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(2, round(size.height / 2 - 1.5), size.width - 4, 3) cornerRadius:4];
if (_style != GBSliderStyleHue) {
@ -107,7 +115,7 @@ static inline void temperature_tint(double temperature, double *r, double *g, do
[path appendPath:[UIBezierPath bezierPathWithRoundedRect:CGRectMake(size.width - 3, 12, 3, size.height - 24) cornerRadius:4]];
}
if (_style == GBSliderStyleHue) {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(3, round(size.height / 2 - 1.5) + 1, size.width - 6, 1) cornerRadius:4];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(3, round(size.height / 2 - 1.5) + 1 - solarium, size.width - 6, solarium? 2 : 1) cornerRadius:8];
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
[path addClip];
@ -124,11 +132,12 @@ static inline void temperature_tint(double temperature, double *r, double *g, do
};
CFArrayRef colorsArray = CFArrayCreate(NULL, (const void **)colors, 7, &kCFTypeArrayCallBacks);
CGGradientRef gradient = CGGradientCreateWithColors(colorspace, colorsArray, NULL);
unsigned spacing = solarium? 16 : 3;
CGContextDrawLinearGradient(context,
gradient,
(CGPoint){3, 0},
(CGPoint){size.width - 3, 0},
0);
(CGPoint){spacing, 0},
(CGPoint){size.width - spacing, 0},
kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CFRelease(gradient);
CFRelease(colorsArray);
CFRelease(colorspace);
@ -139,11 +148,44 @@ static inline void temperature_tint(double temperature, double *r, double *g, do
green:120 / 255.0
blue:130 / 255.0
alpha:70 / 255.0] set];
[path fill];
if (!solarium) {
[path fill];
}
[super drawRect:rect];
}
- (void)setStyle:(GBSliderStyle)style
{
_style = style;
if (@available(iOS 26.0, *)) {
switch (_style) {
case GBSliderStyleTemperature:
case GBSliderStyleTicks: {
UISliderTrackConfiguration *conf = [UISliderTrackConfiguration configurationWithNumberOfTicks:3];
conf.allowsTickValuesOnly = false;
conf.neutralValue = 0.5;
self.trackConfiguration = conf;
self.maximumTrackTintColor = nil;
self.minimumTrackTintColor = nil;
break;
}
case GBSliderStyleHue: {
UISliderTrackConfiguration *conf = [UISliderTrackConfiguration configurationWithNumberOfTicks:0];
conf.allowsTickValuesOnly = false;
self.trackConfiguration = conf;
self.minimumTrackTintColor = [UIColor clearColor];
break;
}
}
}
}
- (GBSliderStyle)style
{
return _style;
}
- (void)setFrame:(CGRect)frame
{
[super setFrame:frame];

View File

@ -39,8 +39,8 @@
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.bounds = CGRectMake(0, 0, 0x300, 0x300);
UIView *root = self.view;
UIView *root = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0x300, 0x300)];
[self.view addSubview:root];
for (unsigned i = 0; i < 9; i++) {
unsigned x = i % 3;
unsigned y = i / 3;
@ -114,6 +114,12 @@
[self presentViewController:controller animated:true completion:nil];
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
self.view.subviews.firstObject.frame = [self.view.safeAreaLayoutGuide layoutFrame];
}
- (NSString *)title
{
return @"Save States";

View File

@ -65,8 +65,8 @@
- (void)showPopup
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Apply “%@” as the current theme?", _verticalLayout.theme.name]
message:nil
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Apply Theme"
message:[NSString stringWithFormat:@"Apply “%@” as the current theme?", _verticalLayout.theme.name]
preferredStyle:[UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad?
UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet];
if (false) {

View File

@ -1814,8 +1814,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
{
UIAlertControllerStyle style = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad?
UIAlertControllerStyleAlert : UIAlertControllerStyleActionSheet;
GBCheckableAlertController *menu = [GBCheckableAlertController alertControllerWithTitle:@"Connect which accessory?"
message:nil
GBCheckableAlertController *menu = [GBCheckableAlertController alertControllerWithTitle:@"Connect Accessory"
message:@"Choose an accessory to connect."
preferredStyle:style];
[menu addAction:[UIAlertAction actionWithTitle:@"None"
style:UIAlertActionStyleDefault

View File

@ -63,6 +63,7 @@
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>Cartridge64.png</string>
<string>Cartridge.png</string>
</array>
<key>CFBundleTypeExtensions</key>
@ -81,6 +82,7 @@
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>ColorCartridge64.png</string>
<string>ColorCartridge.png</string>
</array>
<key>CFBundleTypeExtensions</key>
@ -99,6 +101,7 @@
<dict>
<key>CFBundleTypeIconFiles</key>
<array>
<string>ColorCartridge64.png</string>
<string>ColorCartridge.png</string>
</array>
<key>CFBundleTypeExtensions</key>
@ -157,6 +160,12 @@
<string>gb</string>
</array>
</dict>
<key>UTTypeIconFiles</key>
<array>
<string>Cartridge64</string>
<string>Cartridge</string>
</array>
</dict>
<dict>
<key>UTTypeConformsTo</key>
@ -174,6 +183,11 @@
<string>gbc</string>
</array>
</dict>
<key>UTTypeIconFiles</key>
<array>
<string>ColorCartridge64</string>
<string>ColorCartridge</string>
</array>
</dict>
<dict>
<key>UTTypeConformsTo</key>
@ -191,6 +205,11 @@
<string>isx</string>
</array>
</dict>
<key>UTTypeIconFiles</key>
<array>
<string>ColorCartridge64</string>
<string>ColorCartridge</string>
</array>
</dict>
<dict>
<key>UTTypeConformsTo</key>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -146,6 +146,9 @@ int main(int argc, char * argv[])
@"Manual": @NO,
},
},
// Forces iOS to use Solarium even when linking against older SDKs
@"com.apple.SwiftUI.IgnoreSolariumLinkedOnCheck": @YES,
}];
if (![[defaults stringForKey:@"GBThemesVersion"] isEqualToString:@(GB_VERSION)]) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 87 KiB

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 188 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB