2017-05-10 6 views
11

NSTextField私はNSTextFieldを持っています。内容が変わるたびに自動的に一定の基準でサイズを変更しようとしています。時にはNSTextFieldで奇妙なスクロール

、以下のGIFに示すように、テキストフィールドの可視部分(または下)までの移動を開始、コンテンツの入力を開始します:

gif

私はNSTextFieldの内側をクリックした場合、コンテンツ再び正しい位置に表示されます。 _NSKeyboardFocusClipViewそのY座標、負の数を持っていframeを持っている:私はこのケースが発生したとき、NSTextFieldのプライベートサブビューがいるのを見ましたXcodeで視覚的なデバッガを焼成

何が原因なのかわかりません。ここで

は私のテキストフィールドは、行動のサイズを変更します

extension CanvasViewController: NSTextFieldDelegate { 
    override func controlTextDidChange(_ obj: Notification) { 
    if let textField = obj.object as? NSTextField { 
     textFieldResizingBehavior.resize(textField) 
    } 
    } 

そして最後に、私のテキストフィールドは次のようにのViewControllerの中で宣言されています:

lazy var textField: NSTextField = { 
    let textField = NSTextField() 
    textField.isHidden = true 
    textField.isEditable = false 
    textField.allowsEditingTextAttributes = true 
    return textField 
    }() 
NSTextFieldDelegate方法で呼び出され

import Cocoa 

struct TextFieldResizingBehavior { 
    let maxHeight: CGFloat = 100000.0 
    let maxWidthPadding: CGFloat = 10 
    let minWidth: CGFloat = 50 
    let maxWidth: CGFloat = 250 

    func resize(_ textField: NSTextField) { 
    let originalFrame = textField.frame 

    var textMaxWidth = textField.attributedStringValue.size().width 
    textMaxWidth = textMaxWidth > maxWidth ? maxWidth : textMaxWidth 
    textMaxWidth += maxWidthPadding 

    var constraintBounds: NSRect = textField.frame 
    constraintBounds.size.width = textMaxWidth 
    constraintBounds.size.height = maxHeight 

    var naturalSize = textField.cell!.cellSize(forBounds: constraintBounds) 

    // ensure minimun size of text field 
    naturalSize.width = naturalSize.width < minWidth ? minWidth : naturalSize.width 

    if originalFrame.height != naturalSize.height { 
     // correct the origin in order the textField to grow down. 
     let yOffset: CGFloat = naturalSize.height - originalFrame.height 
     let newOrigin = NSPoint(
     x: originalFrame.origin.x, 
     y: originalFrame.origin.y - yOffset 
    ) 
     textField.setFrameOrigin(newOrigin) 
    } 

    textField.setFrameSize(naturalSize) 

    Swift.print(
     "\n\n>>>>>> text field resized " + 
     "\nnaturalSize=\(naturalSize)" + 
     "\noriginalFrame=\(originalFrame)-\(originalFrame.center)" + 
     "\nnewFrame=\(textField.frame)-\(textField.frame.center)" 
    ) 
    } 
} 

フルコード:https://github.com/fespinoza/linked-ideas-osx

+0

このコードはプロジェクトにありません。私はそれが何かと関係があるかどうかわかりませんが、 'becomeFirstResponder'を呼び出さないでください。ドキュメントには、「このメソッドではなくNSWindow makeFirstResponder(_ :)メソッドを使用して、オブジェクトを最初のレスポンダにします。このメソッドを直接呼び出さないでください。 – Willeke

+0

コードはPRのあるブランチにあります。 – fespinozacast

+0

本当に両方向に成長する必要があるのですが、私はあなたが何を言っているか確認しますか?高さを調整するだけで解決したら簡単だと思います。 – catlan

答えて

1

問題の1つは、becomeFirstResponderメソッドを直接呼び出すことです。あなたはこれをしてはいけません。 documentationによれば

に、NSWindowのmakeFirstResponder(_ :)方法ではなく、この方法を使用して、オブジェクト最初の応答します。このメソッドを直接呼び出さないでください。

また、テキストフィールドは、水平方向と垂直方向の両方に成長する必要がありますか?高さだけに基づいて動的にすることは明らかにはるかに単純です。