我正在尝试创建一个类似于 Xcode 属性面板的选项卡式面板,但标准选项卡式面板似乎具有不同的外观和感觉,无法更改它。应该使用哪些控件来创建外观相似的选项卡式面板?
编辑:我没有使用 NSTabViewController - 只是有 TabView !
我刚刚创建了一个带有情节提要和提供的布局的新项目,添加到视图控制器视图顶部的自定义视图。向自定义视图添加按钮,样式 = 方形,类型 = 切换,并使用提供的模板类型图标。将标签分配给按钮 0-4,并将它们放入水平堆栈视图。然后添加了一条水平线和一个容器视图。然后我将一个选项卡视图控制器添加到情节提要中并将其嵌入到容器视图中。所有按钮都连接到相同的操作。
import Cocoa
class ViewController: NSViewController {
@IBOutlet var myStackView: NSStackView!
var oldSelection: Int = 0
var newSelection: Int = 0
var buttons: [NSButton]?
var tabViewDelegate: NSTabViewController?
@IBAction func selectedButton(_ sender: NSButton) {
newSelection = sender.tag
tabViewDelegate?.selectedTabViewItemIndex = newSelection
buttons![oldSelection].state = .off
sender.state = .on
oldSelection = newSelection
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
buttons = (myStackView.arrangedSubviews as! [NSButton])
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
override func prepare(for segue: NSStoryboardSegue, sender: Any?) {
// Once on load
tabViewDelegate = segue.destinationController as? NSTabViewController
}
}
struct SystemSegmentControl : View {
// MARK: - Internal -
@Binding var selection : Int
let systemImages: [String]
var body : some View {
HStack(spacing: 5) {
ForEach (0..<systemImages.count) { i in
SystemSegmentButton(selection: self.$selection, selectionIndex: i, systemImage: systemImages[i])
}
}
}
}
struct SystemSegmentButton : View {
// MARK: - Internal -
@Binding var selection : Int
let selectionIndex: Int
let systemImage : String
var body : some View {
Button(action: { self.selection = self.selectionIndex }) {
Image(systemName: systemImage)
.padding(8)
.foregroundColor(selectionIndex == selection ? .controlAccentColor : .controlColor)
}
.buttonStyle(BorderlessButtonStyle())
}
}
struct SettingsView: View {
// MARK: - Internal -
var body: some View {
GeometryReader { geometry in
VStack(spacing: 0) {
SystemSegmentControl(selection: $selection, systemImages: ["slider.horizontal.3", "eye"])
Divider()
switch selection {
case 0:
Text("Tab 1")
default:
Text("Tab 2")
}
}
.frame(width: geometry.size.width, height: geometry.size.height, alignment: .topLeading)
}
.frame(width: 250)
}
// MARK: - Private -
@State private var selection = 0
}