以编程方式添加约束会导致意外行为

时间:2019-04-04 15:14:16

标签: swift macos nsview

我正在处理约束,试图了解它们的工作原理,并尝试学习如何在没有IB的情况下构建UI,但我没有得到预期的结果。在下面的代码中,如果我在最后注释掉约束,则可以看到紫色视图。如果我取消注释,那么我得到的只是一个空窗口,我希望该视图固定在主视图的左侧,顶部右边缘。

我还尝试过使用centerX和centerY属性进行类似操作,以将视图居中放置在窗口中间,再次激活它们时,我会得到一个空窗口。

任何帮助表示赞赏!

import Cocoa

class ViewController : NSViewController {

override func loadView() {

    // NSMakeRect parameters do nothing?
    let view = NSView(frame: NSMakeRect(0,0,400,2000))
    view.wantsLayer = true
    view.layer?.borderWidth = 5
    view.layer?.borderColor = NSColor.gray.cgColor
    self.view = view
}

override func viewWillAppear() {

    super.viewWillAppear()

    // Do any additional setup after loading the view.
    createMasterView()
}



func makeView() -> NSView {
    let view = NSView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.setFrameSize(NSSize(width: 600, height: 100))
    view.wantsLayer = true
    view.heightAnchor.constraint(equalToConstant: 1000)
    return view
}

func createMasterView() {

    let mainView = self.view
    let headerView = makeView()

    headerView.layer?.backgroundColor = NSColor.purple.cgColor
    headerView.layer?.borderWidth = 5
    headerView.layer?.borderColor = CGColor.black

    mainView.translatesAutoresizingMaskIntoConstraints = false
    mainView.addSubview(headerView)

    headerView.topAnchor.constraint(equalTo: mainView.topAnchor).isActive = true
    headerView.leadingAnchor.constraint(equalTo: mainView.leadingAnchor).isActive = true
    headerView.trailingAnchor.constraint(equalTo: mainView.trailingAnchor).isActive = true
}  
}

编辑:我还在下面包括我的AppDelegate代码。我对这一切仍然很陌生,因此代码是我从各种教程中拼凑而成的东西。

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate {

var windowController: NSWindowController!
var window: NSWindow!
var windowTitle = "Test App"
var customBGColor = NSColor(red: 1, green: 1, blue: 1, alpha: 1)

func applicationDidFinishLaunching(_ aNotification: Notification) {

    createMainWindow()
}  

func createMainWindow() {
    window = NSWindow()
    // window.alphaValue = 0.5
    window.backgroundColor = customBGColor
    window.title = windowTitle
    window.styleMask = NSWindow.StyleMask(rawValue: 0xf)
    window.backingType = .buffered
    window.contentViewController = ViewController()
    window.setFrame(NSRect(x: 700, y: 200, width: 1920, height: 1080), display: false)
    windowController = NSWindowController()
    windowController.contentViewController = window.contentViewController
    windowController.window = window
    windowController.showWindow(self)
}

func applicationWillTerminate(_ aNotification: Notification) {
    // Insert code here to tear down your application
}
}

2 个答案:

答案 0 :(得分:0)

view.setFrameSize(NSSize(width:600,height:100))

之后不久,您将使用heightAnchor覆盖高度。 尝试使用锚点设置宽度

答案 1 :(得分:0)

使用自动布局时,您无需触摸视图的frame属性。但是,当以编程方式进行工作时,必须使用视图本身,但是之后,可以使用约束来调整所有子视图的大小和位置。为了清楚起见,我摆脱了makeView()

func createMasterView() {

    let headerView = NSView() // instantiate
    headerView.layer?.backgroundColor = NSColor.purple.cgColor // style
    headerView.layer?.borderWidth = 5
    headerView.layer?.borderColor = CGColor.black
    headerView.translatesAutoresizingMaskIntoConstraints = false // disable mask translating
    view.addSubview(headerView) // add as a subview

    // then configure constraints

    // one possible setup
    headerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    headerView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    headerView.heightAnchor.constraint(equalToConstant: 100).isActive = true

    // another possible setup
    headerView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    headerView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    headerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    headerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5).isActive = true

    // another possible setup
    headerView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    headerView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    headerView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -50).isActive = true
    headerView.heightAnchor.constraint(equalTo: view.heightAnchor, constant: -50).isActive = true

}
相关问题