Skip to content

Commit

Permalink
On iOS, add configuration for status bar style
Browse files Browse the repository at this point in the history
Co-authored-by: Mads Marquart <[email protected]>
  • Loading branch information
2 people authored and kchibisov committed Oct 21, 2023
1 parent cdee616 commit 20384d2
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ And please only add new entries to the top of this list, right below the `# Unre
- On Android, fix `DeviceId` to contain device id's.
- Add `Window::set_blur` to request a blur behind the window; implemented on Wayland for now.
- On Web, fix `ControlFlow::WaitUntil` to never wake up **before** the given time.
- On iOS, add ability to change the status bar style.
- Add `Window::show_window_menu` to request a titlebar/system menu; implemented on Wayland/Windows for now.
- On iOS, send events `WindowEvent::Occluded(false)`, `WindowEvent::Occluded(true)` when application enters/leaves foreground.
- **Breaking** add `Event::MemoryWarning`; implemented on iOS/Android.
Expand Down
2 changes: 1 addition & 1 deletion FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ If your PR makes notable changes to Winit's features, please update this section
* Setting the `UIView` hidpi factor
* Valid orientations
* Home indicator visibility
* Status bar visibility
* Status bar visibility and style
* Deferrring system gestures
* Getting the device idiom
* Getting the preferred video mode
Expand Down
50 changes: 46 additions & 4 deletions src/platform/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,25 @@ pub trait WindowExtIOS {
///
/// The default is to prefer showing the status bar.
///
/// This changes the value returned by
/// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc),
/// and then calls
/// [`-[UIViewController setNeedsStatusBarAppearanceUpdate]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621354-setneedsstatusbarappearanceupdat?language=objc).
/// This sets the value of the
/// [`prefersStatusBarHidden`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc)
/// property.
///
/// [`setNeedsStatusBarAppearanceUpdate()`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621354-setneedsstatusbarappearanceupdat?language=objc)
/// is also called for you.
fn set_prefers_status_bar_hidden(&self, hidden: bool);

/// Sets the preferred status bar style for the [`Window`].
///
/// The default is system-defined.
///
/// This sets the value of the
/// [`preferredStatusBarStyle`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621416-preferredstatusbarstyle?language=objc)
/// property.
///
/// [`setNeedsStatusBarAppearanceUpdate()`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621354-setneedsstatusbarappearanceupdat?language=objc)
/// is also called for you.
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle);
}

impl WindowExtIOS for Window {
Expand Down Expand Up @@ -107,6 +121,12 @@ impl WindowExtIOS for Window {
self.window
.maybe_queue_on_main(move |w| w.set_prefers_status_bar_hidden(hidden))
}

#[inline]
fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle) {
self.window
.maybe_queue_on_main(move |w| w.set_preferred_status_bar_style(status_bar_style))
}
}

/// Additional methods on [`WindowBuilder`] that are specific to iOS.
Expand Down Expand Up @@ -154,6 +174,14 @@ pub trait WindowBuilderExtIOS {
/// This sets the initial value returned by
/// [`-[UIViewController prefersStatusBarHidden]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621440-prefersstatusbarhidden?language=objc).
fn with_prefers_status_bar_hidden(self, hidden: bool) -> Self;

/// Sets the style of the [`Window`]'s status bar.
///
/// The default is system-defined.
///
/// This sets the initial value returned by
/// [`-[UIViewController preferredStatusBarStyle]`](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621416-preferredstatusbarstyle?language=objc),
fn with_preferred_status_bar_style(self, status_bar_style: StatusBarStyle) -> Self;
}

impl WindowBuilderExtIOS for WindowBuilder {
Expand Down Expand Up @@ -187,6 +215,12 @@ impl WindowBuilderExtIOS for WindowBuilder {
self.platform_specific.prefers_status_bar_hidden = hidden;
self
}

#[inline]
fn with_preferred_status_bar_style(mut self, status_bar_style: StatusBarStyle) -> Self {
self.platform_specific.preferred_status_bar_style = status_bar_style;
self
}
}

/// Additional methods on [`MonitorHandle`] that are specific to iOS.
Expand Down Expand Up @@ -264,3 +298,11 @@ bitflags! {
| ScreenEdge::BOTTOM.bits() | ScreenEdge::RIGHT.bits();
}
}

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum StatusBarStyle {
#[default]
Default,
LightContent,
DarkContent,
}
2 changes: 2 additions & 0 deletions src/platform_impl/ios/uikit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ mod event;
mod responder;
mod screen;
mod screen_mode;
mod status_bar_style;
mod touch;
mod trait_collection;
mod view;
Expand All @@ -25,6 +26,7 @@ pub(crate) use self::event::UIEvent;
pub(crate) use self::responder::UIResponder;
pub(crate) use self::screen::{UIScreen, UIScreenOverscanCompensation};
pub(crate) use self::screen_mode::UIScreenMode;
pub(crate) use self::status_bar_style::UIStatusBarStyle;
pub(crate) use self::touch::{UITouch, UITouchPhase, UITouchType};
pub(crate) use self::trait_collection::{UIForceTouchCapability, UITraitCollection};
#[allow(unused_imports)]
Expand Down
27 changes: 27 additions & 0 deletions src/platform_impl/ios/uikit/status_bar_style.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::platform::ios::StatusBarStyle;
use icrate::Foundation::NSInteger;
use objc2::encode::{Encode, Encoding};

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
#[allow(dead_code)]
#[repr(isize)]
pub enum UIStatusBarStyle {
#[default]
Default = 0,
LightContent = 1,
DarkContent = 3,
}

