flush_rewrite_rules() not working on updating Settings API

flush_rewrite_rules is firing, but it’s too late; the previous rewrite setting has already determined your register_post_type args at the start of the request, so you’re just flushing the “old” rules.

You could try re-registering the post type just before flushing, but I’m not sure of the wider implications or even if this will work.

If it were me, I’d use the logic you’ve already got to stash a flag in the settings, then handle on the subsequent request:

function my_flush_rules_while_rewrite_changed( $new_values, $old_values ) {
    if( empty( $new_values['rewrite_url'] ) && ! empty( $old_values['rewrite_url'] ) || ! empty( $new_values['rewrite_url'] ) && empty( $old_values['rewrite_url'] ) ) {
        $new_values['flush_rewrite_rules'] = true;
    }

    return $new_values;
}

add_filter( 'pre_update_option_my_custom_settings', 'my_flush_rules_while_rewrite_changed', 11, 2 );

And then as an example:

add_action( 'init', function () {
    $settings = get_option( 'my_custom_settings' );
    if ( ! empty( $settings['flush_rewrite_rules'] ) ) {
        flush_rewrite_rules();
        unset( $settings['flush_rewrite_rules'] );
        update_option( 'my_custom_settings', $settings );
    }
});