Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
UI gaussian blur
-
@Phuket2 Basically, you just create a
BlurView
instance, and add it on top of the background you want to apply the blur effect on. -
@omz , ok thanks.
Should it work if you already have a custom class that inherits from ui.View, then you change it to inherit from BlurView instead -
@Phuket2 Should be possible, but you must make sure to call
BlurView.__init__
in your custom subclass. -
@omz I have been playing around with
UIBlurView
andUIVibrancyEffect
, but have not been able to get theUIVibrancyEffect
to work (text does not show up). Any suggestions on how to get it to work? I'm away from my iPad right now and can post some code later, if needed. But, my code is based on the followingObjective-C
code:// Blur effect UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]; UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; [blurEffectView setFrame:self.view.bounds]; [self.view addSubview:blurEffectView]; // Vibrancy effect UIVibrancyEffect *vibrancyEffect = [UIVibrancyEffect effectForBlurEffect:blurEffect]; UIVisualEffectView *vibrancyEffectView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect]; [vibrancyEffectView setFrame:self.view.bounds]; // Label for vibrant text UILabel *vibrantLabel = [[UILabel alloc] init]; [vibrantLabel setText:@"Vibrant"]; [vibrantLabel setFont:[UIFont systemFontOfSize:72.0f]]; [vibrantLabel sizeToFit]; [vibrantLabel setCenter: self.view.center]; // Add label to the vibrancy view [[vibrancyEffectView contentView] addSubview:vibrantLabel]; // Add the vibrancy view to the blur view [[blurEffectView contentView] addSubview:vibrancyEffectView];
Thanks,
B -
@blmacbeth Here's an extended version of
BlurView
that includes support for vibrancy effects. Themain
function shows a little demo.# coding: utf-8 import ui from objc_util import * class BlurView (ui.View): def __init__(self, style=1, *args, **kwargs): ui.View.__init__(self, **kwargs) self._style = style self.effect_view = None self.setup_effect_view() @on_main_thread def setup_effect_view(self): if self.effect_view is not None: self.effect_view.removeFromSuperview() UIVisualEffectView = ObjCClass('UIVisualEffectView') UIVibrancyEffect = ObjCClass('UIVibrancyEffect') UIBlurEffect = ObjCClass('UIBlurEffect') UILabel = ObjCClass('UILabel') frame = (self.bounds[:2], self.bounds[2:]) self.effect_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() effect = UIBlurEffect.effectWithStyle_(self._style) self.effect_view.effect = effect self.effect_view.setAutoresizingMask_(18) ObjCInstance(self).addSubview_(self.effect_view) vibrancy_effect = UIVibrancyEffect.effectForBlurEffect_(effect) self.vibrancy_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() self.vibrancy_view.effect = vibrancy_effect self.effect_view.contentView().addSubview_(self.vibrancy_view) @property def style(self): return self._style @style.setter def style(self, value): if value != self._style: self._style = value self.setup_effect_view() @on_main_thread def add_vibrant_label(self, label): self.vibrancy_view.contentView().addSubview_(ObjCInstance(label)) def main(): image_view = ui.ImageView(frame=(0, 0, 320, 320)) image_view.image = ui.Image.named('test:Mandrill') blur_view = BlurView(style=2, frame=image_view.bounds.inset(40, 40)) image_view.add_subview(blur_view) label = ui.Label(frame=blur_view.bounds) label.text = 'Hello World' label.font = ('HelveticaNeue', 40) label.alignment = ui.ALIGN_CENTER blur_view.add_vibrant_label(label) image_view.present('sheet') main()
-
@omz You're the man! Thanks for that.
-
Noticed some bugs in the above code, so here are my fixes to make it work (in Pythonista3, at least).
# coding: utf-8 import ui from objc_util import * class BlurView (ui.View): def __init__(self, style=1, *args, **kwargs): ui.View.__init__(self, **kwargs) self._style = style self.effect_view = None self.setup_effect_view() @on_main_thread def setup_effect_view(self): if self.effect_view is not None: self.effect_view.removeFromSuperview() UIVisualEffectView = ObjCClass('UIVisualEffectView') UIVibrancyEffect = ObjCClass('UIVibrancyEffect') UIBlurEffect = ObjCClass('UIBlurEffect') UILabel = ObjCClass('UILabel') # Brooks patch for Rect not having a 'slice' bounds = self.bounds.as_tuple() frame = (bounds[:2], bounds[2:]) self.effect_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() effect = UIBlurEffect.effectWithStyle_(self._style) self.effect_view.effect = effect self.effect_view.setAutoresizingMask_(18) ObjCInstance(self).addSubview_(self.effect_view) vibrancy_effect = UIVibrancyEffect.effectForBlurEffect_(effect) self.vibrancy_view = UIVisualEffectView.alloc().initWithFrame_(frame).autorelease() self.vibrancy_view.effect = vibrancy_effect self.effect_view.contentView().addSubview_(self.vibrancy_view) @property def style(self): return self._style @style.setter def style(self, value): if value != self._style: self._style = value self.setup_effect_view() # Brooks fix @on_mains_thread to @on_main_thread @on_main_thread def add_vibrant_label(self, label): self.vibrancy_view.contentView().addSubview_(ObjCInstance(label)) def main(): image_view = ui.ImageView(frame=(0, 0, 320, 320)) image_view.image = ui.Image.named('test:Mandrill') blur_view = BlurView(style=2, frame=image_view.bounds.inset(40, 40)) image_view.add_subview(blur_view) label = ui.Label(frame=blur_view.bounds) label.text = 'Hello World' label.font = ('HelveticaNeue', 40) label.alignment = ui.ALIGN_CENTER blur_view.add_vibrant_label(label) image_view.present('sheet') main()
The biggest problem was that the
ui.Rect()
object does not have the ability to useslices
. This was fixed with theui.Rect().as_tuple()
function. The second problem was just a typo.B
-
How could you apply the vibrancy effect to work with a rectangular region rather than a label? I read there is a fill method and a separator method but not sure how you would implement.
-
@rb What do you call a rectangular region? A label could be seen as a rectangular region if you don't set its text.
-
Ah ok - so what is the difference then between fill and label?I just thought label would be isolated to text - but it I’ll try that!
-
@rb the blur_view it-self is a rectangular region, thus no need of label at all
def main(): image_view = ui.ImageView(frame=(0, 0, 320, 320)) image_view.image = ui.Image.named('test:Mandrill') blur_view = BlurView(style=16, frame=image_view.bounds.inset(40, 40)) image_view.add_subview(blur_view) #label = ui.Label(frame=blur_view.bounds) #label.text = 'Hello World' #label.font = ('HelveticaNeue', 40) #label.alignment = ui.ALIGN_CENTER #blur_view.add_vibrant_label(label) image_view.present('sheet')
-
No I mentioned vibrancy- ie I want bg to be blurred but a central rectangle to be not blurred and more vibrant.
-
@rb ok, sorry, misunderstood