-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(iOS): Paint safe areas on iOS mobile #928
Changes from 4 commits
5fd188e
a5b2b1b
d72bf51
f06f822
9d1049f
2dbd47a
00a357d
5d999c8
08b2fbf
c99075f
4118fdb
9e72d5c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import Capacitor | ||
import UIKit | ||
|
||
@objc(SafeAreasColorPlugin) | ||
public class SafeAreasColorPlugin: CAPPlugin, CAPBridgedPlugin { | ||
public let identifier = "SafeAreasColorPlugin" | ||
public let jsName = "SafeAreasColor" | ||
public let pluginMethods: [CAPPluginMethod] = [ | ||
CAPPluginMethod(name: "changeSafeAreasColorOniOS", returnType: CAPPluginReturnPromise) | ||
] | ||
|
||
@objc func changeSafeAreasColorOniOS(_ call: CAPPluginCall) { | ||
let value = call.getString("color") ?? "" | ||
guard let uiColor = UIColor(hex: value) else { | ||
call.reject("Invalid color format") | ||
return | ||
} | ||
|
||
DispatchQueue.main.async { | ||
if #available(iOS 13.0, *) { | ||
// Find the active window in iOS 13 or later | ||
if let window = UIApplication.shared.connectedScenes | ||
.compactMap({ $0 as? UIWindowScene }) | ||
.flatMap({ $0.windows }) | ||
.first(where: { $0.isKeyWindow }) { | ||
|
||
window.backgroundColor = uiColor // Set the background color | ||
call.resolve(["value": "Color set successfully"]) | ||
} else { | ||
call.reject("No active window found") | ||
} | ||
} else { | ||
// For iOS 12 and earlier | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we don't support 12 and earlier, our version minimum atm is 16 - latest iOS is 18 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did this condition based on code made for cut Safe Areas. So remove this condition from there as well? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we can keep it if you want, just saying that since we only support iOS 16 and above the code is not being used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you are correct, if both are dead code, they should be removed to not have unnecessary code. And the condition is using 13.0, we can increase this number to 16 as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sounds good There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed |
||
if let window = UIApplication.shared.keyWindow { | ||
window.backgroundColor = uiColor | ||
call.resolve(["value": "Color set successfully"]) | ||
} else { | ||
call.reject("No key window found") | ||
} | ||
} | ||
} | ||
|
||
call.resolve(["value": value]) | ||
} | ||
} | ||
|
||
extension UIColor { | ||
convenience init?(hex: String) { | ||
var hexSanitized = hex.trimmingCharacters(in: .whitespacesAndNewlines).uppercased() | ||
|
||
if hexSanitized.hasPrefix("#") { | ||
hexSanitized.remove(at: hexSanitized.startIndex) | ||
} | ||
|
||
var rgb: UInt64 = 0 | ||
guard Scanner(string: hexSanitized).scanHexInt64(&rgb) else { return nil } | ||
|
||
let length = hexSanitized.count | ||
switch length { | ||
case 6: // RGB | ||
self.init( | ||
red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, | ||
green: CGFloat((rgb & 0x00FF00) >> 8) / 255.0, | ||
blue: CGFloat(rgb & 0x0000FF) / 255.0, | ||
alpha: 1.0 | ||
) | ||
case 8: // RGBA | ||
self.init( | ||
red: CGFloat((rgb & 0xFF000000) >> 24) / 255.0, | ||
green: CGFloat((rgb & 0x00FF0000) >> 16) / 255.0, | ||
blue: CGFloat((rgb & 0x0000FF00) >> 8) / 255.0, | ||
alpha: CGFloat(rgb & 0x000000FF) / 255.0 | ||
) | ||
default: | ||
return nil | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { log } from "$lib/utils/Logger" | ||
import { registerPlugin } from "@capacitor/core" | ||
import { StatusBar, Style } from "@capacitor/status-bar" | ||
|
||
interface ISafeAreasColorPlugin { | ||
changeSafeAreasColorOniOS(options: { color: string }): Promise<{ value: string }> | ||
} | ||
|
||
const Echo = registerPlugin<ISafeAreasColorPlugin>("SafeAreasColor") | ||
|
||
async function setNewSafeAreasColorOniOS(color: string) { | ||
try { | ||
log.info("Calling native iOS function to change status bar color") | ||
|
||
// Check if the color is 'white' and convert to hex | ||
if (color.toLowerCase() === "white") { | ||
color = "#FFFFFF" | ||
log.info(`Converted color "white" to hexadecimal: ${color}`) | ||
await StatusBar.setStyle({ style: Style.Light }) | ||
log.debug("Change status bar style to light") | ||
} else { | ||
await StatusBar.setStyle({ style: Style.Dark }) | ||
log.debug("Change status bar style to dark") | ||
} | ||
|
||
await Echo.changeSafeAreasColorOniOS({ color }) | ||
} catch (error) { | ||
log.error("Error trying to call swift function:", error) | ||
} | ||
} | ||
|
||
export function changeSafeAreaColorsOniOS(color: string) { | ||
setNewSafeAreasColorOniOS(color) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this empty line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed