Как расположить NSView ниже другого NSView?

#swift #nsview

#swift #nsview

Вопрос:

Добрый день,

У кого есть идея о том, как расположить NSButton ниже другого представления в его супервизоре?

Вот код, который я написал, но положение кнопки NSButton не меняется независимо от того, где находится NSView. Я был бы признателен, если бы кто-нибудь мог разобраться в этом и помочь мне решить эту проблему.

  @objc func printHello() {
        var theButton = NSButton(frame: NSRect(x: 0, y: 0, width: 168, height: 32))
        theButton.bezelStyle = .rounded
        theButton.controlSize = .large
        theButton.keyEquivalent = "r"
        theButton.title = "Edit Chart Data"
        self.superview?.addSubview(theButton, positioned: .below, relativeTo: self)
        print(self.frame)
        
 

Ответ №1:

Метод addSubview(theButton, positioned: .below, relativeTo: self) не определяет положение элемента в кадре. Часть «positioned: .below» на самом деле предназначена для координаты Z.

Итак, что вы сделали, так это сказали представлению добавить подраздел ниже «self» в своей иерархии. Это означает, что если кадры self и кнопка будут перекрываться, то self они будут находиться перед кнопкой. Использование .above поместило бы кнопку впереди.

Вы можете использовать свойство frame для достижения своей цели или ограничений. С frame это должно быть что-то вроде

 func placeView(_ targetView: NSView, belowView currentView: NSView) {
    targetView.frame = NSRect(x: currentView.frame.minX,
                              y: currentView.frame.minY-currentView.frame.height,
                              width: currentView.frame.width,
                              height: currentView.frame.height)
}
 

Используя его как:

 self.superview?.addSubview({
    let theButton = NSButton(frame: .zero)
    placeView(theButton, belowView: self)
    theButton.bezelStyle = .rounded
    theButton.controlSize = .large
    theButton.keyEquivalent = "r"
    theButton.title = "New view"
    return theButton
}())
 

При использовании ограничений может быть сделано что-то подобное:

 func placeView(_ targetView: NSView, belowView currentView: NSView) {
    let view = targetView.superview!
    view.addConstraint(NSLayoutConstraint(item: currentView, attribute: .leading, relatedBy: .equal, toItem: targetView, attribute: .leading, multiplier: 1.0, constant: 0.0))
    view.addConstraint(NSLayoutConstraint(item: currentView, attribute: .trailing, relatedBy: .equal, toItem: targetView, attribute: .trailing, multiplier: 1.0, constant: 0.0))
    view.addConstraint(NSLayoutConstraint(item: currentView, attribute: .top, relatedBy: .equal, toItem: targetView, attribute: .bottom, multiplier: 1.0, constant: 0.0))
    view.addConstraint(NSLayoutConstraint(item: currentView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: currentView.frame.height))
}
 

И использовать его как:

 let theButton: NSButton = {
    let theButton = NSButton(frame: NSRect(x: 0, y: 0, width: 0, height: 90.0))
    theButton.translatesAutoresizingMaskIntoConstraints = false
    theButton.bezelStyle = .rounded
    theButton.controlSize = .large
    theButton.keyEquivalent = "r"
    theButton.title = "New view"
    return theButton
}()
self.view.addSubview(theButton)
placeView(theButton, belowView: someView)
self.view.layoutSubtreeIfNeeded()
 

Комментарии:

1. Спасибо, но он добавляет его поверх представления, а не ниже

2. @Matthew1998 какой из двух методов вы использовали? В любом случае должно быть очень интуитивно понятно, как это исправить…

3. первый брат, тот, который без ограничений