我無法弄清楚如何完成看似非常簡單的任務。我有一個 macOS cocoa 應用程式,它由一個視窗組成,里面有一個自定義視圖。視圖為 600x500 點。在這個視圖里面是一個子視圖,它跨越了主視圖的整個寬度,但只是視圖高度的一小部分。它的垂直原點大約在 y=200。
子視圖繪制一個矩形,從左右邊界 20 點開始,大約 30 點的高度。它還使用它的層和一個 CAEmitter 層作為子層。這個發射器的位置可以由用戶控制,所以它的位置會被一個從視圖外部呼叫的函式更新。
我想要的是:
當用戶調整視窗大小時,它應該只按比例縮放(我設法做到了),以便整個視窗的內容被調整大小。子視圖不應該以任何方式重新排列,它們都應該保持它們的大小和相對位置,只是變大/變小。
我沒有得到這個作業。
到目前為止我嘗試過的:
- 沒有設定額外的屬性,我可以調整視窗的大小,但 subiew 根本不縮放,它堅持在超級視圖中的位置。
- 我設定
subView.leadingAnchor.constraint(greaterThanOrEqualTo: view.leadingAnchor).isActive = true和尾隨Anchor相同,另外我設定subView.autoresizingMask = [.width]現在在子視圖中繪制的矩形的寬度被調整大小,但矩形的邊緣遠離邊框20點。我希望這個距離也被縮放。 - 矩形的高度保持固定。當我添加
-heigth到子視圖的自動調整大小蒙版時,高度會以一種非常不成比例的方式扭曲(到頂部和底部邊距的距離保持不變,因此盡管子視圖的高度在開始時只有 30 左右,但 rect 在調整大小時會被放大。 - 發射器不會重新定位。它的水平位置是根據用戶互動計算的,并且是相對于視圖邊框的,在調整大小后,它會堅持其絕對位置。我通過從 draw() 方法呼叫計算函式解決了這個問題,但這對我來說似乎不對
cocoa 框架中有很多關于大小、錨點、約束等的入口點,我根本不知道從哪里開始,所以任何幫助將不勝感激。
更新:我添加了精簡到最小值的代碼:
class MyViewController: NSViewController {
public init () {
super.init(nibName: nil, bundle: nil)
self.view = MyView(frame: NSRect(x: 0, y: 0, width: 600, height: 500))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MyView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
let subView = MySubView(frame: NSRect(x: 0, y: frame.height/3, width: frame.width, height: frame.height/10))
self.addSubview(subView)
subView.autoresizingMask = [.width, .height]
subView.translatesAutoresizingMaskIntoConstraints = true
subView.trailingAnchor.constraint(greaterThanOrEqualTo: self.trailingAnchor).isActive = true
subView.leadingAnchor.constraint(greaterThanOrEqualTo: self.leadingAnchor).isActive = true
}
required init?(coder decoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class MySubView: NSView {
override func draw(_ dirtyRect: NSRect) {
let context = NSGraphicsContext.current!.cgContext
context.setStrokeColor(.black)
context.setFillColor(CGColor.init(red: 0.7, green: 0.7, blue: 0.7, alpha: 1))
context.setLineWidth(2)
let borderRect = CGRect(x: constant.sideMargin, y: 5, width: frame.width-2*constant.sideMargin, height: frame.height-10)
let roundedRect = CGPath.init(roundedRect: borderRect, cornerWidth: 5, cornerHeight: 5, transform: nil)
context.addPath(roundedRect)
context.fillPath()
context.strokePath()
context.addPath(roundedRect)
context.strokePath()
}
}
uj5u.com熱心網友回復:
正如View Programming Guide 中所解釋的,NSView如果它的內容與其bounds不同,將縮放和偏移它的內容frame。只需設定bounds為何{600, 500}時frame更改。視圖的子視圖不需要約束,因為它們的坐標不會改變。
MyView 設定代碼:
// frame changed notitication
self.postsFrameChangedNotifications = true
self.frameChangeObserver = NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification,
object: self, queue: OperationQueue.main) { (note) in
self.setBoundsSize(NSSize(width:600, height: 500))
}
let subView = MySubView(frame: NSRect(x: 0, y: bounds.height/3, width: bounds.width, height: bounds.height/10))
// no constraints
subView.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(subView)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/366840.html
下一篇:如何將一個陣列推入另一個陣列?
