ios - SegmentedControl 的新 iOS13 外观是否可供公众使用
解决方案
是的,我已经尽可能地做了类似的东西,所以我以任何一种方式分享它,只有一个问题是这不能很好地调整大小并且更适合静态项目列表
@IBDesignable
class BlurredSegmentedControl: UIView {
var delegate:TabBarDelegate?
static var segmentInset: CGFloat = 4
static var cornerRadius: CGFloat = 15
let segmentedControl: UISegmentedControl = {
let control = UISegmentedControl()
control.backgroundColor = .clear
control.tintColor = .clear
control.setTitleTextAttributes([
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14) as Any,
NSAttributedString.Key.foregroundColor: UIColor.lightGray
], for: .normal)
control.setTitleTextAttributes([
NSAttributedString.Key.font: UIFont.systemFont(ofSize: 14) as Any,
NSAttributedString.Key.foregroundColor: UIColor.white
], for: .selected)
control.translatesAutoresizingMaskIntoConstraints = false
return control
}()
let bacgroundView: UIView = {
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.layer.cornerRadius = cornerRadius + (segmentInset / 2)
blurEffectView.clipsToBounds = true
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
return blurEffectView
}()
let bottomBar: UIView = {
let blurEffect = UIBlurEffect(style: UIBlurEffect.Style.light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurEffectView.layer.cornerRadius = cornerRadius
blurEffectView.clipsToBounds = true
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
return blurEffectView
}()
@IBInspectable
var segmentItems: [String] = [] {
didSet {
guard segmentItems.count > 0 else { return }
setupSegmentItems()
}
}
var bottomBarWidthAnchor: NSLayoutConstraint?
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
addSubview(bacgroundView)
addSubview(bottomBar)
addSubview(segmentedControl)
bacgroundView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
bacgroundView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
bacgroundView.topAnchor.constraint(equalTo: topAnchor).isActive = true
bacgroundView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
segmentedControl.widthAnchor.constraint(equalTo: widthAnchor, constant: -2 * BlurredSegmentedControl.segmentInset).isActive = true
segmentedControl.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
segmentedControl.topAnchor.constraint(equalTo: topAnchor, constant: BlurredSegmentedControl.segmentInset).isActive = true
segmentedControl.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -1 * BlurredSegmentedControl.segmentInset).isActive = true
segmentedControl.addTarget(self, action: #selector(segmentedControlValueChanged(_:)), for: .valueChanged)
bottomBar.topAnchor.constraint(equalTo: topAnchor, constant: BlurredSegmentedControl.segmentInset).isActive = true
bottomBar.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -1 * BlurredSegmentedControl.segmentInset).isActive = true
bottomBar.leftAnchor.constraint(equalTo: leftAnchor, constant: BlurredSegmentedControl.segmentInset).isActive = true
setupSegmentItems()
}
private func setupSegmentItems() {
if(segmentItems.count < 1) { return }
segmentedControl.removeAllSegments()
for (index, value) in segmentItems.enumerated() {
segmentedControl.insertSegment(withTitle: value, at: index, animated: true)
}
segmentedControl.selectedSegmentIndex = 0
bottomBarWidthAnchor?.isActive = false
bottomBarWidthAnchor = bottomBar.widthAnchor.constraint(equalTo: segmentedControl.widthAnchor, multiplier: 1 / CGFloat(segmentItems.count))
bottomBarWidthAnchor?.isActive = true
delegate?.selectedTabItem(title: segmentItems[0])
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
}
@objc func segmentedControlValueChanged(_ sender: UISegmentedControl) {
delegate?.selectedTabItem(title: segmentItems[self.segmentedControl.selectedSegmentIndex])
UIView.animate(withDuration: 0.3) {
var offset: CGFloat = 0
if self.segmentedControl.selectedSegmentIndex == 0 {
offset = BlurredSegmentedControl.segmentInset
}
if self.segmentedControl.selectedSegmentIndex == self.segmentItems.count - 1 {
offset = (1 * BlurredSegmentedControl.segmentInset)
}
let originX = ((self.segmentedControl.frame.width / CGFloat(self.segmentItems.count)) * CGFloat(self.segmentedControl.selectedSegmentIndex)) + offset
self.bottomBar.frame.origin.x = originX
}
}
}
推荐阅读
- java - 为什么我的垂直产品求和程序会出现“索引越界”异常?
- python - 如何使用 requests_html 异步获取() URL 列表?
- android - 我想通过使用分切器将扬声器输出循环回麦克风来在 Android 手机上播放音频消息。它会起作用吗?
- r - 如何在 r 中制作年度音乐排行榜?重复合并不起作用
- android - ArrayAdapter.getItem java.lang.IndexOutOfBoundsException:索引:1,大小:1
- c - 无限制计算无符号整数最大值的最佳算法.h
- gtk - 为 GtkWindow 使用 GdkWindow 的功能
- excel - 基于另一个具有数据的单元格格式化一个单元格
- html - 调整屏幕大小时菜单动画错误
- c# - 调试 C# 外部类