我正在使用下面的代碼在超級視圖的邊界內移動視圖,它作業正常,但我想使用自動布局。下面是可移動視圖應該具有的初始約束,當我使用手勢移動它時,我想更新 trailingConstraints 和 bottomConstraints。
寬度 - 超級視圖寬度 / 4 高度 = 寬度的 9/16 trailingConstraints = 0 bottomConstraints = 0
是否可以使用自動布局使用 NSPanGestureRecognizer?
import Cocoa
class ViewController: NSViewController {
var movableView = NSView()
// MARK: - IBOutlet
@IBOutlet weak var panView: NSView!
// MARK: - Life cycle
override func viewDidLoad() {
super.viewDidLoad()
panView.wantsLayer = true
panView.layer?.backgroundColor = NSColor.white.cgColor
movableView.setFrameSize(NSSize(width: 100, height: 100))
movableView.setFrameOrigin(NSPoint(x: self.panView.frame.size.width - movableView.frame.size.width, y: 0))
movableView.wantsLayer = true
if let myLayer1 = movableView.layer {
myLayer1.backgroundColor = NSColor.red.cgColor
}
panView.addSubview(movableView)
let panRecognizer1 = NSPanGestureRecognizer.init(target: self, action: #selector(panPictureView(_:)))
movableView.addGestureRecognizer(panRecognizer1)
}
// MARK: - Pan gesture
@objc func panPictureView(_ sender: NSPanGestureRecognizer) {
if let movingObject = sender.view {
let translation = sender.translation(in: self.panView)
sender.setTranslation(CGPoint.zero, in: self.panView)
let newX = movingObject.frame.origin.x translation.x
let newY = movingObject.frame.origin.y translation.y
let maxX = panView.frame.width - movingObject.frame.width
let maxY = panView.frame.height - movingObject.frame.height
if newX <= 0 && newY <= 0 {
let newPosition = CGPoint(x: 0, y: 0)
movingObject.setFrameOrigin(newPosition)
} else if newX <= 0 {
let newPosition = CGPoint(x: 0, y: newY < maxY ? newY : maxY)
movingObject.setFrameOrigin(newPosition)
} else if newY <= 0 {
let newPosition = CGPoint(x: newX < maxX ? newX : maxX, y: 0)
movingObject.setFrameOrigin(newPosition)
} else if newX >= maxX && newY >= maxY {
let newPosition = CGPoint(x: maxX, y: maxY)
movingObject.setFrameOrigin(newPosition)
} else if newX >= maxX {
let newPosition = CGPoint(x: maxX, y: newY)
movingObject.setFrameOrigin(newPosition)
} else if newY >= maxY {
let newPosition = CGPoint(x: newX, y: maxY)
movingObject.setFrameOrigin(newPosition)
} else {
let newPosition = CGPoint(x: newX, y: newY)
movingObject.setFrameOrigin(newPosition)
}
}
}
}
uj5u.com熱心網友回復:
使用自動布局/約束來做到這一點相當簡單......
我們將為Leading 和Top 約束添加var 屬性:
var leadingC: NSLayoutConstraint!
var topC: NSLayoutConstraint!
在我們的 Pan Gesture 處理程式中,我們將更新這些約束常量:
let translation = sender.translation(in: self.panView)
sender.setTranslation(CGPoint.zero, in: self.panView)
// update movable view Leading and Top constraints
leadingC.constant = translation.x
topC.constant -= translation.y
作為一個額外的好處,我們可以避免所有的 if/else 檢查,方法是為可移動視圖提供必需的約束限制,并賦予“可調整的”Leading 和 Top 約束低于必需的優先級。
這是一個完整的示例實作(假設您@IBOutlet var panView已經設定):
import Cocoa
class ViewController: NSViewController {
@IBOutlet var panView: NSView!
var movableView = NSView()
var leadingC: NSLayoutConstraint!
var topC: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
super.viewDidLoad()
panView.wantsLayer = true
panView.layer?.backgroundColor = NSColor.blue.cgColor
// we don't need these, since we'll be using constraints
//movableView.setFrameSize(NSSize(width: 100, height: 100))
//movableView.setFrameOrigin(NSPoint(x: self.panView.frame.size.width - movableView.frame.size.width, y: 0))
movableView.wantsLayer = true
if let myLayer1 = movableView.layer {
myLayer1.backgroundColor = NSColor.red.cgColor
}
panView.addSubview(movableView)
// let's use constraints
movableView.translatesAutoresizingMaskIntoConstraints = false
// initialize the constraints we'll use to
// move the subview
leadingC = movableView.leadingAnchor.constraint(equalTo: panView.leadingAnchor)
topC = movableView.topAnchor.constraint(equalTo: panView.topAnchor)
// give them less-than-required priority
// we'll use stronger constraints to prevent dragging
// outside the frame of panView
leadingC.priority = .required - 1
topC.priority = .required - 1
NSLayoutConstraint.activate([
// width and height
movableView.widthAnchor.constraint(equalToConstant: 100.0),
movableView.heightAnchor.constraint(equalTo: movableView.widthAnchor),
// these will prevent dragging outside the panView frame
movableView.topAnchor.constraint(greaterThanOrEqualTo: panView.topAnchor),
movableView.leadingAnchor.constraint(greaterThanOrEqualTo: panView.leadingAnchor),
movableView.trailingAnchor.constraint(lessThanOrEqualTo: panView.trailingAnchor),
movableView.bottomAnchor.constraint(lessThanOrEqualTo: panView.bottomAnchor),
])
let panRecognizer1 = NSPanGestureRecognizer.init(target: self, action: #selector(panPictureView(_:)))
movableView.addGestureRecognizer(panRecognizer1)
}
override func viewDidLayout() {
super.viewDidLayout()
// start movable view at bottom-right corner
// need to wait until auto-layout has setup the frames
// and, to make sure this only happens once,
// only execute if our "movable" constraints are not yet activated
if movableView.frame.size.width != 0 && !leadingC.isActive {
leadingC.constant = self.panView.frame.size.width - movableView.frame.size.width
topC.constant = self.panView.frame.size.height - movableView.frame.size.height
leadingC.isActive = true
topC.isActive = true
}
}
// MARK: - Pan gesture
@objc func panPictureView(_ sender: NSPanGestureRecognizer) {
let translation = sender.translation(in: self.panView)
sender.setTranslation(CGPoint.zero, in: self.panView)
// update movable view Leading and Top constraints
leadingC.constant = translation.x
topC.constant -= translation.y
}
override var representedObject: Any? {
didSet {
// Update the view, if already loaded.
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/431805.html
下一篇:將滑鼠保持在Swift中的區域內
