UIKitPlatform now reads `[UIView safeAreaInsets]` (UIEdgeInsets = 32-byte
struct: top, left, bottom, right CGFloats) in begin_frame, and subscribes
to UIKeyboardWillChangeFrameNotification on NSNotificationCenter. The
chess game's build_ui pads its root by `g_safe_insets`, so the Dynamic
Island no longer overlaps the board on iPhone 17 Pro — all 8 ranks and
files are visible.
Struct returns >16 bytes (UIEdgeInsets, CGRect) go through the arm64
x8 indirect-result-pointer convention; expressing the return type on a
typed `objc_msgSend` fn-pointer cast generates the right call sequence.
Same pattern used to unwrap the keyboard's CGRect from NSValue
(UIKeyboardFrameEndUserInfoKey).
show_keyboard / hide_keyboard now drive a hidden UITextField subview as
the firstResponder source. resignFirstResponder dismisses; observer
fires with height=0 → safe_insets bottom collapses.
Deferred (next iteration): wrap the inset update in
[UIView animateWithDuration: animations:^{ ... }] to land in the same
CoreAnimation transaction as the keyboard. sx doesn't have block
syntax yet — we'd need a C shim that takes an fn-ptr and builds the
block. Today the inset snaps while the keyboard slides; the lag is
visible but the rest of the wiring is in place.
examples/66-uikit-platform.sx updated: each tap toggles the keyboard
+ advances the clear color (red→green→blue), so the observer can be
observed firing via the visible keyboard slide.
65 lines
2.0 KiB
Plaintext
65 lines
2.0 KiB
Plaintext
// UIKitPlatform end-to-end smoke: boots the AppDelegate, installs an
|
|
// SxGLView with a CAEAGLLayer + GLES3 context + CADisplayLink, polls
|
|
// UITouch events into ui.Event, and on every vsync clears the screen
|
|
// to a color that advances on each tap. Each tap also toggles the
|
|
// on-screen keyboard so safe_insets.bottom can be observed growing /
|
|
// shrinking under it.
|
|
//
|
|
// Build + run:
|
|
// sx build --target ios-sim examples/66-uikit-platform.sx \
|
|
// -o /tmp/SxUIKitBoot --bundle /tmp/SxUIKitBoot.app \
|
|
// --bundle-id co.swipelab.sxuikit -F ~/Library/Frameworks
|
|
// xcrun simctl install booted /tmp/SxUIKitBoot.app
|
|
// xcrun simctl launch --console booted co.swipelab.sxuikit
|
|
// xcrun simctl io booted screenshot /tmp/screen.png
|
|
|
|
#import "modules/std.sx";
|
|
#import "modules/std/uikit.sx";
|
|
#framework "OpenGLES";
|
|
#framework "QuartzCore";
|
|
#import "modules/opengl.sx";
|
|
#import "modules/ui/types.sx";
|
|
#import "modules/ui/events.sx";
|
|
#import "modules/platform/uikit.sx";
|
|
|
|
g_color_index : s64 = 0;
|
|
g_keyboard_up : bool = false;
|
|
|
|
tap_frame :: () {
|
|
fc := g_uikit_plat.begin_frame();
|
|
|
|
events := g_uikit_plat.poll_events();
|
|
i : s64 = 0;
|
|
while i < events.len {
|
|
ev := events.ptr[i];
|
|
if ev == {
|
|
case .mouse_down: {
|
|
g_color_index += 1;
|
|
if g_keyboard_up {
|
|
g_uikit_plat.hide_keyboard();
|
|
g_keyboard_up = false;
|
|
} else {
|
|
g_uikit_plat.show_keyboard();
|
|
g_keyboard_up = true;
|
|
}
|
|
}
|
|
}
|
|
i += 1;
|
|
}
|
|
|
|
phase := g_color_index % 3;
|
|
r : f32 = if phase == 0 then 0.8 else 0.1;
|
|
g : f32 = if phase == 1 then 0.8 else 0.1;
|
|
b : f32 = if phase == 2 then 0.8 else 0.1;
|
|
glViewport(0, 0, fc.pixel_w, fc.pixel_h);
|
|
glClearColor(r, g, b, 1.0);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
g_uikit_plat.end_frame();
|
|
}
|
|
|
|
main :: () -> void {
|
|
plat : *UIKitPlatform = xx malloc(size_of(UIKitPlatform));
|
|
plat.init("SxUIKitPlatform", 0, 0);
|
|
plat.run_frame_loop(closure(tap_frame));
|
|
}
|