Nell'app Music del nuovo iOS, possiamo vedere una copertina dell'album dietro una vista che la sfoca.
Come si può realizzare qualcosa del genere? Ho letto la documentazione, ma non ho trovato nulla lì.
Nell'app Music del nuovo iOS, possiamo vedere una copertina dell'album dietro una vista che la sfoca.
Come si può realizzare qualcosa del genere? Ho letto la documentazione, ma non ho trovato nulla lì.
Risposte:
Puoi usare UIVisualEffectView
per ottenere questo effetto. Questa è un'API nativa che è stata ottimizzata per prestazioni e durata della batteria, inoltre è facile da implementare.
Swift:
//only apply the blur if the user hasn't disabled transparency effects
if !UIAccessibility.isReduceTransparencyEnabled {
view.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
} else {
view.backgroundColor = .black
}
Objective-C:
//only apply the blur if the user hasn't disabled transparency effects
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
self.view.backgroundColor = [UIColor clearColor];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
//always fill the view
blurEffectView.frame = self.view.bounds;
blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self.view addSubview:blurEffectView]; //if you have more UIViews, use an insertSubview API to place it where needed
} else {
self.view.backgroundColor = [UIColor blackColor];
}
Se stai presentando questo controller di visualizzazione in modo modale per offuscare il contenuto sottostante, dovrai impostare lo stile di presentazione modale su Over Current Context e impostare il colore di sfondo su clear per garantire che il controller di visualizzazione sottostante rimanga visibile una volta che questo viene presentato in overtop.
insertSubView:belowSubView:
commento in questo codice, ho usato quanto segue per impostare la sfocatura come sfondo della vista:view.insertSubview(blurEffectView, atIndex: 0)
UIAccessibilityIsReduceTransparencyEnabled()
.
Poiché l'immagine nello screenshot è statica, è possibile utilizzare CIGaussianBlur
da Core Image (richiede iOS 6). Ecco un esempio: https://github.com/evanwdavis/Fun-with-Masks/blob/master/Fun%20with%20Masks/EWDBlurExampleVC.m
Intendiamoci, questo è più lento rispetto alle altre opzioni in questa pagina.
#import <QuartzCore/QuartzCore.h>
- (UIImage*) blur:(UIImage*)theImage
{
// ***********If you need re-orienting (e.g. trying to blur a photo taken from the device camera front facing camera in portrait mode)
// theImage = [self reOrientIfNeeded:theImage];
// create our blurred image
CIContext *context = [CIContext contextWithOptions:nil];
CIImage *inputImage = [CIImage imageWithCGImage:theImage.CGImage];
// setting up Gaussian Blur (we could use one of many filters offered by Core Image)
CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
[filter setValue:inputImage forKey:kCIInputImageKey];
[filter setValue:[NSNumber numberWithFloat:15.0f] forKey:@"inputRadius"];
CIImage *result = [filter valueForKey:kCIOutputImageKey];
// CIGaussianBlur has a tendency to shrink the image a little,
// this ensures it matches up exactly to the bounds of our original image
CGImageRef cgImage = [context createCGImage:result fromRect:[inputImage extent]];
UIImage *returnImage = [UIImage imageWithCGImage:cgImage];//create a UIImage for this function to "return" so that ARC can manage the memory of the blur... ARC can't manage CGImageRefs so we need to release it before this function "returns" and ends.
CGImageRelease(cgImage);//release CGImageRef because ARC doesn't manage this on its own.
return returnImage;
// *************** if you need scaling
// return [[self class] scaleIfNeeded:cgImage];
}
+(UIImage*) scaleIfNeeded:(CGImageRef)cgimg {
bool isRetina = [[[UIDevice currentDevice] systemVersion] intValue] >= 4 && [[UIScreen mainScreen] scale] == 2.0;
if (isRetina) {
return [UIImage imageWithCGImage:cgimg scale:2.0 orientation:UIImageOrientationUp];
} else {
return [UIImage imageWithCGImage:cgimg];
}
}
- (UIImage*) reOrientIfNeeded:(UIImage*)theImage{
if (theImage.imageOrientation != UIImageOrientationUp) {
CGAffineTransform reOrient = CGAffineTransformIdentity;
switch (theImage.imageOrientation) {
case UIImageOrientationDown:
case UIImageOrientationDownMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, theImage.size.height);
reOrient = CGAffineTransformRotate(reOrient, M_PI);
break;
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
reOrient = CGAffineTransformRotate(reOrient, M_PI_2);
break;
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
reOrient = CGAffineTransformTranslate(reOrient, 0, theImage.size.height);
reOrient = CGAffineTransformRotate(reOrient, -M_PI_2);
break;
case UIImageOrientationUp:
case UIImageOrientationUpMirrored:
break;
}
switch (theImage.imageOrientation) {
case UIImageOrientationUpMirrored:
case UIImageOrientationDownMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.width, 0);
reOrient = CGAffineTransformScale(reOrient, -1, 1);
break;
case UIImageOrientationLeftMirrored:
case UIImageOrientationRightMirrored:
reOrient = CGAffineTransformTranslate(reOrient, theImage.size.height, 0);
reOrient = CGAffineTransformScale(reOrient, -1, 1);
break;
case UIImageOrientationUp:
case UIImageOrientationDown:
case UIImageOrientationLeft:
case UIImageOrientationRight:
break;
}
CGContextRef myContext = CGBitmapContextCreate(NULL, theImage.size.width, theImage.size.height, CGImageGetBitsPerComponent(theImage.CGImage), 0, CGImageGetColorSpace(theImage.CGImage), CGImageGetBitmapInfo(theImage.CGImage));
CGContextConcatCTM(myContext, reOrient);
switch (theImage.imageOrientation) {
case UIImageOrientationLeft:
case UIImageOrientationLeftMirrored:
case UIImageOrientationRight:
case UIImageOrientationRightMirrored:
CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.height,theImage.size.width), theImage.CGImage);
break;
default:
CGContextDrawImage(myContext, CGRectMake(0,0,theImage.size.width,theImage.size.height), theImage.CGImage);
break;
}
CGImageRef CGImg = CGBitmapContextCreateImage(myContext);
theImage = [UIImage imageWithCGImage:CGImg];
CGImageRelease(CGImg);
CGContextRelease(myContext);
}
return theImage;
}
Nella sessione "Implementazione dell'interfaccia utente su iOS" del WWDC 2013, Apple spiega come creare uno sfondo sfocato (alle 14:30) e menziona un metodo applyLightEffect
implementato nel codice di esempio utilizzando Accelerate.framework.
GPUImage utilizza shader OpenGL per creare sfocature dinamiche. Ha diversi tipi di sfocatura: GPUImageBoxBlurFilter, GPUImageFastBlurFilter, GaussianSelectiveBlur, GPUImageGaussianBlurFilter. Esiste anche un GPUImageiOSBlurFilter che "dovrebbe replicare completamente l'effetto sfocatura fornito dal pannello di controllo di iOS 7" ( tweet , articolo ). L'articolo è dettagliato e informativo.
- (UIImage *) blurryGPUImage: (UIImage *) image withBlurLevel: (NSInteger) blur { GPUImageFastBlurFilter * blurFilter = [GPUImageFastBlurFilter new]; blurFilter.blurSize = blur; UIImage * result = [blurFilter imageByFilteringImage: image]; risultato di ritorno; }
Da indieambitions.com: esegui una sfocatura usando vImage . L'algoritmo è utilizzato anche in iOS-RealTimeBlur .
Da Nick Lockwood: https://github.com/nicklockwood/FXBlurView L'esempio mostra la sfocatura su una vista di scorrimento. Sfoca con dispatch_async, quindi si sincronizza per chiamare gli aggiornamenti con UITrackingRunLoopMode in modo che la sfocatura non sia ritardata quando UIKit dà più priorità allo scorrimento di UIScrollView. Questo è spiegato nel libro iOS Core Animation di Nick , che tra l'altro è fantastico.
iOS-blur Questo prende il livello di sfocatura di UIToolbar e lo mette altrove. Apple rifiuterà la tua app se usi questo metodo. Vedi https://github.com/mochidev/MDBlurView/issues/4
Dal blog di Evadne: LiveFrost: veloce, sincrono con UIView Snapshot coinvolgente . Ottimo codice e un'ottima lettura. Alcune idee da questo post:
Andy Matuschak ha dichiarato su Twitter: "Sai, molti dei posti in cui sembra che lo stiamo facendo in tempo reale, è statico con trucchi intelligenti".
Su doubleencore.com affermano che "abbiamo scoperto che un raggio di sfocatura di 10 pt più un aumento di 10 pt della saturazione imita meglio l'effetto di sfocatura di iOS 7 nella maggior parte dei casi".
Uno sguardo alle intestazioni private di SBFProceduralWallpaperView di Apple .
Infine, questa non è una vera sfocatura, ma ricorda che puoi impostare rasterizationScale per ottenere un'immagine pixelata: http://www.dimzzy.com/blog/2010/11/blur-effect-for-uiview/
UIImage
altrimenti sembrerà troppo grande su un dispositivo Retina ...
Ho deciso di pubblicare una versione scritta di Objective-C dalla risposta accettata solo per fornire più opzioni in questa domanda.
- (UIView *)applyBlurToView:(UIView *)view withEffectStyle:(UIBlurEffectStyle)style andConstraints:(BOOL)addConstraints
{
//only apply the blur if the user hasn't disabled transparency effects
if(!UIAccessibilityIsReduceTransparencyEnabled())
{
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:style];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
blurEffectView.frame = view.bounds;
[view addSubview:blurEffectView];
if(addConstraints)
{
//add auto layout constraints so that the blur fills the screen upon rotating device
[blurEffectView setTranslatesAutoresizingMaskIntoConstraints:NO];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeTop
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeBottom
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeLeading
multiplier:1
constant:0]];
[view addConstraint:[NSLayoutConstraint constraintWithItem:blurEffectView
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:view
attribute:NSLayoutAttributeTrailing
multiplier:1
constant:0]];
}
}
else
{
view.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
}
return view;
}
I vincoli potrebbero essere rimossi se si desidera in caso di supporto se si supporta solo la modalità verticale o aggiungo semplicemente un flag a questa funzione per usarli o meno.
Non credo di poter pubblicare il codice, ma il post sopra che menziona il codice di esempio WWDC è corretto. Ecco il link: https://developer.apple.com/downloads/index.action?name=WWDC%202013
Il file che stai cercando è la categoria su UIImage e il metodo è applyLightEffect.
Come ho notato sopra in un commento, l'Apple Blur ha saturazione e altre cose oltre a sfocatura. Una semplice sfocatura non farà ... se stai cercando di emulare il loro stile.
Penso che la soluzione più semplice sia quella di sovrascrivere UIToolbar, che sfuma tutto ciò che sta dietro in iOS 7. È abbastanza subdolo, ma è molto semplice da implementare e veloce!
Puoi farlo con qualsiasi vista, basta renderlo una sottoclasse UIToolbar
invece di UIView
. Si può anche farlo con una UIViewController
's view
proprietà, per esempio ...
1) creare una nuova classe che è una "sottoclasse di" UIViewController
e selezionare la casella "Con XIB per l'interfaccia utente".
2) Seleziona la vista e vai alla finestra di ispezione identità nel pannello di destra (alt-command-3). Cambia la "Classe" in UIToolbar
. Ora vai alla finestra di ispezione degli attributi (alt-command-4) e cambia il colore "Sfondo" in "Cancella colore".
3) Aggiungi una sottoview alla vista principale e collegala a una IBOutlet nella tua interfaccia. Chiamatela backgroundColorView
. Assomiglierà a qualcosa del genere, come una categoria privata nel .m
file deployment ( ).
@interface BlurExampleViewController ()
@property (weak, nonatomic) IBOutlet UIView *backgroundColorView;
@end
4) Vai al .m
file di implementazione del controller di visualizzazione ( ) e modifica il -viewDidLoad
metodo, per visualizzare come segue:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.barStyle = UIBarStyleBlack; // this will give a black blur as in the original post
self.backgroundColorView.opaque = NO;
self.backgroundColorView.alpha = 0.5;
self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
}
Questo ti darà una vista grigio scuro, che offusca tutto ciò che c'è dietro. Nessun business divertente, nessuna sfocatura delle immagini core lenta, utilizzando tutto ciò che è a portata di mano fornito dal sistema operativo / SDK.
È possibile aggiungere la vista del controller di questa vista a un'altra vista, come segue:
[self addChildViewController:self.blurViewController];
[self.view addSubview:self.blurViewController.view];
[self.blurViewController didMoveToParentViewController:self];
// animate the self.blurViewController into view
Fammi sapere se qualcosa non è chiaro, sarò felice di aiutarti!
UIToolbar è stato modificato in 7.0.3 per dare un effetto potenzialmente indesiderato quando si usa una sfocatura colorata.
barTintColor
Prima eravamo in grado di impostare il colore usando , ma se lo facevi prima, dovrai impostare il componente alfa su un valore inferiore a 1. Altrimenti la tua barra UITool sarà completamente opaca, senza sfocature.
Ciò può essere ottenuto come segue: (tenere presente che self
è una sottoclasse di UIToolbar
)
UIColor *color = [UIColor blueColor]; // for example
self.barTintColor = [color colorWithAlphaComponent:0.5];
Questo darà una sfumatura blu alla vista sfocata.
self.backgroundColorView.opaque = NO;
self.backgroundColorView.alpha = 0.5;
self.backgroundColorView.backgroundColor = [UIColor colorWithWhite:0.3 alpha:1];
ma lo sfondo non è stato sfocato, ma solo un bell'effetto. grazie comunque!
Ecco un'implementazione veloce in Swift usando CIGaussianBlur:
func blur(image image: UIImage) -> UIImage {
let radius: CGFloat = 20;
let context = CIContext(options: nil);
let inputImage = CIImage(CGImage: image.CGImage!);
let filter = CIFilter(name: "CIGaussianBlur");
filter?.setValue(inputImage, forKey: kCIInputImageKey);
filter?.setValue("\(radius)", forKey:kCIInputRadiusKey);
let result = filter?.valueForKey(kCIOutputImageKey) as! CIImage;
let rect = CGRectMake(radius * 2, radius * 2, image.size.width - radius * 4, image.size.height - radius * 4)
let cgImage = context.createCGImage(result, fromRect: rect);
let returnImage = UIImage(CGImage: cgImage);
return returnImage;
}
Puoi provare UIVisualEffectView
con un'impostazione personalizzata come -
class BlurViewController: UIViewController {
private let blurEffect = (NSClassFromString("_UICustomBlurEffect") as! UIBlurEffect.Type).init()
override func viewDidLoad() {
super.viewDidLoad()
let blurView = UIVisualEffectView(frame: UIScreen.main.bounds)
blurEffect.setValue(1, forKeyPath: "blurRadius")
blurView.effect = blurEffect
view.addSubview(blurView)
}
}
Uscita: - per blurEffect.setValue(1...
& blurEffect.setValue(2..
(NSClassFromString("_UICustomVibrancyEffect") as! UIVibrancyEffect.Type).init()
Avrei davvero apprezzato l'aiuto!
Ecco un modo semplice per aggiungere la sfocatura personalizzata senza contrattare con le API private utilizzando UIViewPropertyAnimator :
Per prima cosa, dichiara la proprietà della classe:
var blurAnimator: UIViewPropertyAnimator!
Quindi imposta la sfocatura in viewDidLoad()
:
let blurEffectView = UIVisualEffectView()
blurEffectView.backgroundColor = .clear
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
blurAnimator = UIViewPropertyAnimator(duration: 1, curve: .linear) { [blurEffectView] in
blurEffectView.effect = UIBlurEffect(style: .light)
}
blurAnimator.fractionComplete = 0.15 // set the blur intensity.
Nota: questa soluzione non è adatta per UICollectionView
/ UITableView
cellule
Da Xcode puoi farlo facilmente. Seguire i passaggi da xcode. Drage vista effetti visivi sul tuo uiview o imageview.
Happy Coding :)
La risposta accettata è corretta ma manca un passaggio importante qui, nel caso in cui questa vista, per la quale si desidera uno sfondo sfocato, sia presentata usando
[self presentViewController:vc animated:YES completion:nil]
Per impostazione predefinita, questo annullerà la sfocatura poiché UIKit rimuove la vista del presentatore, che in realtà stai sfocando. Per evitare tale rimozione, aggiungi questa riga prima di quella precedente
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
O usa altri Over
stili.
Objective-C
UIVisualEffect *blurEffect;
blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark];
UIVisualEffectView *visualEffectView;
visualEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
visualEffectView.frame = self.accessImageView.bounds;
[self.accessImageView addSubview:visualEffectView];
SWIFT 3.0
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(blurEffectView)
Per le persone che desiderano maggiore controllo, è possibile utilizzare il UIImageEffects
codice di esempio di Apple .
Puoi copiare il codice UIImageEffects
dalla Libreria per sviluppatori di Apple: sfocatura e tinta di un'immagine
#import "UIImageEffects.h"
...
self.originalImageView.image = [UIImageEffects imageByApplyingLightEffectToImage:[UIImage imageNamed:@"yourImage.png"]];
func blurBackgroundUsingImage(image: UIImage)
{
var frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
var imageView = UIImageView(frame: frame)
imageView.image = image
imageView.contentMode = .ScaleAspectFill
var blurEffect = UIBlurEffect(style: .Light)
var blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = frame
var transparentWhiteView = UIView(frame: frame)
transparentWhiteView.backgroundColor = UIColor(white: 1.0, alpha: 0.30)
var viewsArray = [imageView, blurEffectView, transparentWhiteView]
for index in 0..<viewsArray.count {
if let oldView = self.view.viewWithTag(index + 1) {
var oldView = self.view.viewWithTag(index + 1)
// Must explicitly unwrap oldView to access its removeFromSuperview() method as of Xcode 6 Beta 5
oldView!.removeFromSuperview()
}
var viewToInsert = viewsArray[index]
self.view.insertSubview(viewToInsert, atIndex: index + 1)
viewToInsert.tag = index + 1
}
}
Ho trovato questo per caso, mi dà risultati davvero fantastici (quasi duplicati con quelli di Apple) e usa il framework Acceleration. - http://pastebin.com/6cs6hsyQ * Non scritto da me
Questa risposta si basa sull'eccellente risposta precedente di Mitja Semolic . L'ho convertito in Swift 3, ho aggiunto una spiegazione a ciò che sta accadendo nei commenti, l'ho trasformato in un'estensione di UIViewController in modo che qualsiasi VC possa chiamarlo a piacimento, ho aggiunto una vista non sfocata per mostrare un'applicazione selettiva e ho aggiunto un blocco di completamento in modo che il controller della vista chiamante può fare quello che vuole al completamento della sfocatura.
import UIKit
//This extension implements a blur to the entire screen, puts up a HUD and then waits and dismisses the view.
extension UIViewController {
func blurAndShowHUD(duration: Double, message: String, completion: @escaping () -> Void) { //with completion block
//1. Create the blur effect & the view it will occupy
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView()//(effect: blurEffect)
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
//2. Add the effect view to the main view
self.view.addSubview(blurEffectView)
//3. Create the hud and add it to the main view
let hud = HudView.getHUD(view: self.view, withMessage: message)
self.view.addSubview(hud)
//4. Begin applying the blur effect to the effect view
UIView.animate(withDuration: 0.01, animations: {
blurEffectView.effect = blurEffect
})
//5. Halt the blur effects application to achieve the desired blur radius
self.view.pauseAnimationsInThisView(delay: 0.004)
//6. Remove the view (& the HUD) after the completion of the duration
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
blurEffectView.removeFromSuperview()
hud.removeFromSuperview()
self.view.resumeAnimationsInThisView()
completion()
}
}
}
extension UIView {
public func pauseAnimationsInThisView(delay: Double) {
let time = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in
let layer = self.layer
let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
})
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
}
public func resumeAnimationsInThisView() {
let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
}
}
Ho confermato che funziona con iOS 10.3.1 e iOS 11
Un importante supplemento alla risposta di @ Joey
Questo vale per una situazione in cui si desidera presentare un offuscata-sfondo UIViewController
con UINavigationController
.
// suppose you've done blur effect with your presented view controller
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController];
// this is very important, if you don't do this, the blur effect will darken after view did appeared
// the reason is that you actually present navigation controller, not presented controller
// please note it's "OverFullScreen", not "OverCurrentContext"
nav.modalPresentationStyle = UIModalPresentationOverFullScreen;
UIViewController *presentedViewController = [[UIViewController alloc] init];
// the presented view controller's modalPresentationStyle is "OverCurrentContext"
presentedViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[presentingViewController presentViewController:nav animated:YES completion:nil];
Godere!
Swift 3 Versione della risposta di Kev per restituire un'immagine sfocata -
func blurBgImage(image: UIImage) -> UIImage? {
let radius: CGFloat = 20;
let context = CIContext(options: nil);
let inputImage = CIImage(cgImage: image.cgImage!);
let filter = CIFilter(name: "CIGaussianBlur");
filter?.setValue(inputImage, forKey: kCIInputImageKey);
filter?.setValue("\(radius)", forKey:kCIInputRadiusKey);
if let result = filter?.value(forKey: kCIOutputImageKey) as? CIImage{
let rect = CGRect(origin: CGPoint(x: radius * 2,y :radius * 2), size: CGSize(width: image.size.width - radius * 4, height: image.size.height - radius * 4))
if let cgImage = context.createCGImage(result, from: rect){
return UIImage(cgImage: cgImage);
}
}
return nil;
}
Ecco un esempio più completo usando la straordinaria tecnica di @AdamBardon.
@IBDesignable class ButtonOrSomethingWithBlur: UIButton {
var ba: UIViewPropertyAnimator?
private lazy var blurry: BlurryBall = { return BlurryBall() }()
override func didMoveToSuperview() {
super.didMoveToSuperview()
// Setup the blurry ball. BE SURE TO TEARDOWN.
// Use superb trick to access the internal guassian level of Apple's
// standard gpu blurrer per stackoverflow.com/a/55378168/294884
superview?.insertSubview(blurry, belowSubview: self)
ba = UIViewPropertyAnimator(duration:1, curve:.linear) {[weak self] in
// note, those duration/curve values are simply unusued
self?.blurry.effect = UIBlurEffect(style: .extraLight)
}
ba?.fractionComplete = live.largeplaybutton_blurfactor
}
override func willMove(toSuperview newSuperview: UIView?) {
// Teardown for the blurry ball - critical
if newSuperview == nil { print("safe teardown")
ba?.stopAnimation(true)
ba?.finishAnimation(at: .current)
}
}
override func layoutSubviews() { super.layoutSubviews()
blurry.frame = bounds, your drawing frame or whatever
}
{A parte: come una questione generale di ingegneria iOS, didMoveToWindow
potrebbe essere più adatto a te di didMoveToSuperview
. In secondo luogo, è possibile utilizzare un altro modo per eseguire lo smontaggio, ma lo smontaggio sono le due righe di codice mostrate lì.}
BlurryBall
è solo un UIVisualEffectView
. Nota gli init per una vista degli effetti visivi. Se hai bisogno di angoli arrotondati o altro, fallo in questa classe.
class BlurryBall: UIVisualEffectView {
override init(effect: UIVisualEffect?) { super.init(effect: effect)
commonInit() }
required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder)
commonInit() }
private func commonInit() {
clipsToBounds = true
backgroundColor = .clear
}
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = bounds.width / 2
}
}
Apple ha fornito un'estensione per la classe UIImage chiamata UIImage + ImageEffects.h. In questa classe hai i metodi desiderati per sfocare la tua vista
Ecco il codice Swift 2.0 per la soluzione fornita nella risposta accettata :
//only apply the blur if the user hasn't disabled transparency effects
if !UIAccessibilityIsReduceTransparencyEnabled() {
self.view.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth, .FlexibleHeight]
self.view.addSubview(blurEffectView) //if you have more UIViews, use an insertSubview API to place it where needed
} else {
self.view.backgroundColor = UIColor.blackColor()
}
Se aggiunge una vista sfocatura scura per tableView, questo lo renderà magnificamente:
tableView.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = tableView.bounds
blurEffectView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
// Assigning blurEffectView to backgroundView instead of addSubview to tableView makes tableView cell not blocked by blurEffectView
tableView.backgroundView = blurEffectView
Puoi creare direttamente la sfocatura dello sfondo usando "Vista effetto visivo con sfocatura" e "Vista effetto visivo con sfocatura e vividezza".
Tutto quello che devi fare per creare sfocatura dello sfondo nell'applicazione iOS è ...
Layout dell'applicazione prima di fare clic su qualsiasi pulsante!
Se questo aiuta qualcuno, ecco una rapida estensione che ho creato sulla base della risposta di Jordan H. È scritto in Swift 5 e può essere utilizzato dall'Obiettivo C.
extension UIView {
@objc func blurBackground(style: UIBlurEffect.Style, fallbackColor: UIColor) {
if !UIAccessibility.isReduceTransparencyEnabled {
self.backgroundColor = .clear
let blurEffect = UIBlurEffect(style: style)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.self.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
self.insertSubview(blurEffectView, at: 0)
} else {
self.backgroundColor = fallbackColor
}
}
}
NOTA: se si desidera sfocare lo sfondo di un UILabel senza influire sul testo, è necessario creare un UIView contenitore, aggiungere UILabel al contenitore UIView come sottoview, impostare il backgroundColor di UILabel su UIColor.clear, quindi chiamare blurBackground (stile : UIBlurEffect.Style, fallbackColor: UIColor) sul contenitore UIView. Ecco un breve esempio di questo scritto in Swift 5:
let frame = CGRect(x: 50, y: 200, width: 200, height: 50)
let containerView = UIView(frame: frame)
let label = UILabel(frame: frame)
label.text = "Some Text"
label.backgroundColor = UIColor.clear
containerView.addSubview(label)
containerView.blurBackground(style: .dark, fallbackColor: UIColor.black)
Swift 4:
Per aggiungere una sovrapposizione o la vista popup È inoltre possibile utilizzare la vista contenitore con la quale si ottiene un controller vista gratuito (si ottiene la vista contenitore dalla normale tavolozza / libreria di oggetti)
passi:
Avere una vista (ViewForContainer nella foto) che contiene questa vista contenitore, per oscurarla quando vengono visualizzati i contenuti della vista contenitore. Collegare la presa all'interno del primo View Controller
Nascondi questa vista quando viene caricato il 1 ° VC
Scopri quando si fa clic sul pulsante, immettere qui la descrizione dell'immagine
Per oscurare questa vista quando viene visualizzato il contenuto della vista contenitore, impostare lo Sfondo delle viste su Nero e l'opacità sul 30%
Ho aggiunto una risposta alla creazione della vista popview in un'altra domanda StackOver https://stackoverflow.com/a/49729431/5438240
La risposta semplice è Aggiungi una sottoview e cambiarla è alfa.
UIView *mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
UIView *subView = [[UIView alloc] initWithFrame:popupView.frame];
UIColor * backImgColor = [UIColor colorWithPatternImage:[UIImage imageNamed:@"blue_Img.png"]];
subView.backgroundColor = backImgColor;
subView.alpha = 0.5;
[mainView addSubview:subView];