Разработка
Делаем в SwiftUI размытие экрана при переключении задачи
Узнайте, как реализовать автоматическое размытие экрана в приложениях SwiftUI, чтобы повысить конфиденциальность пользователя, когда приложение переходит в режим многозадачности.
Повышение конфиденциальности пользователей имеет решающее значение при разработке приложений. В этом руководстве рассказывается о том, как создать приложение SwiftUI, которое автоматически размывает экран, когда переходит в многозадачный или фоновый режим, — полезная функция защиты конфиденциального контента.
Мы рассмотрим, как реализовать эту концепцию на шутливом примере с «секретами» разработчика, которые размываются, когда приложение не активно. Следуя этому краткому пошаговому руководству, вы узнаете, как применить эту технику защиты конфиденциальности в своих приложениях SwiftUI.
Прежде чем начать
Прежде чем начать, убедитесь, что вы обладаете базовыми знаниями о Swift и SwiftUI, особенно об управлении сценами и фазами сцен. Если вы не знакомы с этими понятиями, рекомендуем вам ознакомиться с документацией Apple по SwiftUI.
Настройка проекта
Чтобы продемонстрировать размытие экрана, мы воспользуемся простым приложением под названием My Secrets, которое скрывает конфиденциальную информацию, когда приложение переходит в фоновый режим.
В качестве отправной точки создайте список секретов, хранящихся локально, чтобы заполнить наш пользовательский интерфейс.
class SecretsStore {
static var secrets: [String] = [
"I still have a soft spot for **UIKit**.",
"I cringe at the sight of hamburger menus.",
"In **Human Interface Guidelines**, I trust.",
"I secretly enjoy writing documentation.",
"I believe every bug is just a misunderstood feature",
"I'm always looking for a better way to do things.",
"I have a favorite Xcode theme, and it's not dark..."
]
}
Затем обновите ContentView
, чтобы отобразить простой стилизованный список элементов массива секретов из SecretsStore
.
xxxxxxxxxx
struct ContentView: View {
var body: some View {
List(SecretsStore.secrets, id: \.self) { secret in
Text(.init(secret))
.listRowSeparator(.hidden)
.fontDesign(.monospaced)
}
.listStyle(.inset)
.navigationTitle("My Secrets")
}
}
Задача приложения — автоматически размывать содержимое при переходе в режим многозадачности или при бездействии. Вот как мы можем это реализовать.
Размытие представления
В ContentView
.swift приложение будет отслеживать состояние сцены с помощью @Environment(\.scenePhase)
, чтобы определить, когда оно становится неактивным или переходит в фоновый режим. В зависимости от текущего состояния сцены будет меняться значение радиуса размытия, применяемого к содержимому представления.
xxxxxxxxxx
struct ContentView: View {
// Monitoring the value of the scenePhase from the app environment
@Environment(\.scenePhase) private var scenePhase
// Value of the radius of the blur effect
@State private var blurRadius: CGFloat = 0
var body: some View {
NavigationStack {
List(SecretsStore.secrets, id: \.self) { secret in
Text(.init(secret))
.listRowSeparator(.hidden)
.fontDesign(.monospaced)
}
.listStyle(.inset)
.navigationTitle("My Secrets")
}
// Changes the blurRadius value when the scene phase changes
.onChange(of: scenePhase) { oldPhase, newPhase in
if newPhase == .inactive || newPhase == .background {
withAnimation { blurRadius = 20}
} else {
withAnimation { blurRadius = 0}
}
}
}
}
Затем с помощью модификатора blur(radius:opaque:)
мы применим эффект размытия к содержимому View.
xxxxxxxxxx
struct ContentView: View {
// Monitoring the value of the scenePhase from the app environment
@Environment(\.scenePhase) private var scenePhase
// Value of the radius of the blur effect
@State private var blurRadius: CGFloat = 0
var body: some View {
NavigationStack {
List(SecretsStore.secrets, id: \.self) { secret in
Text(.init(secret))
.listRowSeparator(.hidden)
.fontDesign(.monospaced)
}
.listStyle(.inset)
.navigationTitle("My Secrets")
// The blur modifier
.blur(radius: blurRadius)
}
// Changes the blurRadius value when the scene phase changes
.onChange(of: scenePhase) { oldPhase, newPhase in
if newPhase == .inactive || newPhase == .background {
withAnimation { blurRadius = 20}
} else {
withAnimation { blurRadius = 0}
}
}
}
}
Если пользователь переключается на другое приложение или возвращается на главный экран, конфиденциальный контент в вашем приложении становится размытым, скрывая его от глаз. Таким образом, отображаемая информация остается защищенной, когда приложение неактивно.
Когда пользователь возвращается к вашему приложению, эффект размытия плавно исчезает, делая содержимое снова видимым без резких переходов.
Расширяем функцию
Хотя в предыдущем примере речь шла об одном представлении, вы можете расширить функциональность размытия на все приложение, интегрировав аналогичную логику в делегат главной сцены вашего приложения или выше в иерархии представлений. Это гарантирует, что весь конфиденциальный контент останется защищенным при переходе приложения из одного состояния в другое.
xxxxxxxxxx
import SwiftUI
@main
struct MySecretsApp: App {
@Environment(\.scenePhase) private var scenePhase
@State private var blurRadius: CGFloat = 0
var body: some Scene {
WindowGroup {
ZStack {
ContentView()
.blur(radius: blurRadius)
if blurRadius > 0 {
Image("logo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200)
}
}
.onChange(of: scenePhase) { oldValue, newValue in
if newValue == .inactive || newValue == .background {
withAnimation { blurRadius = 20 }
} else {
withAnimation { blurRadius = 0 }
}
}
}
}
}
Создание контейнера
Другим подходом может быть создание контейнера представлений, который будет отвечать за отслеживание текущего состояния приложения и применение эффекта размытия к его содержимому. Это может быть полезно, если вы хотите поместить изображение поверх содержимого, например логотип приложения, или если есть только определенные View, которые вы хотите размыть.
xxxxxxxxxx
struct SensitiveContentView<Content: View>: View {
@Environment(\.scenePhase) private var scenePhase
@State private var blurRadius: CGFloat = 0
private var content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
ZStack {
content
.blur(radius: blurRadius)
// Shows the app logo on top of the blurred content
if blurRadius != 0 {
Image(systemName: "swift")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 200)
}
}
.onChange(of: scenePhase) { oldPhase, newPhase in
if newPhase == .inactive || newPhase == .background {
withAnimation { blurRadius = 20 }
} else {
withAnimation { blurRadius = 0 }
}
}
}
}
Та же логика может быть использована для создания пользовательского модификатора.
-
Программирование3 недели назад
Конец программирования в том виде, в котором мы его знаем
-
Магазины приложений3 недели назад
Магазин игр Aptoide запустился на iOS в Европе
-
Видео и подкасты для разработчиков6 дней назад
Как устроена мобильная архитектура. Интервью с тех. лидером юнита «Mobile Architecture» из AvitoTech
-
Новости3 недели назад
Видео и подкасты о мобильной разработке 2025.8