从XIB OS X App添加(addsubview)自定义/可重用视图

时间:2017-12-26 18:12:02

标签: swift macos swift4

以下是我的自定义视图的代码。我还有一个自定义XIB文件,其中包含视图mainView。我需要在视图控制器的stackView中使用这3次。我该怎么做?

class PlatformView: NSView {

    @IBOutlet weak var mainView: NSView!
    @IBOutlet weak var currentPriceLabel: NSTextField!

    //Here is the button
    @IBAction func testButtonPressed(_ sender: Any) {
    }

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
        // Drawing code here.
    }

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        NSNib(nibNamed: NSNib.Name(rawValue: "PlatformView"), bundle: nil)?.instantiate(withOwner: self, topLevelObjects: nil)
        addSubview(mainView)
        self.mainView.frame = self.bounds
    }
}

这是我的mainViewController的代码

class ViewController: NSViewController {

    @IBOutlet weak var platformStackView: NSStackView!

    var platformView1:PlatformView!
    var platformView2:PlatformView!
    var platformView3:PlatformView!

    override func viewDidLoad() {
        super.viewDidLoad()
        //This part is not working in a macOS app
        if let tempView = Bundle.main.loadNibNamed(NSNib.Name(rawValue: "PlatformView"), owner: self, topLevelObjects: nil)?.first as? PlatformView {
            self.platformView1 = tempView
            self.platformView1.currentPriceLabel = "$1.35"
            self.platformStackView.addArrangedSubview(self.platformView1)
            self.platformStackView.addSubview()
            self.platformStackView.addView(tempView, in: self)
            //Which one of these three methods should I use?

        }
    }
}

我在平台视图中有按钮,我想通过IBAction插座连接。我该如何处理?

我还添加了三种方法来添加视图到堆栈视图。哪一个最好用?

它还说.loadNibNamed将返回Bool而不是视图的实例。如何在此View控制器中多次加载视图?我显然还需要在VC的生命周期中进行更改,因此我需要保留该视图的实例。

1 个答案:

答案 0 :(得分:1)

首先你应该使用:

android:showAsAction="always|withText"

因为这会将self.platformView1添加为子视图(根据self.platformStackView.addArrangedSubview(self.platformView1) )并将其添加到堆栈视图排列的视图列表中。

其次,XIB文件可以包含多个顶级对象,因此不能指望它返回单个对象。 Bool返回指示整个XIB文件是否已成功加载,顶级对象的内容将放在topLevelObjects参数中,该参数是一个数组。

所以你做这样的事情:

addSubView

作为替代方案,您也可以这样做:

var topLevelObjects: NSArray?
if Bundle.main.loadNibNamed(NSNib.Name(rawValue: "TestView"), owner: self, topLevelObjects: &topLevelObjects) {
    // Use the objects as you need including searching for a specific one you may require.
}

使用时,结果如下: enter image description here

这是一个从XIB文件加载自定义类并将其添加到当前视图控制器视图三次的工作示例。按钮操作将加载XIB文件实例化它的三个副本,并将它找到的TestView类添加到视图控制器主视图(0,110和220):

if let nib = NSNib(nibNamed: NSNib.Name(rawValue: "TestView"), bundle: nil) {
    if nib.instantiate(withOwner: self, topLevelObjects: &temp) {
        // Use the objects as you need including searching for a specific one you may require.
    }
}

TestView代码如下所示:

@IBAction func buttonAction(_ sender: Any) {
    var objectArray: NSArray?
    if let nib = NSNib(nibNamed: NSNib.Name(rawValue: "TestView"), bundle: nil) {
        if nib.instantiate(withOwner: self, topLevelObjects: &objectArray),
            let topLevelObjects = objectArray {
            for object in topLevelObjects {
                if let testView = object as? TestView {
                    self.view.addSubview(testView)
                    testView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
                    testView.testLabel.stringValue = "Test Label 1"
                }
            }
        }

        if nib.instantiate(withOwner: self, topLevelObjects: &objectArray),
            let topLevelObjects = objectArray {
            for object in topLevelObjects {
                if let testView = object as? TestView {
                    self.view.addSubview(testView)
                    testView.frame = CGRect(x: 110, y: 0, width: 100, height: 100)
                    testView.testLabel.stringValue = "Test Label 2"
                }
            }
        }

        if nib.instantiate(withOwner: self, topLevelObjects: &objectArray),
            let topLevelObjects = objectArray {
            for object in topLevelObjects {
                if let testView = object as? TestView {
                    self.view.addSubview(testView)
                    testView.frame = CGRect(x: 220, y: 0, width: 100, height: 100)
                    testView.testLabel.stringValue = "Test Label 3"
                }
            }
        }
    }
}

该自定义视图没有太复杂。它有一个NSTextField,它都设置正确,所以可以设置它的字符串值。

这一切都适合我,所以应该是要走的路(这是我实际上做的第一个MacOS应用程序,因为我通常是iOS人员。)