impl From<StatusBarStyle> for UIStatusBarStyle {
fn from(value: StatusBarStyle) -> Self {
match value {
StatusBarStyle::Default => Self::Default,
StatusBarStyle::LightContent => Self::LightContent,
StatusBarStyle::DarkContent => Self::DarkContent,
}
}
}

unsafe impl Encode for UIStatusBarStyle {
const ENCODING: Encoding = NSInteger::ENCODING;
}
18 changes: 16 additions & 2 deletions src/platform_impl/ios/view.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use objc2::{declare_class, extern_methods, msg_send, msg_send_id, mutability, Cl
use super::app_state::{self, EventWrapper};
use super::uikit::{
UIApplication, UIDevice, UIEvent, UIForceTouchCapability, UIInterfaceOrientationMask,
UIResponder, UITouch, UITouchPhase, UITouchType, UITraitCollection, UIView, UIViewController,
UIWindow,
UIResponder, UIStatusBarStyle, UITouch, UITouchPhase, UITouchType, UITraitCollection, UIView,
UIViewController, UIWindow,
};
use super::window::WindowId;
use crate::{
Expand Down Expand Up @@ -267,6 +267,7 @@ impl WinitView {

pub struct ViewControllerState {
prefers_status_bar_hidden: Cell<bool>,
preferred_status_bar_style: Cell<UIStatusBarStyle>,
prefers_home_indicator_auto_hidden: Cell<bool>,
supported_orientations: Cell<UIInterfaceOrientationMask>,
preferred_screen_edges_deferring_system_gestures: Cell<UIRectEdge>,
Expand Down Expand Up @@ -297,6 +298,7 @@ declare_class!(
&mut this.state,
Box::new(ViewControllerState {
prefers_status_bar_hidden: Cell::new(false),
preferred_status_bar_style: Cell::new(UIStatusBarStyle::Default),
prefers_home_indicator_auto_hidden: Cell::new(false),
supported_orientations: Cell::new(UIInterfaceOrientationMask::All),
preferred_screen_edges_deferring_system_gestures: Cell::new(
Expand All @@ -320,6 +322,11 @@ declare_class!(
self.state.prefers_status_bar_hidden.get()
}

#[method(preferredStatusBarStyle)]
fn preferred_status_bar_style(&self) -> UIStatusBarStyle {
self.state.preferred_status_bar_style.get()
}

#[method(prefersHomeIndicatorAutoHidden)]
fn prefers_home_indicator_auto_hidden(&self) -> bool {
self.state.prefers_home_indicator_auto_hidden.get()
Expand All @@ -345,6 +352,11 @@ impl WinitViewController {
self.setNeedsStatusBarAppearanceUpdate();
}

pub(crate) fn set_preferred_status_bar_style(&self, val: UIStatusBarStyle) {
self.state.preferred_status_bar_style.set(val);
self.setNeedsStatusBarAppearanceUpdate();
}

pub(crate) fn set_prefers_home_indicator_auto_hidden(&self, val: bool) {
self.state.prefers_home_indicator_auto_hidden.set(val);
let os_capabilities = app_state::os_capabilities();
Expand Down Expand Up @@ -403,6 +415,8 @@ impl WinitViewController {

this.set_prefers_status_bar_hidden(platform_attributes.prefers_status_bar_hidden);

this.set_preferred_status_bar_style(platform_attributes.preferred_status_bar_style.into());

this.set_supported_interface_orientations(mtm, platform_attributes.valid_orientations);

this.set_prefers_home_indicator_auto_hidden(
Expand Down
8 changes: 7 additions & 1 deletion src/platform_impl/ios/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
error::{ExternalError, NotSupportedError, OsError as RootOsError},
event::{Event, WindowEvent},
icon::Icon,
platform::ios::{ScreenEdge, ValidOrientations},
platform::ios::{ScreenEdge, StatusBarStyle, ValidOrientations},
platform_impl::platform::{
app_state, monitor, EventLoopWindowTarget, Fullscreen, MonitorHandle,
},
Expand Down Expand Up @@ -551,6 +551,11 @@ impl Inner {
pub fn set_prefers_status_bar_hidden(&self, hidden: bool) {
self.view_controller.set_prefers_status_bar_hidden(hidden);
}

pub fn set_preferred_status_bar_style(&self, status_bar_style: StatusBarStyle) {
self.view_controller
.set_preferred_status_bar_style(status_bar_style.into());
}
}

impl Inner {
Expand Down Expand Up @@ -659,5 +664,6 @@ pub struct PlatformSpecificWindowBuilderAttributes {
pub valid_orientations: ValidOrientations,
pub prefers_home_indicator_hidden: bool,
pub prefers_status_bar_hidden: bool,
pub preferred_status_bar_style: StatusBarStyle,
pub preferred_screen_edges_deferring_system_gestures: ScreenEdge,
}

0 comments on commit 20384d2

Please sign in to comment.