You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MacOS Swift应用点击添加标签功能代码编译通过但崩溃求助

Fixing Crash in macOS Swift App When Adding Text Fields on Mouse Click

Hey Marco, let's dig into why your code is crashing and fix it step by step. I spotted a few key issues that are causing the crash and preventing your text fields from showing up properly:


1. Undefined location Variable

Your code references self.location but never actually retrieves the mouse click position from the NSEvent. This is definitely causing a crash because the variable doesn't exist. Instead, you need to get the click location directly from the event passed to the monitor closure.

2. Misused @IBOutlet for the Text Field Array

@IBOutlet is meant for connecting UI elements from Storyboard/XIB files to your code. Since you're creating text fields programmatically, you don't need this annotation—just declare a regular array to hold your text fields. Using @IBOutlet here can lead to unexpected memory or initialization issues.

3. Forgetting to Add Text Fields to the View

Even if you create the NSTextField instances, they won't appear (and might cause memory-related crashes) unless you add them as subviews to your window's content view.

4. Redundant count Variable

You're manually tracking a count variable, but you can just use here2.count directly—this avoids synchronization issues where count might not match the actual array size.


Fixed Code

Here's the revised, crash-free version of your code with explanations in comments:

// Remove @IBOutlet since we're creating text fields programmatically
var here2 = [NSTextField]()

override func viewDidLoad() {
    super.viewDidLoad()
    // Set up the mouse event monitor in a proper lifecycle method
    setupMouseClickMonitor()
}

func setupMouseClickMonitor() {
    NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown) { [weak self] event in
        guard let self = self else { return event }
        
        // Get the click position relative to the window's content view
        let clickLocation = event.locationInWindow
        // Convert to the view's coordinate system for accurate positioning
        let viewLocation = self.view.convert(clickLocation, from: nil)
        
        // Check if the click is within your desired bounds
        if viewLocation.x < 700 && viewLocation.y < 750 {
            // Create a new text field
            let newTextField = NSTextField()
            // Set position and size (adjust size as needed)
            newTextField.frame = CGRect(origin: viewLocation, size: CGSize(width: 80, height: 24))
            // Set text to the current array count (no need for a separate variable)
            newTextField.stringValue = String(self.here2.count)
            // Make the text field visible (default style is hard to see)
            newTextField.borderStyle = .lineBorder
            newTextField.drawsBackground = true
            newTextField.backgroundColor = .white
            
            // Add the text field to the view so it renders on screen
            self.view.addSubview(newTextField)
            // Store it in the array for future reference
            self.here2.append(newTextField)
            
            print("count is: \(self.here2.count)")
        }
        return event
    }
}

Key Fixes Explained:

  • [weak self] in the closure: Prevents retain cycles that could cause memory leaks or crashes over time.
  • Proper location retrieval: Uses event.locationInWindow and converts it to the view's coordinate system for accurate positioning.
  • Added view insertion: self.view.addSubview(newTextField) ensures the text field is rendered on screen.
  • Removed redundant count variable: Uses here2.count directly to keep track of the number of text fields.
  • Visible text field setup: Added border and background so you can actually see the text field when it's created.

内容的提问来源于stack exchange,提问作者marco

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 19:02:50