Эффект размытия в реальном времени для панели навигации
Как добиться эффекта размытия в реальном времени для панели навигации, как в приложении Trailers в iPhone.
т.е. при прокрутке содержимое должно быть размыто за панелью навигации. Пожалуйста, помогите мне с кодом.
Спасибо!
Я хочу добиться такого эффекта:
12 ответов
Apple представила новые классы UIVisualEffectView и другие, чтобы добавить прозрачность и эффект размытия на представления из выпуска iOS 8.0.
Вот как вы можете использовать его, чтобы добавить эффект размытия на панель навигации или любой другой UIView
:
Swift 2.1 Править
func addBlurEffect() {
let bounds = self.navigationController?.navigationBar.bounds as CGRect!
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = bounds!
visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.navigationController?.navigationBar.addSubview(visualEffectView)
// Here you can add visual effects to any UIView control.
// Replace custom view with navigation bar in above code to add effects to custom view.
}
Objective C Code:
- (void) addBlurEffect {
// Add blur view
CGRect bounds = self.navigationController.navigationBar.bounds;
UIVisualEffectView *visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
visualEffectView.frame = bounds;
visualEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.navigationController.navigationBar addSubview:visualEffectView];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];
// Here you can add visual effects to any UIView control.
// Replace custom view with navigation bar in above code to add effects to custom view.
}
ОБНОВИТЬ:
Если вы обнаружите, что после добавления эффекта размытия на навигационную панель кнопки навигации не отображаются, добавьте нижнюю строку после добавления кода blurView.
Swift:
self.navigationController?.navigationBar.sendSubview(toBack: visualEffectView)
Цель C:
[self.navigationController.navigationBar sendSubviewToBack:visualEffectView];
Swift 4
extension UINavigationBar {
func installBlurEffect() {
isTranslucent = true
setBackgroundImage(UIImage(), for: .default)
let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height
var blurFrame = bounds
blurFrame.size.height += statusBarHeight
blurFrame.origin.y -= statusBarHeight
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
blurView.isUserInteractionEnabled = false
blurView.frame = blurFrame
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(blurView)
blurView.layer.zPosition = -1
}
}
использование
navigationController?.navigationBar.installBlurEffect()
Отметил: на iOS 11, функция sendSubviewToBack
не работает нормально. Чтобы достичь этого, мы должны использовать zPosition
разместить вид эффекта размытия под другими видами.
self.visualEffectView.layer.zPosition = -1;
Код Objective-C
[self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.shadowImage = [UIImage new];
self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.translucent = YES;
// Add blur view
CGRect bounds = self.navigationController.navigationBar.bounds;
bounds.size.height += 20;
bounds.origin.y -= 20;
_visualEffectView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleLight]];
self.visualEffectView.frame = bounds;
self.visualEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.visualEffectView.userInteractionEnabled = NO;
self.visualEffectView.layer.zPosition = -1;
[self.navigationController.navigationBar addSubview:self.visualEffectView];
[self.navigationController.navigationBar sendSubviewToBack:self.visualEffectView];
Код Swift 4
self.navigationController?.navigationBar.isTranslucent = true
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
var bounds = view.bounds
bounds.size.height += 20
bounds.origin.y -= 20
visualEffectView.isUserInteractionEnabled = false
visualEffectView.frame = bounds
visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.navigationController?.navigationBar.addSubview(visualEffectView)
visualEffectView.layer.zPosition = -1
Я добавил @Kampai, @Damasio в свои настройки, чтобы решить мои проблемы (которые были связаны с pushNavigation). Код будет поддерживать Swift 4.0+, iOS9, Xcode 9
В ViewDidLoad () вашего ViewController просто вызовите
addBlurEffect(toView: self.navigationController?.navigationBar)
функция:
//MARK :- It can be used in navBarGlassEffect view
func addBlurEffect(toView view:UIView?) {
// Add blur view
guard let view = view else { return }
//This will let visualEffectView to work perfectly
if let navBar = view as? UINavigationBar{
navBar.setBackgroundImage(UIImage(), for: .default)
navBar.shadowImage = UIImage()
}
var bounds = view.bounds
bounds.offsetBy(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
let blurEffect = UIBlurEffect(style: .dark)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.isUserInteractionEnabled = false
visualEffectView.frame = bounds
visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.insertSubview(visualEffectView, at: 0)
}
Если после ответа @Kampai строка состояния не получает эффекта, добавьте следующее:
bounds.offsetInPlace(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
Вопрос адресован в этой теме.
Swift 5, iOS 13 +
Ты можешь использовать
UINavigationBarAppearance()
в файле AppDelegate. И не забудьте установить внешний вид для режима без прокрутки. Для меня он отлично работает с navigationBar.prefersLargeTitles.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.clear
appearance.backgroundEffect = UIBlurEffect(style: .light) // or dark
let scrollingAppearance = UINavigationBarAppearance()
scrollingAppearance.configureWithTransparentBackground()
scrollingAppearance.backgroundColor = .white // your view (superview) color
UINavigationBar.appearance().standardAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = scrollingAppearance
UINavigationBar.appearance().compactAppearance = scrollingAppearance
return true
}
SWIFT 3:
func addBlurEffect(toView view:UIView?) {
// Add blur view
guard let view = view else { return }
//This will let visualEffectView to work perfectly
if let navBar = view as? UINavigationBar{
navBar.setBackgroundImage(UIImage(), for: .default)
navBar.shadowImage = UIImage()
}
var bounds = view.bounds
bounds.offsetBy(dx: 0.0, dy: -20.0)
bounds.size.height = bounds.height + 20.0
let blurEffect = UIBlurEffect(style: .dark)
let visualEffectView = UIVisualEffectView(effect: blurEffect)
visualEffectView.isUserInteractionEnabled = false
visualEffectView.frame = bounds
visualEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.insertSubview(visualEffectView, at: 0)
}
Ключевое примечание: после того, как вы внедрите приведенный выше код для добавления размытия, 1. Вам нужно отправить свой размытый вид назад, чтобы показать другие вещи. 2. Вам нужно установить ложное взаимодействие с пользователем в режиме размытия, чтобы иметь возможность нажимать на элементы. панель навигации.
Сначала я добавил метод addBlurEffect(), а затем в AppDelegate я добавил
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().backgroundColor = UIColor.clearColor()
UINavigationBar.appearance().translucent = true
Теперь это работает для меня
У меня была та же проблема, но теперь я вижу, что это размытие является поведением по умолчанию, по крайней мере, в iOS 16. Моя ошибка заключалась в том, что я прикрепил UITableView к view.safeAreaLayoutGuide.topAnchor. Чтобы получить эффект размытия на панели навигации или вкладке, вам нужно просто прикрепить ее к краю представления, например, view.topAnchor.
Эффект размытия панели навигации iOS
let navigationBar = self.navigationController?.navigationBar
if #available(iOS 13.0, *) {
navigationBar?.standardAppearance.backgroundColor = .clear
navigationBar?.standardAppearance.backgroundEffect = UIBlurEffect(style: .systemMaterial)
}
Не забудьте выровнятьUITableView
контролировать (не безопасная зона)
Это решение neoneye сверху, которое отлично работает применительно к UIToolbar.
extension UIToolbar {
func toolBarBlurEffect() {
isTranslucent = true
setBackgroundImage(UIImage(), forToolbarPosition: .any, barMetrics: .default)
let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height
var blurFrame = bounds
blurFrame.size.height += statusBarHeight
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
blurView.isUserInteractionEnabled = false
blurView.frame = blurFrame
blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
addSubview(blurView)
blurView.layer.zPosition = -1
}
}
Использование аналогично:
navigationController?.toolbar.toolBarBlurEffect()