user784637
user784637

Reputation: 16152

How to blur the background of a segmented control?

I'm defining a segmented control inside of a UITableViewDelegate's tableView(_:viewForHeaderInSection:). Since I'm using UITableView.Style.plain, when the table scrolls, the header with the segmented control stays in a fixed position.

I'd like to create some context so that the background of the unselected segmented control blurs the table that is scrolling behind it. Here is what an ios 13 segmented control looks like:

Is there a way to blur the background of a segmented control's unselected segments?

I'm able to created a segmented control like this

let items = ["First", "Second"]
let customSC = UISegmentedControl(items: items)
customSC.selectedSegmentIndex = 0

And I'm able to create a blur with this https://stackoverflow.com/a/25706250/784637

let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
//always fill the view
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

But I don't know how to bring everything together

Upvotes: 1

Views: 686

Answers (2)

Asperi
Asperi

Reputation: 258443

Here is possible approach... the idea is to place blur-effect view behind the segmented control in some wrapper view and provide that view as header for table.

Here is demo (how it looks with just some my settings, but those are all configurable), of course gif is not very good for this, but it is visible that blur effect works.

enter image description here

Approach demo code:

class HeaderView: UIView {
    override init(frame: CGRect) {
        super.init(frame: frame)

        let blurEffect = UIBlurEffect(style: .dark) // .light looks better as for me, so used in demo
        let blurEffectView = UIVisualEffectView(effect: blurEffect)
        blurEffectView.translatesAutoresizingMaskIntoConstraints = false

        let items = ["First", "Second"]
        let customSC = UISegmentedControl(items: items)
        customSC.selectedSegmentIndex = 0
        customSC.translatesAutoresizingMaskIntoConstraints = false

        self.addSubview(customSC)
        customSC.centerXAnchor.constraint(equalTo: self.centerXAnchor).isActive = true
        customSC.centerYAnchor.constraint(equalTo: self.centerYAnchor).isActive = true
        customSC.widthAnchor.constraint(equalToConstant: 200).isActive = true
        customSC.heightAnchor.constraint(equalToConstant: 60).isActive = true

        self.insertSubview(blurEffectView, belowSubview: customSC)
        blurEffectView.leadingAnchor.constraint(equalTo: customSC.leadingAnchor).isActive = true
        blurEffectView.trailingAnchor.constraint(equalTo: customSC.trailingAnchor).isActive = true
        blurEffectView.topAnchor.constraint(equalTo: customSC.topAnchor).isActive = true
        blurEffectView.bottomAnchor.constraint(equalTo: customSC.bottomAnchor).isActive = true
        blurEffectView.layer.cornerRadius = 8
        blurEffectView.layer.masksToBounds = true
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

Upvotes: 2

Mohan Meruva
Mohan Meruva

Reputation: 322

You can use the below tableView delegates to create custom header view.

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    //Create header view and add blur effect
    let headerView = UITableViewHeaderFooterView()
    let blurEffect = UIBlurEffect(style: .dark)
    let blurEffectView = UIVisualEffectView(effect: blurEffect)
    headerView.backgroundView = blurEffectView

    //Add Segmented Control ot headerView
    let items = ["first", "second"]
    let segmentedControl = UISegmentedControl(items: items)
    segmentedControl.frame = CGRect(x: 0, y: 0, width: tableView.frame.width, height: 50)
    segmentedControl.backgroundColor = .clear
    segmentedControl.selectedSegmentIndex = 0
    segmentedControl.selectedSegmentTintColor = .red
    headerView.contentView.addSubview(segmentedControl)
    return headerView
}

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 50
}

Upvotes: 0

Related Questions