簡體   English   中英

從 XIB OS X App 添加(addsubview)自定義/可重用視圖

[英]Add (addsubview) custom/reusable view from XIB OS X App

這是我的自定義視圖的代碼。 我還有一個自定義的 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 而不是視圖的實例。 如何在此視圖控制器中多次加載視圖? 我顯然還需要在 VC 的整個生命周期中進行更改,因此我需要保留該視圖的實例。

首先你應該使用:

self.platformStackView.addArrangedSubview(self.platformView1)

因為這會將 self.platformView1 添加為子視圖(根據addSubView )並將其添加到堆棧視圖排列的視圖列表中。

其次,XIB 文件可以包含多個頂級對象,因此不能期望它返回單個對象。 Bool 返回指示 XIB 文件作為一個整體是否已成功加載,並且頂級對象的內容將放在 topLevelObjects 參數中,該參數是一個數組。

所以你做這樣的事情:

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.
}

作為替代方案,您也可以這樣做:

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.
    }
}

使用時結果如下: 在此處輸入圖片說明

這是從 XIB 文件加載自定義類並將其添加到當前視圖控制器視圖三次的工作示例。 按鈕操作將加載 XIB 文件實例化它的三個副本並將它找到的 TestView 類添加到視圖控制器主視圖(在 0、110 和 220):

@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"
                }
            }
        }
    }
}

TestView 代碼如下所示:

class TestView: NSView {
    @IBOutlet var testLabel: NSTextField!

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        self.testLabel.stringValue = "Init"
    }

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)

        // Drawing code here.
    }
}

該自定義視圖沒有什么太復雜的。 它有一個單獨的 NSTextField,所有設置都正確,因此可以只設置它的字符串值。

這一切都對我有用,所以應該是要走的路(這是我實際完成的第一個 MacOS 應用程序,因為我通常是一個 iOS 人)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM