Можно ли изменить порядок просмотров в NSStackView, перетащив подзоны, как мы это делаем в NSTableView?Перетаскивание представлений в NSStackView для изменения последовательности
1
A
ответ
1
Нет встроенной поддержки для переопределения подпрограмм NSStackView.
1
Вот реализация подкласса NSStackView, содержимое которого может быть заказана с помощью перетаскивания:
//
// DraggingStackView.swift
// Analysis
//
// Created by Mark Onyschuk on 2017-02-02.
// Copyright © 2017 Mark Onyschuk. All rights reserved.
//
import Cocoa
class DraggingStackView: NSStackView {
var isEnabled = true
// MARK: -
// MARK: Update Function
var update: (NSStackView, Array<NSView>)->Void = { stack, views in
stack.views.forEach {
stack.removeView($0)
}
views.forEach {
stack.addView($0, in: .leading)
switch stack.orientation {
case .horizontal:
$0.topAnchor.constraint(equalTo: stack.topAnchor).isActive = true
$0.bottomAnchor.constraint(equalTo: stack.bottomAnchor).isActive = true
case .vertical:
$0.leadingAnchor.constraint(equalTo: stack.leadingAnchor).isActive = true
$0.trailingAnchor.constraint(equalTo: stack.trailingAnchor).isActive = true
}
}
}
// MARK: -
// MARK: Event Handling
override func mouseDragged(with event: NSEvent) {
if isEnabled {
let location = convert(event.locationInWindow, from: nil)
if let dragged = views.first(where: { $0.hitTest(location) != nil }) {
reorder(view: dragged, event: event)
}
} else {
super.mouseDragged(with: event)
}
}
private func reorder(view: NSView, event: NSEvent) {
guard let layer = self.layer else { return }
guard let cached = try? self.cacheViews() else { return }
let container = CALayer()
container.frame = layer.bounds
container.zPosition = 1
container.backgroundColor = NSColor.underPageBackgroundColor.cgColor
cached
.filter { $0.view !== view }
.forEach { container.addSublayer($0) }
layer.addSublayer(container)
defer { container.removeFromSuperlayer() }
let dragged = cached.first(where: { $0.view === view })!
dragged.zPosition = 2
layer.addSublayer(dragged)
defer { dragged.removeFromSuperlayer() }
let d0 = view.frame.origin
let p0 = convert(event.locationInWindow, from: nil)
window!.trackEvents(matching: [.leftMouseDragged, .leftMouseUp], timeout: 1e6, mode: .eventTrackingRunLoopMode) { event, stop in
if event.type == .leftMouseDragged {
let p1 = self.convert(event.locationInWindow, from: nil)
let dx = (self.orientation == .horizontal) ? p1.x - p0.x : 0
let dy = (self.orientation == .vertical) ? p1.y - p0.y : 0
CATransaction.begin()
CATransaction.setDisableActions(true)
dragged.frame.origin.x = d0.x + dx
dragged.frame.origin.y = d0.y + dy
CATransaction.commit()
let reordered = self.views.map {
(view: $0,
position: $0 !== view
? NSPoint(x: $0.frame.midX, y: $0.frame.midY)
: NSPoint(x: dragged.frame.midX, y: dragged.frame.midY))
}
.sorted {
switch self.orientation {
case .vertical: return $0.position.y < $1.position.y
case .horizontal: return $0.position.x < $1.position.x
}
}
.map { $0.view }
let nextIndex = reordered.index(of: view)!
let prevIndex = self.views.index(of: view)!
if nextIndex != prevIndex {
self.update(self, reordered)
self.layoutSubtreeIfNeeded()
CATransaction.begin()
CATransaction.setAnimationDuration(0.15)
CATransaction.setAnimationTimingFunction(CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut))
for layer in cached {
layer.position = NSPoint(x: layer.view.frame.midX, y: layer.view.frame.midY)
}
CATransaction.commit()
}
} else {
view.mouseUp(with: event)
stop.pointee = true
}
}
}
// MARK: -
// MARK: View Caching
private class CachedViewLayer: CALayer {
let view: NSView!
enum CacheError: Error {
case bitmapCreationFailed
}
override init(layer: Any) {
self.view = (layer as! CachedViewLayer).view
super.init(layer: layer)
}
init(view: NSView) throws {
self.view = view
super.init()
guard let bitmap = view.bitmapImageRepForCachingDisplay(in: view.bounds) else { throw CacheError.bitmapCreationFailed }
view.cacheDisplay(in: view.bounds, to: bitmap)
frame = view.frame
contents = bitmap.cgImage
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
private func cacheViews() throws -> [CachedViewLayer] {
return try views.map { try cacheView(view: $0) }
}
private func cacheView(view: NSView) throws -> CachedViewLayer {
return try CachedViewLayer(view: view)
}
}
код требует вашего стека, чтобы быть слой поддерживается, и использует подслоя для моделирования и анимации свои взгляды контента во время обработки перетаскивания. Перетаскивание определяется переопределением mouseDragged (с :), поэтому не будет инициировано, если содержимое стека потребляет это событие.
Смежные вопросы
- 1. Перетаскивание представлений в android
- 2. Перетаскивание представлений с использованием UIAttachmentBehavior
- 3. Перетаскивание JavaFX для изменения узлов
- 4. Перетаскивание точек для изменения фигур
- 5. HTML5 перетаскивание для изменения виджетов в сетке?
- 6. NSScrollView, содержащий NSStackView. Почему элементы NSStackView снизу вверх?
- 7. Несколько экземпляров единого представления содержимого в NSStackView
- 8. Скрытый вид в NSStackView не скрывается?
- 9. NSStackView неправильно отображает макеты
- 10. Перетаскивание украшений для изменения размера многоугольника
- 11. стиль для функции изменения OpenLayers (перетаскивание)
- 12. Создание делегата для изменения представлений из меню
- 13. данные изменения Python в последовательности
- 14. Lua: «перетаскивание» последовательности элементов внутри массива
- 15. Перетаскивание представлений в сцену в док-станции в построителе интерфейсов
- 16. HTML5 Перетаскивание без изменения разметки
- 17. NSStackView имеет неправильный интервал просмотра
- 18. NSStackView и subviews с внутренним размером содержимого
- 19. Последовательный номер последовательности изменения Quickfix
- 20. Определить силу и место изменения в последовательности
- 21. Сценарий для изменения записей последовательности действий в MSI
- 22. Основное перетаскивание в iOS
- 23. Перетаскивание заголовка заголовка таблицы изменения цвета
- 24. Можно ли использовать powershell для изменения представлений файлового обозревателя?
- 25. TableView для изменения с помощью UIButton на другом диспетчере представлений
- 26. Как реализовать перетаскивание для изменения порядка относительных позиционированных элементов?
- 27. macOS Содержимое NSStackView не заполняет доступное пространство
- 28. Динамический NSStackView, который изменяет размер для его содержимого
- 29. Scala последовательности в последовательности последовательности
- 30. Перетаскивание ячеек с формулами сохраняя ту же логику последовательности