Skip to content

iOS: scrollViewSetOffset(sv, x, y) ignores y — always scrolls to 0 (FFI takes one offset, binds x) #5200

@proggeramlug

Description

@proggeramlug

Perry version: 0.5.1161 (iOS)

Summary

scrollViewSetOffset(scrollView, x, y) ignores the y argument and always uses x, so any caller that does scrollViewSetOffset(sv, 0, savedY) scrolls to 0 (the top) instead of savedY.

Cause

The dispatch table declares 3 args:

// crates/perry-dispatch/src/ui_table.rs
MethodRow { method: "scrollViewSetOffset", runtime: "perry_ui_scrollview_set_offset",
            args: &[ArgKind::Widget, ArgKind::F64, ArgKind::F64], ret: ReturnKind::Void },

…but the FFI + impl took a single offset and bound it to the first f64 (the x coordinate):

// crates/perry-ui-ios/src/ffi/widgets_basic.rs
pub extern "C" fn perry_ui_scrollview_set_offset(scroll_handle: i64, offset: f64) { ... }
// crates/perry-ui-ios/src/widgets/scrollview.rs
pub fn set_offset(scroll_handle: i64, offset: f64) {
    let point = CGPoint::new(0.0, offset);  // offset = x (usually 0) → contentOffset.y = 0
    msg_send![scroll_view, setContentOffset: point, animated: true];
}

So setContentOffset got (0, x) and x is almost always 0 → scrolls to top.

Impact

Breaks scroll-position restoration across rebuilds in any immediate-mode/rebuild app: every rebuild that calls scrollViewSetOffset(sv, 0, savedY) snaps the view to the top. (Also surfaced as an apparent "the screen jumps to the top whenever I tap a control" in our app.)

Fix (applied locally, PR-able)

Make the FFI/impl take both coordinates, and don't animate (this is used to restore position):

pub extern "C" fn perry_ui_scrollview_set_offset(scroll_handle: i64, x: f64, y: f64) {
    widgets::scrollview::set_offset(scroll_handle, x, y);
}
pub fn set_offset(scroll_handle: i64, x: f64, y: f64) {
    let point = CGPoint::new(x, y);
    let _: () = msg_send![scroll_view, setContentOffset: point, animated: false];
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions