UIBlurEffect on StatusBar only (not on UINavigationBar) - ios

Similar to this:
How to make a Navigation Bar and Status Bar blurred (UIBlurEffect)? iOS, Swift 3
but we'd like to apply the UIBlurEffect on the StatusBar only, not the navigationbar. Is this possible?

You can get your statusBar view by following code, then try add to visual effect like here
let statWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statWindow.subviews[0] as UIView
// statusBar.backgroundColor = UIColor(red: 23 / 255.0, green: 0 / 255.0, blue: 154 / 255.0, alpha: 0.7)
statusBar.backgroundColor = UIColor(red: 213 / 255.0, green: 0 / 255.0, blue: 0 / 255.0, alpha: 0.7)

let statWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statWindow.subviews[0] as UIView
statusBar.backgroundColor = UIColor.clear
let blur = UIBlurEffect(style:.dark)
let visualeffect = UIVisualEffectView(effect: blur)
visualeffect.frame = statusBar.frame
//statusBar.addSubview(visualeffect)
visualeffect.alpha = 0.5
self.view.addSubview(visualeffect)
try this

iOS 14/iOS 13 solution: You can get your statusBar blur effect, by following code in your viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let blurryEffect = UIBlurEffect(style: .regular)
let blurredStatusBar = UIVisualEffectView(effect: blurryEffect)
blurredStatusBar.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(blurredStatusBar)
blurredStatusBar.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
blurredStatusBar.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
blurredStatusBar.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
blurredStatusBar.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true }
Sample Image

Related

iOS 13 Tab Bar Layer attribute is missing swift

I have added shadow on Tab Bar in initial versions on layer, but on iOS 13 we have to use Appearance that don't have layer attribute, how to add Shadow now.
Shadow on top like below image.
if #available(iOS 13, *) {
let appearance = self.self.tabBarController?.tabBar.standardAppearance.copy()
appearance?.backgroundImage = UIImage()
appearance?.shadowImage = UIImage()
appearance?.shadowColor = .clear
//appearance?.layer this is missing now
if let appearance = appearance{
self.tabBarController?.tabBar.standardAppearance = appearance
}
} else {
self.tabBarController?.tabBar.shadowImage = UIImage()
self.tabBarController?.tabBar.backgroundImage = UIImage()
self.tabBarController?.tabBar.layer.shadowOpacity = 0.0
self.tabBarController?.tabBar.layer.borderWidth = 0.0
self.tabBarController?.tabBar.clipsToBounds = true
self.tabBarController?.tabBar.layer.applySketchShadow(color: UIColor(red: 15/255, green: 54/255, blue: 136/255, alpha: 1.0), alpha: 0.1, x: 0, y: 0, blur: 25, spread: 0)
self.tabBarController?.tabBar.clipsToBounds = false
}
Set clipsToBounds False will do the magic for you.
//**self.tabBarController?.tabBar.clipsToBounds = false**
if #available(iOS 13, *) {
let appearance = self.self.tabBarController?.tabBar.standardAppearance.copy()
appearance?.backgroundImage = UIImage()
appearance?.shadowImage = UIImage()
appearance?.configureWithTransparentBackground()
if let appearance = appearance{
self.tabBarController?.tabBar.standardAppearance = appearance
}
} else {
self.tabBarController?.tabBar.shadowImage = UIImage()
self.tabBarController?.tabBar.backgroundImage = UIImage()
self.tabBarController?.tabBar.clipsToBounds = false
}
self.tabBarController?.tabBar.clipsToBounds = false
self.tabBarController?.tabBar.layer.shadowOpacity = 0.0
self.tabBarController?.tabBar.layer.borderWidth = 0.0
self.tabBarController?.tabBar.layer.applySketchShadow(color: UIColor(red: 15/255, green: 54/255, blue: 136/255, alpha: 1.0), alpha: 0.1, x: 0, y: 0, blur: 25, spread: 0)
UIBarAppearance has shadowImage and shadowColor properties. Set them as desired. Right now you are setting them to have no shadow.
Also configureWithTransparentBackground means no shadow. So you are removing the shadow and then asking where the shadow is.
Try the below code in your UITabBarController class
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 13, *) {
let appearance = self.tabBar.standardAppearance.copy()
appearance.backgroundImage = UIImage()
appearance.shadowImage = UIImage()
self.tabBar.standardAppearance = appearance
} else {
self.tabBar.shadowImage = UIImage()
self.tabBar.backgroundImage = UIImage()
}
//Change These values according to your requirement. This will work for all iOS versions
self.tabBar.layer.shadowColor = UIColor.lightGray.cgColor
self.tabBar.layer.shadowOpacity = 0.3
self.tabBar.layer.shadowRadius = 5
}

SelectedTintColor of Segment Control is not rounded corner on iOS 13

Rounded corner is working great on iOS 12 and below, but it's broken on iOS 13. I've created a custom Segment control class.
Code:
class SegmentedControl: UISegmentedControl {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = self.bounds.size.height / 2.0
layer.borderColor = UIColor(red: 170.0/255.0, green: 170.0/255.0, blue: 170.0/255.0, alpha: 1.0).cgColor
layer.borderWidth = 1.0
layer.masksToBounds = true
clipsToBounds = true
}
}
I've gone through this post - How to change the colors of a segment in a UISegmentedControl in iOS 13?
but I couldn't get any solution.
Screenshot:
I was facing the same issue on iOS 13. Then I dug into its view hierarchy then I found it has multiple subviews. So I made a trick for iOS 13. You have to do following changes for iOS 13 -
ChangeselectedSegmentTintColor to Clear - self.selectedSegmentTintColor = .clear
Add following code snippet inside layoutSubviews -
for i in 0...subviews.count - 1{
if let subview = subviews[i] as? UIImageView{
if i == self.selectedSegmentIndex {
subview.backgroundColor = UIColor(red: 170.0/255.0, green: 170.0/255.0, blue: 170.0/255.0, alpha: 1.0)
}else{
subview.backgroundColor = .clear
}
}
}
I hope it will help you.
Similar to other solution I have Following Sub-Class Segment control
UISegmentedControl
Which gives following result -
class OYSegmentControl: UISegmentedControl {
override func layoutSubviews(){
super.layoutSubviews()
let segmentStringSelected: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.font : UIFont.fontActionLabel(ofSize: 14.0),
NSAttributedString.Key.foregroundColor : UIColor.white
]
let segmentStringHighlited: [NSAttributedString.Key : Any] = [
NSAttributedString.Key.font : UIFont.fontActionLabel(ofSize: 14.0),
NSAttributedString.Key.foregroundColor : #colorLiteral(red: 0.5567105412, green: 0.5807551742, blue: 0.6022000909, alpha: 1)
]
setTitleTextAttributes(segmentStringHighlited, for: .normal)
setTitleTextAttributes(segmentStringSelected, for: .selected)
setTitleTextAttributes(segmentStringHighlited, for: .highlighted)
layer.masksToBounds = true
if #available(iOS 13.0, *) {
selectedSegmentTintColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
} else {
tintColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
}
backgroundColor = #colorLiteral(red: 0.9191747308, green: 0.9334954619, blue: 0.9506797194, alpha: 1)
//corner radius
let cornerRadius = bounds.height / 2
let maskedCorners: CACornerMask = [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMinYCorner, .layerMaxXMaxYCorner]
//background
clipsToBounds = true
layer.cornerRadius = cornerRadius
layer.maskedCorners = maskedCorners
let foregroundIndex = numberOfSegments
if subviews.indices.contains(foregroundIndex),
let foregroundImageView = subviews[foregroundIndex] as? UIImageView {
foregroundImageView.image = UIImage()
foregroundImageView.clipsToBounds = true
foregroundImageView.layer.masksToBounds = true
foregroundImageView.backgroundColor = #colorLiteral(red: 0, green: 0.861200273, blue: 0.67304039, alpha: 1)
foregroundImageView.layer.cornerRadius = bounds.height / 2 + 5
foregroundImageView.layer.maskedCorners = maskedCorners
}
}
override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return false
}
}
Language: Swift 5.1
NOTE: This only works if you have outlet / frame set from Storyboard.
Frame from code will cause issues.
The extra 5 px on cornerRadius,a hack to make it better round rect.
I ended up using - https://github.com/alokc83/MASegmentedControl as my use-case was from Code only view.
Swift 5
If you use a subclass:
override func layoutSubviews() {
super.layoutSubviews()
roundCorners(radius: frame.height / 2)
if #available(iOS 13.0, *) {
selectedSegmentTintColor = .clear
} else {
tintColor = .clear
}
for (index, subview) in subviews.enumerated() {
if ((subviews[index] as? UIImageView) != nil) && index == selectedSegmentIndex {
subview.backgroundColor = .white
subview.roundCorners(radius: subview.frame.height / 2)
} else {
subview.backgroundColor = .clear
}
}
}
Conienience method:
extension UIView {
func roundCorners(radius: CGFloat) {
layer.roundCorners(radius: radius)
self.clipsToBounds = true
}
}
If you use the default segmented control, you just prefix with name of your segmented control:
mySegmentedControl.selectedSegmentTintColor = .clear
for (index, subview) in mySegmentedControl.subviews.enumerated() {
.....
}
Make a custom class for segment
class CustomSegmentedControl: UISegmentedControl {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = self.bounds.size.height / 2.0
layer.borderColor = use_your_custom_color
layer.borderWidth = 1.0
layer.masksToBounds = true
clipsToBounds = true
for i in 0...subviews.count - 1{
if let subview = subviews[i] as? UIImageView{
if i == self.selectedSegmentIndex {
subview.backgroundColor = use_your_custom_color
}else{
subview.backgroundColor = .white
}
}
}
}}
May be this will easy to use like this
#IBOutlet weak var reminderSegmentControl: CustomSegmentedControl!
this code works for me iOS 13 - Swift 5.1
segment.layer.cornerRadius = 12
segment.layer.borderWidth = 1
segment.layer.borderColor = UIColor.black.cgColor
segment.font(name: "TheSans-Plain", size: 14)
segment.clipsToBounds = true
segment.layer.masksToBounds = true
if #available(iOS 13.0, *) {
segment.selectedSegmentTintColor = .red
}

Status bar Blur view (Translucent ) in swift 4.2 ios 12

I am trying to blur the status bar depending on the background like it works when we pull down the status bar. like it is see through
let statusBarFrame = UIApplication.shared.statusBarFrame
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
visualEffectView.frame = statusBarFrame
view.addSubview(visualEffectView)
I have tried all styles but it does change to translucent
even I tried from storyboard effect shows in the storyboard but not in simulator even my Reduce Transparency is also turned on
I want to achive this in the stausbar
but it only gives a white bar
You can get your statusBar view by following code, then try add to visual effect like here
let statWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statWindow.subviews[0] as UIView
statusBar.backgroundColor = UIColor(red: 213 / 255.0, green: 0 / 255.0, blue: 0 / 255.0, alpha: 0.7)
OR
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
}
}
Usage
navigationController?.navigationBar.installBlurEffect()

How to arrange views in the `UIStackView`?

I want to set four views in the UIStackView with the horizontal direction. The four views next to each without space.
My code:
let arrangeStackView = UIStackView()
let followUpActionView = UIView()
let developCurriculumView = UIView()
let moreMoreView = UIView()
let takeCareSalonView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(arrangeStackView)
developCurriculumView.translatesAutoresizingMaskIntoConstraints = false;
followUpActionView.translatesAutoresizingMaskIntoConstraints = false;
takeCareSalonView.translatesAutoresizingMaskIntoConstraints = false;
moreMoreView.translatesAutoresizingMaskIntoConstraints = false;
developCurriculumView.backgroundColor = UIColor(red: CGFloat(arc4random()%256)/255.0, green: CGFloat(arc4random()%256)/255.0, blue: CGFloat(arc4random()%256)/255.0, alpha: 1)
followUpActionView.backgroundColor = UIColor(red: CGFloat(arc4random()%256)/255.0, green: CGFloat(arc4random()%256)/255.0, blue: CGFloat(arc4random()%256)/255.0, alpha: 1)
takeCareSalonView.backgroundColor = UIColor(red: CGFloat(arc4random()%256)/255.0, green: CGFloat(arc4random()%256)/255.0, blue: CGFloat(arc4random()%256)/255.0, alpha: 1)
moreMoreView.backgroundColor = UIColor(red: CGFloat(arc4random()%256)/255.0, green: CGFloat(arc4random()%256)/255.0, blue: CGFloat(arc4random()%256)/255.0, alpha: 1)
arrangeStackView.axis = .horizontal
arrangeStackView.distribution = .fillEqually
arrangeStackView.spacing = 10
arrangeStackView.alignment = .fill
arrangeStackView.translatesAutoresizingMaskIntoConstraints = false
arrangeStackView.addSubview(followUpActionView)
arrangeStackView.addSubview(developCurriculumView)
arrangeStackView.addSubview(moreMoreView)
arrangeStackView.addSubview(takeCareSalonView)
arrangeStackView.snp.makeConstraints { (make) in
make.center.equalToSuperview()
make.height.equalTo(95)
make.width.equalToSuperview()
}
let yaIconWith = self.view.frame.width * 0.25
followUpActionView.snp.makeConstraints{(make) -> Void in
make.height.equalToSuperview()
make.width.equalTo(yaIconWith)
}
takeCareSalonView.snp.makeConstraints{(make) -> Void in
make.height.equalToSuperview()
make.width.equalTo(yaIconWith)
}
moreMoreView.snp.makeConstraints{(make) -> Void in
make.height.equalToSuperview()
make.width.equalTo(yaIconWith)
}
developCurriculumView.snp.makeConstraints{(make) -> Void in
make.height.equalToSuperview()
make.width.equalTo(yaIconWith)
}
Now, I look the result as below.
Why the four views locate the top-left on the screen?
You added each of the views as a subview to the stack view, instead of adding each view as an arranged subview. While they sound similar, only the arranged subviews are laid out according to the stack view's properties.
So you will change these lines:
arrangeStackView.addSubview(followUpActionView)
arrangeStackView.addSubview(developCurriculumView)
arrangeStackView.addSubview(moreMoreView)
arrangeStackView.addSubview(takeCareSalonView)
To this:
arrangeStackView.addArrangedSubview(followUpActionView)
arrangeStackView.addArrangedSubview(developCurriculumView)
arrangeStackView.addArrangedSubview(moreMoreView)
arrangeStackView.addArrangedSubview(takeCareSalonView)
And if you need special arrangement or if you need to add the views at different times in certain places, insertArrangedSubview(_:at:) is an alternative to addArrangedSubview(_:)
A UIStackView only distributes its arrangedSubViews not its regular subViews. Use addArrangedSubview instead of addSubView.

XLPagerTabStrip - Selected tab selection not working

The selected tab indicator in the XLPagerTabStrip Library is not working with Swift 3 and XCode 8
I'm using the following customization for the Tab Strip
super.viewDidLoad()
buttonBarView.selectedBar.backgroundColor = UIColor(red: 240.0/255.0, green: 89.0/255.0, blue: 43.0/255.0, alpha: 1.0)
buttonBarView.backgroundColor = UIColor.clear
settings.style.selectedBarHeight = 3.0
settings.style.selectedBarBackgroundColor = UIColor(red: 240.0/255.0, green: 89.0/255.0, blue: 43.0/255.0, alpha: 1.0)
settings.style.buttonBarHeight = 45.0
settings.style.buttonBarMinimumLineSpacing = 0.0
settings.style.buttonBarLeftContentInset = 0.0
settings.style.buttonBarRightContentInset = 0.0
settings.style.buttonBarItemFont = UIFont(name: "Avenir-Book", size: 12.0)!
settings.style.buttonBarItemBackgroundColor = UIColor.clear
settings.style.buttonBarItemLeftRightMargin = 0.0
settings.style.buttonBarItemTitleColor = UIColor.black
This is the solution for the above mentioned issue
class ViewController: ButtonBarPagerTabStripViewController {
override func viewDidAppear(_ animated: Bool) {
let selectedBarHeight: CGFloat = 2
buttonBarView.selectedBar.frame.origin.y = buttonBarView.frame.size.height - selectedBarHeight
buttonBarView.selectedBar.frame.size.height = selectedBarHeight
}
override func viewDidLoad() {
settings.style.selectedBarBackgroundColor = .green
super.viewDidLoad()
}
}

Resources