Skip to content

Commit

Permalink
Implement push view for ios. (DioxusLabs#612)
Browse files Browse the repository at this point in the history
  • Loading branch information
dvc94ch authored Nov 22, 2022
1 parent 99dafdb commit 1e99e35
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ dunce = "1.0.2"

interprocess = { version = "1.1.1" }

[target.'cfg(target_os = "ios")'.dependencies]
objc = "0.2.7"
objc_id = "0.1.1"

[target.'cfg(target_os = "macos")'.dependencies]
core-foundation = "0.9.3"

Expand Down
6 changes: 6 additions & 0 deletions packages/desktop/src/controller.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::desktop_context::{DesktopContext, UserWindowEvent};

use dioxus_core::*;
#[cfg(target_os = "ios")]
use objc::runtime::Object;
use std::{
collections::HashMap,
sync::Arc,
Expand All @@ -18,6 +20,8 @@ pub(super) struct DesktopController {
pub(super) pending_edits: Arc<Mutex<Vec<String>>>,
pub(super) quit_app_on_close: bool,
pub(super) is_ready: Arc<AtomicBool>,
#[cfg(target_os = "ios")]
pub(super) views: Vec<*mut Object>,
}

impl DesktopController {
Expand Down Expand Up @@ -87,6 +91,8 @@ impl DesktopController {
webviews: HashMap::new(),
is_ready: Arc::new(AtomicBool::new(false)),
quit_app_on_close: true,
#[cfg(target_os = "ios")]
views: vec![],
}
}

Expand Down
55 changes: 55 additions & 0 deletions packages/desktop/src/desktop_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use crate::controller::DesktopController;
use dioxus_core::ScopeState;
use wry::application::event_loop::ControlFlow;
use wry::application::event_loop::EventLoopProxy;
#[cfg(target_os = "ios")]
use wry::application::platform::ios::WindowExtIOS;
use wry::application::window::Fullscreen as WryFullscreen;

use UserWindowEvent::*;
Expand Down Expand Up @@ -134,6 +136,18 @@ impl DesktopContext {
pub fn eval(&self, script: impl std::string::ToString) {
let _ = self.proxy.send_event(Eval(script.to_string()));
}

/// Push view
#[cfg(target_os = "ios")]
pub fn push_view(&self, view: objc_id::ShareId<objc::runtime::Object>) {
let _ = self.proxy.send_event(PushView(view));
}

/// Push view
#[cfg(target_os = "ios")]
pub fn pop_view(&self) {
let _ = self.proxy.send_event(PopView);
}
}

#[derive(Debug)]
Expand Down Expand Up @@ -164,6 +178,11 @@ pub enum UserWindowEvent {
DevTool,

Eval(String),

#[cfg(target_os = "ios")]
PushView(objc_id::ShareId<objc::runtime::Object>),
#[cfg(target_os = "ios")]
PopView,
}

pub(super) fn handler(
Expand Down Expand Up @@ -231,6 +250,32 @@ pub(super) fn handler(
log::warn!("Eval script error: {e}");
}
}

#[cfg(target_os = "ios")]
PushView(view) => unsafe {
use objc::runtime::Object;
use objc::*;
assert!(is_main_thread());
let ui_view = window.ui_view() as *mut Object;
let ui_view_frame: *mut Object = msg_send![ui_view, frame];
let _: () = msg_send![view, setFrame: ui_view_frame];
let _: () = msg_send![view, setAutoresizingMask: 31];

let ui_view_controller = window.ui_view_controller() as *mut Object;
let _: () = msg_send![ui_view_controller, setView: view];
desktop.views.push(ui_view);
},

#[cfg(target_os = "ios")]
PopView => unsafe {
use objc::runtime::Object;
use objc::*;
assert!(is_main_thread());
if let Some(view) = desktop.views.pop() {
let ui_view_controller = window.ui_view_controller() as *mut Object;
let _: () = msg_send![ui_view_controller, setView: view];
}
},
}
}

Expand All @@ -240,3 +285,13 @@ pub fn use_eval<S: std::string::ToString>(cx: &ScopeState) -> &dyn Fn(S) {

cx.use_hook(|| move |script| desktop.eval(script))
}

#[cfg(target_os = "ios")]
fn is_main_thread() -> bool {
use objc::runtime::{Class, BOOL, NO};
use objc::*;

let cls = Class::get("NSThread").unwrap();
let result: BOOL = unsafe { msg_send![cls, isMainThread] };
result != NO
}

0 comments on commit 1e99e35

Please sign in to comment.