標準ビューから構築されたカスタムビューに関するターゲットアクションの問題

クリス

カスタムビューのサブクラスNSViewがありNSStackViewます。これには、ラベル、スライダー、2番目のラベル、およびチェックボックスが含まれています。スライダーとチェックボックスは両方とも、ビューへの変更を報告するように構成されています(最終的には、ViewControllerへのデリゲートを介して)。

fileprivate extension NSTextField {
    static func label(text: String? = nil) -> NSTextField {
        let label = NSTextField()
        label.isEditable = false
        label.isSelectable = false
        label.isBezeled = false
        label.drawsBackground = false
        label.stringValue = text ?? ""
        return label
    }
}

@IBDesignable
class Adjustable: NSView {

    private let sliderLabel = NSTextField.label()
    private let slider = NSSlider(target: self, action: #selector(sliderChanged(_:)))
    private let valueLabel = NSTextField.label()
    private let enabledCheckbox = NSButton(checkboxWithTitle: "Enabled", target: self, action: #selector(enabledChanged(_:)))

    var valueFormatter: (Double)->(String) = { String(format:"%5.2f", $0) }

    ...

    @objc func sliderChanged(_ sender: Any) {
        guard let slider = sender as? NSSlider else { return }

        valueLabel.stringValue = valueFormatter(slider.doubleValue)
        print("Slider now: \(slider.doubleValue)")

        delegate?.adjustable(self, changedValue: slider.doubleValue)
    }

    @objc func enabledChanged(_ sender: Any) {
        guard let checkbox = sender as? NSButton else { return }
        print("Enabled now: \(checkbox.state == .on)")

        delegate?.adjustable(self, changedEnabled: checkbox.state == .on)
    }
}

InterfaceBuilderを使用して、をドラッグCustomViewし、Identity Inspectorでそのクラスを設定することにより、このインスタンスをViewControllerに1つ追加できますチェックボックスを切り替えるか、スライダーを変更すると、目的の効果が得られます。

ただし、複数のインスタンスがある場合、target-action関数でself、操作対象のインスタンスではなく、常にビューの同じインスタンスを参照します。つまり、スライダーの1つにself.slider == senderのみ当てはまりますsliderChangedを介して正しいスライダー値を取得senderできself.valueLabelますが、カスタムビューの最初のインスタンスのラベルと異なり、正しいラベルを更新できません

ちなみに、@IBDesignableそれをサポートすることを目的としたコードは効果がないので、そこにも欠けているものがあります-InterfaceBuilderは空のスペースを表示するだけです。

ファイル全体:

import Cocoa

fileprivate extension NSTextField {
    static func label(text: String? = nil) -> NSTextField {
        let label = NSTextField()
        label.isEditable = false
        label.isSelectable = false
        label.isBezeled = false
        label.drawsBackground = false
        label.stringValue = text ?? ""
        return label
    }
}

protocol AdjustableDelegate {
    func adjustable(_ adjustable: Adjustable, changedEnabled: Bool)
    func adjustable(_ adjustable: Adjustable, changedValue: Double)
}

@IBDesignable
class Adjustable: NSView {
    var delegate: AdjustableDelegate? = nil

    private let sliderLabel = NSTextField.label()
    private let slider = NSSlider(target: self, action: #selector(sliderChanged(_:)))
    private let valueLabel = NSTextField.label()
    private let enabledCheckbox = NSButton(checkboxWithTitle: "Enabled", target: self, action: #selector(enabledChanged(_:)))

    var valueFormatter: (Double)->(String) = { String(format:"%5.2f", $0) }

    @IBInspectable
    var label: String = "" {
        didSet {
            sliderLabel.stringValue = label
        }
    }

    @IBInspectable
    var value: Double = 0 {
        didSet {
            slider.doubleValue = value
            valueLabel.stringValue = valueFormatter(value)
        }
    }

    @IBInspectable
    var enabled: Bool = false {
        didSet {
            enabledCheckbox.isEnabled = enabled
        }
    }

    @IBInspectable
    var minimum: Double = 0 {
        didSet {
            slider.minValue = minimum
        }
    }

    @IBInspectable
    var maximum: Double = 100 {
        didSet {
            slider.maxValue = maximum
        }
    }

    @IBInspectable
    var tickMarks: Int = 0


    override init(frame: CGRect) {
        super.init(frame: frame)
        setup()
    }

    required init?(coder decoder: NSCoder) {
        super.init(coder: decoder)
        setup()
    }

    override func prepareForInterfaceBuilder() {
        setup()
    }

    override func awakeFromNib() {
        setup()
    }

    private func setup() {
        let stack = NSStackView()
        stack.orientation = .horizontal
        stack.translatesAutoresizingMaskIntoConstraints = false

        stack.addArrangedSubview(sliderLabel)
        stack.addArrangedSubview(slider)
        stack.addArrangedSubview(valueLabel)
        stack.addArrangedSubview(enabledCheckbox)

        sliderLabel.stringValue = label
        slider.doubleValue = value
        valueLabel.stringValue = valueFormatter(value)
        slider.minValue = minimum
        slider.maxValue = maximum
        slider.numberOfTickMarks = tickMarks

        // Make the slider be the one that expands to fill available space
        slider.setContentHuggingPriority(NSLayoutConstraint.Priority(rawValue: 249), for: .horizontal)

        sliderLabel.widthAnchor.constraint(equalToConstant: 60).isActive = true
        valueLabel.widthAnchor.constraint(equalToConstant: 60).isActive = true

        addSubview(stack)

        stack.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        stack.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        stack.topAnchor.constraint(equalTo: topAnchor).isActive = true
        stack.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }

    @objc func sliderChanged(_ sender: Any) {
        guard let slider = sender as? NSSlider else { return }

        valueLabel.stringValue = valueFormatter(slider.doubleValue)
        print("Slider now: \(slider.doubleValue)")

        delegate?.adjustable(self, changedValue: slider.doubleValue)
    }

    @objc func enabledChanged(_ sender: Any) {
        guard let checkbox = sender as? NSButton else { return }
        print("Enabled now: \(checkbox.state == .on)")

        delegate?.adjustable(self, changedEnabled: checkbox.state == .on)
    }
}
クリス

Willekeによってリンクされた質問で説明されているように、解決策は、init参照する前に完了したことを確認することでしたself(コンパイラーがプロパティイニシャライザーでの使用を許可したことに少し驚いています)

違う:

private let slider = NSSlider(target: self, action: #selector(sliderChanged(_:)))
private let enabledCheckbox = NSButton(checkboxWithTitle: "Enabled", target: self, action: #selector(enabledChanged(_:)))

正しい:

private lazy var slider = NSSlider(target: self, action: #selector(sliderChanged(_:)))
private lazy var enabledCheckbox = NSButton(checkboxWithTitle: "Enabled", target: self, action: #selector(enabledChanged(_:)))

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Androidのアクションバーのカスタムビューに関する問題

分類Dev

カスタムUITableViewCellの問題:ビューからスクロールアウトするとUITextFieldsがクリアされる-デキューの問題

分類Dev

Railsのactiveadminは、カスタムアクションからカスタマイズされたビューページにリダイレクトします

分類Dev

かみそりビューでカスタムナビゲーションを構築する

分類Dev

リストビューとカスタムアダプタのスクロールに関する問題

分類Dev

TeamFoundationビルドサービスイベントのカスタムビューに関する問題

分類Dev

コンテナビュー内のビューからナビゲーションスタックにビューをプッシュしますか?

分類Dev

ナビゲーションビューAndroidのヘッダービューの下にあるカスタムビューを膨らませる

分類Dev

カスタムアニメーションを実装して、iPadの指定されたビューからモーダルビューを表示します

分類Dev

ナビゲーションに関するカスタムJQuerycss背景スライダーの問題

分類Dev

複数のターゲットフレームワークのソリューションを構築するにはどうすればよいですか?

分類Dev

ナビゲーションビューのカスタムテーマのツールバー作成の問題?

分類Dev

ブートストラップのドキュメントからこのカスタムオフキャンバスナビゲーションを外側でクリックして閉じるにはどうすればよいですか?

分類Dev

カスタムreactナビゲーションヘッダーコンポーネントから親の状態値にアクセスする方法

分類Dev

jQueryは、セクションがブラウザビューに表示された場合にのみ、ターゲット数にカウントされます

分類Dev

iOS11でのナビゲーションバーのカスタム画像ビューの問題

分類Dev

デフォルトのナビゲーションタブビューをカスタマイズされたタブビューに変更するにはどうすればよいですか?

分類Dev

ハッキングに依存しない依存関係のカスタムバージョンを使用してサンドボックス化されたcabalプロジェクトを構築する方法(例:githubからのチェックアウト)

分類Dev

Railsボタンをクリックすると、ビューからカスタムコントローラーアクションを呼び出します

分類Dev

ネストされたナビゲーション+ IntersectionObserverのcreateRefに関する問題に対応する

分類Dev

ビューコントローラーがナビゲーションスタックにプッシュされる前に呼び出される viewDidAppear()

分類Dev

ネストされたナビゲーターから親のナビゲーションヘッダーを非表示にする

分類Dev

カスタマイズされたLinuxディストリビューションを作成するためのアドバイスが必要です(最初からまたは既存のディストリビューションから?)

分類Dev

マスターページのナビゲーションメニューからWebフォームにアクセスする

分類Dev

次のアサーションは、ナビゲーターを構築するためにスローされました

分類Dev

カードがナビゲーションスタックにプッシュされないのはなぜですか?制限はありますか?

分類Dev

ナビゲーションボタンの問題で提示されたモーダルビュー

分類Dev

カスタムクエリでフェッチされたwordpressのpost_contentからすべてのビジュアルコンポーザーショートコード/タグを取り除く方法

分類Dev

ボタンアクション(パラメーター付き)を使用してカスタムUITableViewCellからビューをプッシュする方法

Related 関連記事

  1. 1

    Androidのアクションバーのカスタムビューに関する問題

  2. 2

    カスタムUITableViewCellの問題:ビューからスクロールアウトするとUITextFieldsがクリアされる-デキューの問題

  3. 3

    Railsのactiveadminは、カスタムアクションからカスタマイズされたビューページにリダイレクトします

  4. 4

    かみそりビューでカスタムナビゲーションを構築する

  5. 5

    リストビューとカスタムアダプタのスクロールに関する問題

  6. 6

    TeamFoundationビルドサービスイベントのカスタムビューに関する問題

  7. 7

    コンテナビュー内のビューからナビゲーションスタックにビューをプッシュしますか?

  8. 8

    ナビゲーションビューAndroidのヘッダービューの下にあるカスタムビューを膨らませる

  9. 9

    カスタムアニメーションを実装して、iPadの指定されたビューからモーダルビューを表示します

  10. 10

    ナビゲーションに関するカスタムJQuerycss背景スライダーの問題

  11. 11

    複数のターゲットフレームワークのソリューションを構築するにはどうすればよいですか?

  12. 12

    ナビゲーションビューのカスタムテーマのツールバー作成の問題?

  13. 13

    ブートストラップのドキュメントからこのカスタムオフキャンバスナビゲーションを外側でクリックして閉じるにはどうすればよいですか?

  14. 14

    カスタムreactナビゲーションヘッダーコンポーネントから親の状態値にアクセスする方法

  15. 15

    jQueryは、セクションがブラウザビューに表示された場合にのみ、ターゲット数にカウントされます

  16. 16

    iOS11でのナビゲーションバーのカスタム画像ビューの問題

  17. 17

    デフォルトのナビゲーションタブビューをカスタマイズされたタブビューに変更するにはどうすればよいですか?

  18. 18

    ハッキングに依存しない依存関係のカスタムバージョンを使用してサンドボックス化されたcabalプロジェクトを構築する方法(例:githubからのチェックアウト)

  19. 19

    Railsボタンをクリックすると、ビューからカスタムコントローラーアクションを呼び出します

  20. 20

    ネストされたナビゲーション+ IntersectionObserverのcreateRefに関する問題に対応する

  21. 21

    ビューコントローラーがナビゲーションスタックにプッシュされる前に呼び出される viewDidAppear()

  22. 22

    ネストされたナビゲーターから親のナビゲーションヘッダーを非表示にする

  23. 23

    カスタマイズされたLinuxディストリビューションを作成するためのアドバイスが必要です(最初からまたは既存のディストリビューションから?)

  24. 24

    マスターページのナビゲーションメニューからWebフォームにアクセスする

  25. 25

    次のアサーションは、ナビゲーターを構築するためにスローされました

  26. 26

    カードがナビゲーションスタックにプッシュされないのはなぜですか?制限はありますか?

  27. 27

    ナビゲーションボタンの問題で提示されたモーダルビュー

  28. 28

    カスタムクエリでフェッチされたwordpressのpost_contentからすべてのビジュアルコンポーザーショートコード/タグを取り除く方法

  29. 29

    ボタンアクション(パラメーター付き)を使用してカスタムUITableViewCellからビューをプッシュする方法

ホットタグ

アーカイブ