macOS - Swift 4.0 容器视图不显示 NSView
macOS - Swift 4.0 Container View does not show NSView
我正在使用 Swift 4.0 编写我的第一个 macOS 应用程序并且
目前我正在为我的容器视图而苦苦挣扎。
I've this layout
Layout while running the app
问题是,当我单击其中一个 TableView 项目时,我的 Container View 没有加载其中带有 "THEMA 1" 标签的 NSView。
(所有 TableView 项目都应加载 "THEMA 1" 视图)
这是我的 ViewController 代码
import Cocoa
class ViewController: NSViewController {
//VARS
var tableViewArray = ["Thema 1", "Thema 2", "Thema 3", "Thema 4", "Thema 5"]
var containerViewArray: [NSView]!
var thema1View = Thema1()
//IBOutlets
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var container: NSView!
override func viewDidLoad() {
super.viewDidLoad()
//setup TableView
tableView.delegate = self
tableView.dataSource = self
tableView.action = #selector(onItemClicked)
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
//Extensions
extension ViewController: NSTableViewDelegate, NSTableViewDataSource {
//show what is clicked on tableView
@objc private func onItemClicked() {
if (tableView.clickedRow <= tableViewArray.count - 1) && (tableView.clickedRow >= 0) {
print("\(tableViewArray[tableView.clickedRow]), clicked")
removeAllSubView()
container.addSubview(thema1View, positioned: .above, relativeTo: container)
}
else {
print("There is no content in this cell")
}
}
//removes all SubViews from containerView
func removeAllSubView() {
for view in container.subviews{
view.removeFromSuperview()
}
}
//rows in tableViewArray
func numberOfRows(in tableView: NSTableView) -> Int {
return tableViewArray.count
}
//populate the tableView
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return tableViewArray[row]
}
}
Thema1 ViewController 代码
import Cocoa
class Thema1: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
}
}
我认为问题隐藏在 onItemClicked() 方法中,但正如我所提到的,我对 macOS 和 Swift 4.0 很陌生。
因此,我发现了很多关于 iOS 的结果,但只有少数 macOS,但没有任何迹象表明我的情况。
感谢您抽出宝贵时间并向您致以最诚挚的问候,
丹尼
我找到了示例代码 SourceView,但它相当复杂并且在 Objective-C 中。这是我把相关部分翻译成Swift(我对Swift不是很熟悉)。
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var tableViewArray = ["Thema 1", "Thema 2", "Thema 3", "Thema 4", "Thema 5"]
var detailViewController: NSViewController?
@IBOutlet weak var container: NSView!
@IBAction func tableViewClickAction(_ tableView: NSTableView) {
if tableView.clickedRow >= 0 {
print("\(tableViewArray[tableView.clickedRow]), clicked")
// remove the detail view if there is one
if let oldViewController = detailViewController {
oldViewController.view.removeFromSuperview()
oldViewController.removeFromParentViewController()
detailViewController = nil
}
// determine the identifier of the new detail view, this is the Storyboard ID of the detail scene
var sceneIdentifier: NSStoryboard.SceneIdentifier?
switch tableView.clickedRow {
case 0:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema1")
case 1:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema2")
case 2:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema3")
case 3:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema4")
case 4:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema5")
default:
sceneIdentifier = nil
}
if sceneIdentifier != nil {
// load the new detail controller and view from the storyboard
detailViewController = self.storyboard?.instantiateController(withIdentifier:sceneIdentifier!) as? NSViewController
if let newViewController = detailViewController {
newViewController.view.translatesAutoresizingMaskIntoConstraints = false
// add controller and view
self.addChildViewController(newViewController)
container.addSubview(newViewController.view)
// add constraints
let views = ["targetView": newViewController.view]
let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[targetView]|",
options: [], metrics: nil, views: views)
let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[targetView]|",
options: [], metrics: nil, views: views)
NSLayoutConstraint.activate(horizontalConstraints)
NSLayoutConstraint.activate(verticalConstraints)
}
}
}
else {
print("Clicked outside the cells")
}
}
}
感谢您帮助我提出故事板的想法。
我制作了一个测试假人,其中有我的主视图,并制作了两个带有标签的 ViewController。
所有 ViewController 都获得了它们的 Storyboard-ID。
主视图有两个按钮,都分配给其中一个 ViewController。
通过单击它们,您将加载其中一个测试视图控制器。
我想到了这个
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
func switchViews(viewNumber: Int) {
let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil)
var controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Main"))
switch viewNumber {
case 1:
print("View: 1")
controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Test1"))
case 2:
print("View: 2")
controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Test2"))
default:
print("Default");
}
if let window = NSApplication.shared.mainWindow {
window.contentViewController = controller as? NSViewController
}
}
@IBAction func buttonAction(_ sender: NSButton) {
var viewNumber: Int = 0
switch sender.title {
case "controller1":
viewNumber = 1
print("Button: 1")
case "controller2":
viewNumber = 2
print("Button2: 2")
default:
print("Default")
}
switchViews(viewNumber: viewNumber)
}
}
我正在使用 Swift 4.0 编写我的第一个 macOS 应用程序并且 目前我正在为我的容器视图而苦苦挣扎。
I've this layout
Layout while running the app
问题是,当我单击其中一个 TableView 项目时,我的 Container View 没有加载其中带有 "THEMA 1" 标签的 NSView。 (所有 TableView 项目都应加载 "THEMA 1" 视图)
这是我的 ViewController 代码
import Cocoa
class ViewController: NSViewController {
//VARS
var tableViewArray = ["Thema 1", "Thema 2", "Thema 3", "Thema 4", "Thema 5"]
var containerViewArray: [NSView]!
var thema1View = Thema1()
//IBOutlets
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var container: NSView!
override func viewDidLoad() {
super.viewDidLoad()
//setup TableView
tableView.delegate = self
tableView.dataSource = self
tableView.action = #selector(onItemClicked)
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
//Extensions
extension ViewController: NSTableViewDelegate, NSTableViewDataSource {
//show what is clicked on tableView
@objc private func onItemClicked() {
if (tableView.clickedRow <= tableViewArray.count - 1) && (tableView.clickedRow >= 0) {
print("\(tableViewArray[tableView.clickedRow]), clicked")
removeAllSubView()
container.addSubview(thema1View, positioned: .above, relativeTo: container)
}
else {
print("There is no content in this cell")
}
}
//removes all SubViews from containerView
func removeAllSubView() {
for view in container.subviews{
view.removeFromSuperview()
}
}
//rows in tableViewArray
func numberOfRows(in tableView: NSTableView) -> Int {
return tableViewArray.count
}
//populate the tableView
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
return tableViewArray[row]
}
}
Thema1 ViewController 代码
import Cocoa
class Thema1: NSView {
override func draw(_ dirtyRect: NSRect) {
super.draw(dirtyRect)
// Drawing code here.
}
}
我认为问题隐藏在 onItemClicked() 方法中,但正如我所提到的,我对 macOS 和 Swift 4.0 很陌生。 因此,我发现了很多关于 iOS 的结果,但只有少数 macOS,但没有任何迹象表明我的情况。
感谢您抽出宝贵时间并向您致以最诚挚的问候, 丹尼
我找到了示例代码 SourceView,但它相当复杂并且在 Objective-C 中。这是我把相关部分翻译成Swift(我对Swift不是很熟悉)。
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
var tableViewArray = ["Thema 1", "Thema 2", "Thema 3", "Thema 4", "Thema 5"]
var detailViewController: NSViewController?
@IBOutlet weak var container: NSView!
@IBAction func tableViewClickAction(_ tableView: NSTableView) {
if tableView.clickedRow >= 0 {
print("\(tableViewArray[tableView.clickedRow]), clicked")
// remove the detail view if there is one
if let oldViewController = detailViewController {
oldViewController.view.removeFromSuperview()
oldViewController.removeFromParentViewController()
detailViewController = nil
}
// determine the identifier of the new detail view, this is the Storyboard ID of the detail scene
var sceneIdentifier: NSStoryboard.SceneIdentifier?
switch tableView.clickedRow {
case 0:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema1")
case 1:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema2")
case 2:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema3")
case 3:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema4")
case 4:
sceneIdentifier = NSStoryboard.SceneIdentifier(rawValue: "Thema5")
default:
sceneIdentifier = nil
}
if sceneIdentifier != nil {
// load the new detail controller and view from the storyboard
detailViewController = self.storyboard?.instantiateController(withIdentifier:sceneIdentifier!) as? NSViewController
if let newViewController = detailViewController {
newViewController.view.translatesAutoresizingMaskIntoConstraints = false
// add controller and view
self.addChildViewController(newViewController)
container.addSubview(newViewController.view)
// add constraints
let views = ["targetView": newViewController.view]
let horizontalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "H:|[targetView]|",
options: [], metrics: nil, views: views)
let verticalConstraints = NSLayoutConstraint.constraints(withVisualFormat: "V:|[targetView]|",
options: [], metrics: nil, views: views)
NSLayoutConstraint.activate(horizontalConstraints)
NSLayoutConstraint.activate(verticalConstraints)
}
}
}
else {
print("Clicked outside the cells")
}
}
}
感谢您帮助我提出故事板的想法。 我制作了一个测试假人,其中有我的主视图,并制作了两个带有标签的 ViewController。 所有 ViewController 都获得了它们的 Storyboard-ID。 主视图有两个按钮,都分配给其中一个 ViewController。 通过单击它们,您将加载其中一个测试视图控制器。 我想到了这个
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
func switchViews(viewNumber: Int) {
let storyboard = NSStoryboard(name: NSStoryboard.Name(rawValue: "Main"), bundle: nil)
var controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Main"))
switch viewNumber {
case 1:
print("View: 1")
controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Test1"))
case 2:
print("View: 2")
controller = storyboard.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier(rawValue: "Test2"))
default:
print("Default");
}
if let window = NSApplication.shared.mainWindow {
window.contentViewController = controller as? NSViewController
}
}
@IBAction func buttonAction(_ sender: NSButton) {
var viewNumber: Int = 0
switch sender.title {
case "controller1":
viewNumber = 1
print("Button: 1")
case "controller2":
viewNumber = 2
print("Button2: 2")
default:
print("Default")
}
switchViews(viewNumber: viewNumber)
}
}